| |
| #if defined(LINUX) || defined(FREEBSD) || defined(HAIKU) |
| #define GL_GLEXT_PROTOTYPES |
| #endif |
| |
| |
| #include "tapp.h" |
| #include "viewerpane.h" |
| #include "onionskinmaskgui.h" |
| #include "viewerdraw.h" |
| #include "menubarcommandids.h" |
| #include "ruler.h" |
| #include "locatorpopup.h" |
| #if defined(x64) |
| #include "../stopmotion/stopmotion.h" |
| #endif |
| #include "tenv.h" |
| #include "cellselection.h" |
| |
| |
| #include "tools/cursors.h" |
| #include "tools/cursormanager.h" |
| #include "tools/toolhandle.h" |
| #include "tools/toolcommandids.h" |
| #include "tools/toolutils.h" |
| #include "tools/assistant.h" |
| #include "tools/replicator.h" |
| |
| |
| #include "toonzqt/icongenerator.h" |
| #include "toonzqt/gutil.h" |
| #include "toonzqt/imageutils.h" |
| #include "toonzqt/lutcalibrator.h" |
| #include "toonzqt/viewcommandids.h" |
| |
| |
| #include "toonz/tscenehandle.h" |
| #include "toonz/txsheethandle.h" |
| #include "toonz/tframehandle.h" |
| #include "toonz/tcolumnhandle.h" |
| #include "toonz/txshlevelhandle.h" |
| #include "toonz/sceneproperties.h" |
| #include "toonz/toonzscene.h" |
| #include "toonz/levelset.h" |
| #include "toonz/txshsimplelevel.h" |
| #include "toonz/tcamera.h" |
| #include "toonz/stage2.h" |
| #include "toonz/stage.h" |
| #include "toonz/stageplayer.h" |
| #include "toonz/stagevisitor.h" |
| #include "toonz/txsheet.h" |
| #include "toonz/tstageobjecttree.h" |
| #include "toonz/tstageobjectspline.h" |
| #include "toonz/tobjecthandle.h" |
| #include "toonz/tonionskinmaskhandle.h" |
| #include "toonz/palettecontroller.h" |
| #include "toonz/tpalettehandle.h" |
| #include "toonz/childstack.h" |
| #include "toonz/dpiscale.h" |
| #include "toonz/txshlevel.h" |
| #include "toonz/txshlevelcolumn.h" |
| #include "toonz/preferences.h" |
| #include "toonz/glrasterpainter.h" |
| #include "toonz/cleanupparameters.h" |
| #include "toonz/toonzimageutils.h" |
| #include "toonz/txshleveltypes.h" |
| #include "subcameramanager.h" |
| #include "toutputproperties.h" |
| |
| |
| #include "tpalette.h" |
| #include "tropcm.h" |
| #include "tgl.h" |
| #include "tofflinegl.h" |
| #include "tstopwatch.h" |
| #include "trop.h" |
| #include "tproperty.h" |
| #include "timagecache.h" |
| #include "trasterimage.h" |
| #include "tstroke.h" |
| #include "ttoonzimage.h" |
| |
| |
| #include <QMenu> |
| #include <QApplication> |
| #include <QDesktopWidget> |
| #include <QInputMethod> |
| #include <QGLContext> |
| #include <QOpenGLFramebufferObject> |
| #include <QMainWindow> |
| |
| #include "sceneviewer.h" |
| |
| void drawSpline(const TAffine &viewMatrix, const TRect &clipRect, bool camera3d, |
| double pixelSize); |
| |
| |
| |
| |
| TEnv::IntVar EnvViewerPreviewBehavior("ViewerPreviewBehavior", 0); |
| |
| |
| namespace { |
| |
| int l_mainDisplayListsSpaceId = |
| -1; |
| std::set<TGlContext> |
| l_contexts; |
| |
| |
| |
| struct DummyProxy : public TGLDisplayListsProxy { |
| ~DummyProxy() {} |
| void makeCurrent() {} |
| void doneCurrent() {} |
| }; |
| |
| |
| |
| double getActualFrameRate() { |
| |
| static double fps = 0; |
| static TStopWatch stopwatch; |
| static int frame = 0; |
| ++frame; |
| |
| stopwatch.start(); |
| |
| unsigned long tt = stopwatch.getTotalTime(); |
| |
| |
| if (tt > 1000) { |
| stopwatch.stop(); |
| fps = troundp(((1000 * frame) / (double)tt)); |
| stopwatch.start(true); |
| frame = 0; |
| } |
| return fps; |
| } |
| |
| |
| |
| void copyFrontBufferToBackBuffer() { |
| static GLint viewport[4]; |
| static GLfloat raster_pos[4]; |
| |
| glGetIntegerv(GL_VIEWPORT, viewport); |
| |
| |
| glReadBuffer(GL_FRONT); |
| |
| |
| glMatrixMode(GL_PROJECTION); |
| glPushMatrix(); |
| glLoadIdentity(); |
| gluOrtho2D(0, viewport[2], 0, viewport[3]); |
| |
| |
| glMatrixMode(GL_MODELVIEW); |
| glPushMatrix(); |
| glLoadIdentity(); |
| |
| |
| glGetFloatv(GL_CURRENT_RASTER_POSITION, raster_pos); |
| |
| |
| glRasterPos4f(0.0, 0.0, 0.0, 1.0); |
| |
| |
| glCopyPixels(0, 0, viewport[2], viewport[3], GL_COLOR); |
| |
| |
| glRasterPos4fv(raster_pos); |
| |
| |
| glPopMatrix(); |
| glMatrixMode(GL_PROJECTION); |
| glPopMatrix(); |
| glMatrixMode(GL_MODELVIEW); |
| |
| |
| glReadBuffer(GL_BACK); |
| } |
| |
| |
| T3DPointD computeNew3DPosition(T3DPointD start3DPos, TPointD delta2D, |
| TPointD &new2dPos, GLdouble modelView3D[16], |
| GLdouble projection3D[16], GLint viewport3D[4], |
| int devPixRatio) { |
| GLdouble pos2D_x, pos2D_y, pos2D_z; |
| gluProject(-start3DPos.x, -start3DPos.y, start3DPos.z, modelView3D, |
| projection3D, viewport3D, &pos2D_x, &pos2D_y, &pos2D_z); |
| new2dPos = TPointD(pos2D_x + delta2D.x, pos2D_y + delta2D.y); |
| GLdouble pos3D_x, pos3D_y, pos3D_z; |
| gluUnProject(new2dPos.x, new2dPos.y, 1, modelView3D, projection3D, viewport3D, |
| &pos3D_x, &pos3D_y, &pos3D_z); |
| new2dPos.y = viewport3D[3] - new2dPos.y - 20 * devPixRatio; |
| return T3DPointD(pos3D_x, pos3D_y, pos3D_z); |
| } |
| |
| |
| #ifdef DA_RIVEDERE |
| |
| |
| |
| |
| |
| |
| |
| |
| void copyBackBufferToFrontBuffer(const TRect &rect) { |
| static GLint viewport[4]; |
| static GLfloat raster_pos[4]; |
| |
| glGetIntegerv(GL_VIEWPORT, viewport); |
| |
| |
| glReadBuffer(GL_BACK); |
| glDrawBuffer(GL_FRONT); |
| |
| |
| glMatrixMode(GL_PROJECTION); |
| glPushMatrix(); |
| glLoadIdentity(); |
| gluOrtho2D(0, viewport[2], 0, viewport[3]); |
| |
| |
| glMatrixMode(GL_MODELVIEW); |
| glPushMatrix(); |
| glLoadIdentity(); |
| |
| |
| glGetFloatv(GL_CURRENT_RASTER_POSITION, raster_pos); |
| |
| |
| glRasterPos4f(0.0, 0.0, 0.0, 1.0); |
| |
| |
| glCopyPixels(0, 0, viewport[2], viewport[3], GL_COLOR); |
| |
| |
| glRasterPos4fv(raster_pos); |
| |
| |
| glPopMatrix(); |
| glMatrixMode(GL_PROJECTION); |
| glPopMatrix(); |
| glMatrixMode(GL_MODELVIEW); |
| |
| |
| glDrawBuffer(GL_BACK); |
| } |
| |
| #endif |
| |
| const TRectD InvalidateAllRect(0, 0, -1, -1); |
| |
| |
| } |
| |
| |
| |
| |
| |
| |
| ToggleCommandHandler::ToggleCommandHandler(CommandId id, bool startStatus) |
| : MenuItemHandler(id), m_status(startStatus) {} |
| |
| void ToggleCommandHandler::execute() { |
| m_status = !m_status; |
| |
| TApp::instance()->getCurrentScene()->notifySceneChanged(false); |
| } |
| |
| |
| |
| ToggleCommandHandler viewTableToggle(MI_ViewTable, false); |
| ToggleCommandHandler editInPlaceToggle(MI_ToggleEditInPlace, false); |
| ToggleCommandHandler fieldGuideToggle(MI_FieldGuide, false); |
| ToggleCommandHandler safeAreaToggle(MI_SafeArea, false); |
| ToggleCommandHandler rasterizePliToggle(MI_RasterizePli, false); |
| |
| ToggleCommandHandler viewClcToggle("MI_ViewColorcard", false); |
| ToggleCommandHandler viewCameraToggle("MI_ViewCamera", false); |
| ToggleCommandHandler viewBBoxToggle("MI_ViewBBox", false); |
| ToggleCommandHandler viewGuideToggle("MI_ViewGuide", false); |
| ToggleCommandHandler viewRulerToggle("MI_ViewRuler", false); |
| |
| |
| |
| void invalidateIcons() { |
| ToonzCheck *tc = ToonzCheck::instance(); |
| int mask = tc->getChecks(); |
| IconGenerator::Settings s; |
| s.m_blackBgCheck = mask & ToonzCheck::eBlackBg; |
| s.m_transparencyCheck = mask & ToonzCheck::eTransparency; |
| s.m_inksOnly = mask & ToonzCheck::eInksOnly; |
| |
| if (mask & ToonzCheck::eInk1) s.m_inkIndex = 1; |
| |
| else if (mask & ToonzCheck::eInk) |
| s.m_inkIndex = tc->getColorIndex(); |
| else |
| s.m_inkIndex = -1; |
| s.m_paintIndex = mask & ToonzCheck::ePaint ? tc->getColorIndex() : -1; |
| IconGenerator::instance()->setSettings(s); |
| |
| |
| TXshLevel *sl = TApp::instance()->getCurrentLevel()->getLevel(); |
| if (sl && sl->getType() == PLI_XSHLEVEL) { |
| std::vector<TFrameId> fids; |
| sl->getFids(fids); |
| |
| for (int i = 0; i < (int)fids.size(); i++) |
| IconGenerator::instance()->invalidate(sl, fids[i]); |
| } |
| |
| |
| |
| |
| |
| TApp::instance()->getCurrentScene()->notifySceneChanged(false); |
| TApp::instance()->getCurrentLevel()->notifyLevelViewChange(); |
| } |
| |
| |
| |
| static void executeCheck(int checkType) { |
| ToonzCheck::instance()->toggleCheck(checkType); |
| invalidateIcons(); |
| } |
| |
| |
| |
| class TCheckToggleCommand final : public MenuItemHandler { |
| public: |
| TCheckToggleCommand() : MenuItemHandler("MI_TCheck") {} |
| void execute() override { executeCheck(ToonzCheck::eTransparency); } |
| } tcheckToggle; |
| |
| |
| |
| class ICheckToggleCommand final : public MenuItemHandler { |
| public: |
| ICheckToggleCommand() : MenuItemHandler("MI_ICheck") {} |
| void execute() override { executeCheck(ToonzCheck::eInk); } |
| } icheckToggle; |
| |
| |
| |
| class PCheckToggleCommand final : public MenuItemHandler { |
| public: |
| PCheckToggleCommand() : MenuItemHandler("MI_PCheck") {} |
| void execute() override { executeCheck(ToonzCheck::ePaint); } |
| } pcheckToggle; |
| |
| |
| |
| class BCheckToggleCommand final : public MenuItemHandler { |
| public: |
| BCheckToggleCommand() : MenuItemHandler("MI_BCheck") {} |
| void execute() override { executeCheck(ToonzCheck::eBlackBg); } |
| } bcheckToggle; |
| |
| |
| |
| class TAutocloseToggleCommand final : public MenuItemHandler { |
| public: |
| TAutocloseToggleCommand() : MenuItemHandler("MI_ACheck") {} |
| void execute() override { executeCheck(ToonzCheck::eAutoclose); } |
| } tautocloseToggle; |
| |
| |
| |
| class TGapToggleCommand final : public MenuItemHandler { |
| public: |
| TGapToggleCommand() : MenuItemHandler("MI_GCheck") {} |
| void execute() override { executeCheck(ToonzCheck::eGap); } |
| } tgapToggle; |
| |
| |
| |
| class TInksOnlyToggleCommand final : public MenuItemHandler { |
| public: |
| TInksOnlyToggleCommand() : MenuItemHandler("MI_IOnly") {} |
| void execute() override { executeCheck(ToonzCheck::eInksOnly); } |
| } tinksOnlyToggle; |
| |
| |
| |
| |
| class Ink1CheckToggleCommand final : public MenuItemHandler { |
| public: |
| Ink1CheckToggleCommand() : MenuItemHandler("MI_Ink1Check") {} |
| void execute() override { executeCheck(ToonzCheck::eInk1); } |
| } ink1checkToggle; |
| |
| |
| |
| class TShiftTraceToggleCommand final : public MenuItemHandler { |
| CommandId m_cmdId; |
| |
| public: |
| TShiftTraceToggleCommand(CommandId cmdId) |
| : MenuItemHandler(cmdId), m_cmdId(cmdId) {} |
| void execute() override { |
| CommandManager *cm = CommandManager::instance(); |
| QAction *action = cm->getAction(m_cmdId); |
| bool checked = action->isChecked(); |
| if (std::string(m_cmdId) == MI_ShiftTrace) { |
| cm->enable(MI_EditShift, checked); |
| cm->enable(MI_NoShift, checked); |
| if (checked) { |
| OnioniSkinMaskGUI::resetShiftTraceFrameOffset(); |
| |
| if (isChecked(MI_EditShift)) |
| TApp::instance()->getCurrentTool()->setPseudoTool("T_ShiftTrace"); |
| } else { |
| |
| if (isChecked(MI_EditShift)) |
| TApp::instance()->getCurrentTool()->unsetPseudoTool(); |
| } |
| |
| |
| TApp::instance()->getCurrentOnionSkin()->notifyOnionSkinMaskChanged(); |
| } else if (std::string(m_cmdId) == MI_EditShift) { |
| if (checked) { |
| QAction *noShiftAction = |
| CommandManager::instance()->getAction(MI_NoShift); |
| if (noShiftAction) noShiftAction->setChecked(false); |
| TApp::instance()->getCurrentTool()->setPseudoTool("T_ShiftTrace"); |
| } else { |
| TApp::instance()->getCurrentTool()->unsetPseudoTool(); |
| } |
| CommandManager::instance()->enable(MI_NoShift, !checked); |
| } else if (std::string(m_cmdId) == MI_NoShift) { |
| } |
| updateShiftTraceStatus(); |
| } |
| |
| bool isChecked(CommandId id) const { |
| QAction *action = CommandManager::instance()->getAction(id); |
| return action != 0 && action->isChecked(); |
| } |
| void updateShiftTraceStatus() { |
| OnionSkinMask::ShiftTraceStatus status = OnionSkinMask::DISABLED; |
| if (isChecked(MI_ShiftTrace)) { |
| if (isChecked(MI_EditShift)) |
| status = OnionSkinMask::EDITING_GHOST; |
| else if (isChecked(MI_NoShift)) |
| status = OnionSkinMask::ENABLED_WITHOUT_GHOST_MOVEMENTS; |
| else |
| status = OnionSkinMask::ENABLED; |
| } |
| OnionSkinMask osm = |
| TApp::instance()->getCurrentOnionSkin()->getOnionSkinMask(); |
| osm.setShiftTraceStatus(status); |
| osm.clearGhostFlipKey(); |
| TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); |
| TApp::instance()->getCurrentOnionSkin()->setOnionSkinMask(osm); |
| } |
| }; |
| |
| TShiftTraceToggleCommand shiftTraceToggleCommand(MI_ShiftTrace), |
| editShiftToggleCommand(MI_EditShift), noShiftToggleCommand(MI_NoShift); |
| |
| class TResetShiftTraceCommand final : public MenuItemHandler { |
| public: |
| TResetShiftTraceCommand() : MenuItemHandler(MI_ResetShift) {} |
| void execute() override { |
| OnionSkinMask osm = |
| TApp::instance()->getCurrentOnionSkin()->getOnionSkinMask(); |
| osm.setShiftTraceGhostCenter(0, TPointD()); |
| osm.setShiftTraceGhostCenter(1, TPointD()); |
| osm.setShiftTraceGhostAff(0, TAffine()); |
| osm.setShiftTraceGhostAff(1, TAffine()); |
| TApp::instance()->getCurrentOnionSkin()->setOnionSkinMask(osm); |
| TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| if (tool) tool->reset(); |
| } |
| } resetShiftTraceCommand; |
| |
| |
| |
| |
| |
| |
| class TViewResetCommand final : public MenuItemHandler { |
| public: |
| TViewResetCommand() : MenuItemHandler(VB_ViewReset) {} |
| void execute() override { |
| if (TApp::instance()->getActiveViewer()) |
| TApp::instance()->getActiveViewer()->resetSceneViewer(); |
| } |
| } viewResetCommand; |
| |
| class TZoomResetCommand final : public MenuItemHandler { |
| public: |
| TZoomResetCommand() : MenuItemHandler(VB_ZoomReset) {} |
| void execute() override { |
| if (TApp::instance()->getActiveViewer()) |
| TApp::instance()->getActiveViewer()->resetZoom(); |
| } |
| } zoomResetCommand; |
| |
| class TZoomFitCommand final : public MenuItemHandler { |
| public: |
| TZoomFitCommand() : MenuItemHandler(VB_ZoomFit) {} |
| void execute() override { |
| if (TApp::instance()->getActiveViewer()) |
| TApp::instance()->getActiveViewer()->fitToCamera(); |
| } |
| } zoomFitCommand; |
| |
| class TActualPixelSizeCommand final : public MenuItemHandler { |
| public: |
| TActualPixelSizeCommand() : MenuItemHandler(VB_ActualPixelSize) {} |
| void execute() override { |
| if (TApp::instance()->getActiveViewer()) |
| TApp::instance()->getActiveViewer()->setActualPixelSize(); |
| } |
| } actualPixelSizeCommand; |
| |
| class TFlipViewerXCommand final : public MenuItemHandler { |
| public: |
| TFlipViewerXCommand() : MenuItemHandler(VB_FlipX) {} |
| void execute() override { |
| if (TApp::instance()->getActiveViewer()) |
| TApp::instance()->getActiveViewer()->flipX(); |
| } |
| } flipViewerXCommand; |
| |
| class TFlipViewerYCommand final : public MenuItemHandler { |
| public: |
| TFlipViewerYCommand() : MenuItemHandler(VB_FlipY) {} |
| void execute() override { |
| if (TApp::instance()->getActiveViewer()) |
| TApp::instance()->getActiveViewer()->flipY(); |
| } |
| } flipViewerYCommand; |
| |
| class TRotateResetCommand final : public MenuItemHandler { |
| public: |
| TRotateResetCommand() : MenuItemHandler(VB_RotateReset) {} |
| void execute() override { |
| if (TApp::instance()->getActiveViewer()) |
| TApp::instance()->getActiveViewer()->resetRotation(); |
| } |
| } rotateResetCommand; |
| |
| class TPositionResetCommand final : public MenuItemHandler { |
| public: |
| TPositionResetCommand() : MenuItemHandler(VB_PositionReset) {} |
| void execute() override { |
| if (TApp::instance()->getActiveViewer()) |
| TApp::instance()->getActiveViewer()->resetPosition(); |
| } |
| } positionResetCommand; |
| |
| class TVectorGuidedDrawingToggleCommand final : public MenuItemHandler { |
| public: |
| TVectorGuidedDrawingToggleCommand() |
| : MenuItemHandler(MI_VectorGuidedDrawing) {} |
| void execute() override { |
| CommandManager *cm = CommandManager::instance(); |
| QAction *action = cm->getAction(MI_VectorGuidedDrawing); |
| Preferences::instance()->setValue(guidedDrawingType, |
| action->isChecked() ? 1 : 0); |
| TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); |
| TApp::instance()->getCurrentScene()->notifyPreferenceChanged( |
| "GuidedDrawingFrame"); |
| } |
| |
| bool isChecked(CommandId id) const { |
| QAction *action = CommandManager::instance()->getAction(id); |
| return action != 0 && action->isChecked(); |
| } |
| } vectorGuidedDrawingToggleCommand; |
| |
| class TSelectGuideStrokeResetCommand final : public MenuItemHandler { |
| public: |
| TSelectGuideStrokeResetCommand() |
| : MenuItemHandler(MI_SelectGuideStrokeReset) {} |
| void execute() override { |
| TVectorImageP vi = (TVectorImageP)TTool::getImage(false); |
| if (!vi) return; |
| |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| if (!tool) return; |
| |
| tool->getViewer()->setGuidedStrokePickerMode(0); |
| tool->getViewer()->setGuidedBackStroke(-1); |
| tool->getViewer()->setGuidedFrontStroke(-1); |
| tool->getViewer()->invalidateAll(); |
| } |
| } SelectGuideStrokeResetCommand; |
| |
| class TSelectGuideStrokeNextCommand final : public MenuItemHandler { |
| public: |
| TSelectGuideStrokeNextCommand() : MenuItemHandler(MI_SelectNextGuideStroke) {} |
| void execute() override { |
| TVectorImageP vi = (TVectorImageP)TTool::getImage(false); |
| if (!vi) return; |
| |
| Preferences *pref = Preferences::instance(); |
| if (!pref->isOnionSkinEnabled() || (pref->getGuidedDrawingType() != 1 && |
| pref->getGuidedDrawingType() != 2)) |
| return; |
| |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| if (!tool) return; |
| |
| tool->getViewer()->setGuidedStrokePickerMode(1); |
| } |
| } selectGuideStrokeNextCommand; |
| |
| class TSelectGuideStrokePrevCommand final : public MenuItemHandler { |
| public: |
| TSelectGuideStrokePrevCommand() : MenuItemHandler(MI_SelectPrevGuideStroke) {} |
| void execute() override { |
| TVectorImageP vi = (TVectorImageP)TTool::getImage(false); |
| if (!vi) return; |
| |
| Preferences *pref = Preferences::instance(); |
| if (!pref->isOnionSkinEnabled() || (pref->getGuidedDrawingType() != 1 && |
| pref->getGuidedDrawingType() != 2)) |
| return; |
| |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| if (!tool) return; |
| |
| tool->getViewer()->setGuidedStrokePickerMode(-1); |
| } |
| } selectGuideStrokePrevCommand; |
| |
| class TSelectBothGuideStrokesCommand final : public MenuItemHandler { |
| public: |
| TSelectBothGuideStrokesCommand() |
| : MenuItemHandler(MI_SelectBothGuideStrokes) {} |
| void execute() override { |
| TVectorImageP vi = (TVectorImageP)TTool::getImage(false); |
| if (!vi) return; |
| |
| Preferences *pref = Preferences::instance(); |
| if (!pref->isOnionSkinEnabled() || (pref->getGuidedDrawingType() != 1 && |
| pref->getGuidedDrawingType() != 2)) |
| return; |
| |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| if (!tool) return; |
| |
| tool->getViewer()->setGuidedStrokePickerMode(-2); |
| } |
| } selectBothGuideStrokesCommand; |
| |
| class TTweenGuideStrokesCommand final : public MenuItemHandler { |
| public: |
| TTweenGuideStrokesCommand() : MenuItemHandler(MI_TweenGuideStrokes) {} |
| void execute() override { |
| TVectorImageP vi = (TVectorImageP)TTool::getImage(false); |
| if (!vi) return; |
| |
| Preferences *pref = Preferences::instance(); |
| if (!pref->isOnionSkinEnabled() || (pref->getGuidedDrawingType() != 1 && |
| pref->getGuidedDrawingType() != 2)) |
| return; |
| |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| if (!tool) return; |
| |
| tool->tweenSelectedGuideStrokes(); |
| } |
| } tweenGuideStrokesCommand; |
| |
| class TTweenGuideStrokeToSelectedCommand final : public MenuItemHandler { |
| public: |
| TTweenGuideStrokeToSelectedCommand() |
| : MenuItemHandler(MI_TweenGuideStrokeToSelected) {} |
| void execute() override { |
| TVectorImageP vi = (TVectorImageP)TTool::getImage(false); |
| if (!vi) return; |
| |
| Preferences *pref = Preferences::instance(); |
| if (!pref->isOnionSkinEnabled() || (pref->getGuidedDrawingType() != 1 && |
| pref->getGuidedDrawingType() != 2)) |
| return; |
| |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| if (!tool) return; |
| |
| tool->tweenGuideStrokeToSelected(); |
| } |
| } tweenGuideStrokeToSelectedCommand; |
| |
| class TSelectGuidesAndTweenCommand final : public MenuItemHandler { |
| public: |
| TSelectGuidesAndTweenCommand() |
| : MenuItemHandler(MI_SelectGuidesAndTweenMode) {} |
| void execute() override { |
| TVectorImageP vi = (TVectorImageP)TTool::getImage(false); |
| if (!vi) return; |
| |
| Preferences *pref = Preferences::instance(); |
| if (!pref->isOnionSkinEnabled() || (pref->getGuidedDrawingType() != 1 && |
| pref->getGuidedDrawingType() != 2)) |
| return; |
| |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| if (!tool) return; |
| |
| tool->getViewer()->setGuidedStrokePickerMode(-3); |
| } |
| } selectGuidesAndTweenCommand; |
| |
| class TFlipNextStrokeDirectionCommand final : public MenuItemHandler { |
| public: |
| TFlipNextStrokeDirectionCommand() : MenuItemHandler(MI_FlipNextGuideStroke) {} |
| void execute() override { |
| TVectorImageP vi = (TVectorImageP)TTool::getImage(false); |
| if (!vi) return; |
| |
| Preferences *pref = Preferences::instance(); |
| if (!pref->isOnionSkinEnabled() || (pref->getGuidedDrawingType() != 1 && |
| pref->getGuidedDrawingType() != 2)) |
| return; |
| |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| if (!tool) return; |
| |
| tool->flipGuideStrokeDirection(1); |
| } |
| } flipNextStrokeDirectionCommand; |
| |
| class TFlipPrevStrokeDirectionCommand final : public MenuItemHandler { |
| public: |
| TFlipPrevStrokeDirectionCommand() : MenuItemHandler(MI_FlipPrevGuideStroke) {} |
| void execute() override { |
| TVectorImageP vi = (TVectorImageP)TTool::getImage(false); |
| if (!vi) return; |
| |
| Preferences *pref = Preferences::instance(); |
| if (!pref->isOnionSkinEnabled() || (pref->getGuidedDrawingType() != 1 && |
| pref->getGuidedDrawingType() != 2)) |
| return; |
| |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| if (!tool) return; |
| |
| tool->flipGuideStrokeDirection(-1); |
| } |
| } flipPrevStrokeDirectionCommand; |
| |
| |
| |
| |
| |
| SceneViewer::SceneViewer(ImageUtils::FullScreenWidget *parent) |
| : GLWidgetForHighDpi(parent) |
| , TToolViewer(this) |
| , m_pressure(0) |
| , m_lastMousePos(0, 0) |
| , m_mouseButton(Qt::NoButton) |
| , m_foregroundDrawing(false) |
| , m_tabletEvent(false) |
| , m_tabletMove(false) |
| , m_buttonClicked(false) |
| , m_referenceMode(NORMAL_REFERENCE) |
| , m_previewMode(NO_PREVIEW) |
| , m_isMouseEntered(false) |
| , m_forceGlFlush(true) |
| , m_freezedStatus(NO_FREEZED) |
| , m_viewGrabImage(0) |
| , m_FPS(0) |
| , m_hRuler(0) |
| , m_vRuler(0) |
| , m_viewMode(SCENE_VIEWMODE) |
| , m_pos(0, 0) |
| , m_pan3D(TPointD(0, 0)) |
| , m_zoomScale3D(0.1) |
| , m_theta3D(20) |
| , m_phi3D(30) |
| , m_dpiScale(TPointD(1, 1)) |
| , m_compareSettings() |
| , m_minZ(0) |
| , m_tableDLId(-1) |
| , m_groupIndexToBeEntered(-1) |
| , m_pixelSize(1) |
| , m_eraserPointerOn(false) |
| , m_backupTool("") |
| , m_clipRect() |
| , m_isPicking(false) |
| , m_current3DDevice(NONE) |
| , m_sideRasterPos() |
| , m_topRasterPos() |
| , m_toolDisableReason("") |
| , m_editPreviewSubCamera(false) |
| , m_locator(NULL) |
| , m_isLocator(false) |
| , m_isBusyOnTabletMove(false) { |
| m_visualSettings.m_sceneProperties = |
| TApp::instance()->getCurrentScene()->getScene()->getProperties(); |
| #if defined(x64) |
| m_stopMotion = StopMotion::instance(); |
| #endif |
| |
| setAttribute(Qt::WA_KeyCompression); |
| |
| setAttribute(Qt::WA_InputMethodEnabled); |
| setFocusPolicy(Qt::StrongFocus); |
| setAcceptDrops(true); |
| this->setMouseTracking(true); |
| |
| this->setTabletTracking(true); |
| |
| for (int i = 0; i < m_viewAff.size(); ++i) { |
| setViewMatrix(getNormalZoomScale(), i); |
| m_rotationAngle[i] = 0.0; |
| } |
| |
| m_3DSideR = rasterFromQPixmap(svgToPixmap(":Resources/3Dside_r.svg")); |
| m_3DSideL = rasterFromQPixmap(svgToPixmap(":Resources/3Dside_l.svg")); |
| m_3DTop = rasterFromQPixmap(svgToPixmap(":Resources/3Dtop.svg")); |
| |
| setAttribute(Qt::WA_AcceptTouchEvents); |
| grabGesture(Qt::SwipeGesture); |
| grabGesture(Qt::PanGesture); |
| grabGesture(Qt::PinchGesture); |
| |
| setUpdateBehavior(QOpenGLWidget::PartialUpdate); |
| |
| if (Preferences::instance()->isColorCalibrationEnabled()) |
| m_lutCalibrator = new LutCalibrator(); |
| if (Preferences::instance()->is30bitDisplayEnabled()) |
| setTextureFormat(TGL_TexFmt10); |
| } |
| |
| |
| |
| void SceneViewer::setVisual(const ImagePainter::VisualSettings &settings) { |
| |
| |
| bool repaint = m_visualSettings.needRepaint(settings); |
| m_visualSettings = settings; |
| m_visualSettings.m_sceneProperties = |
| TApp::instance()->getCurrentScene()->getScene()->getProperties(); |
| if (repaint) GLInvalidateAll(); |
| } |
| |
| |
| |
| SceneViewer::~SceneViewer() { |
| |
| emit aboutToBeDestroyed(); |
| |
| if (m_fbo) delete m_fbo; |
| |
| |
| std::set<TGlContext>::iterator ct, cEnd(l_contexts.end()); |
| for (ct = l_contexts.begin(); ct != cEnd; ++ct) |
| TGLDisplayListsManager::instance()->releaseContext(*ct); |
| l_contexts.clear(); |
| } |
| |
| |
| |
| |
| TRectD SceneViewer::getPreviewRect() const { |
| TApp *app = TApp::instance(); |
| int row = app->getCurrentFrame()->getFrame(); |
| TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); |
| TStageObjectId cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); |
| double cameraZ = xsh->getZ(cameraId, row); |
| TAffine cameraAff = |
| xsh->getPlacement(cameraId, row) * TScale((1000 + cameraZ) / 1000); |
| |
| TDimensionD cameraSize = |
| app->getCurrentScene()->getScene()->getCurrentCamera()->getSize(); |
| TDimension cameraRes = |
| app->getCurrentScene()->getScene()->getCurrentCamera()->getRes(); |
| TScale cameraScale(Stage::inch * cameraSize.lx / cameraRes.lx, |
| Stage::inch * cameraSize.ly / cameraRes.ly); |
| |
| TRectD viewRect(-width() * 0.5, -height() * 0.5, width() * 0.5, |
| height() * 0.5); |
| |
| return (getViewMatrix() * cameraAff * cameraScale).inv() * viewRect; |
| } |
| |
| |
| |
| void SceneViewer::onRenderStarted(int frame) { emit previewStatusChanged(); } |
| |
| |
| |
| void SceneViewer::onRenderCompleted(int frame) { |
| invalidateAll(); |
| emit previewStatusChanged(); |
| } |
| |
| |
| |
| void SceneViewer::onPreviewUpdate() { |
| update(); |
| emit previewStatusChanged(); |
| } |
| |
| |
| |
| void SceneViewer::setReferenceMode(int referenceMode) { |
| if (m_referenceMode == referenceMode) return; |
| |
| TApp *app = TApp::instance(); |
| if (app->getCurrentFrame()->isEditingLevel()) |
| app->getCurrentFrame()->setFrame(app->getCurrentFrame()->getFrame()); |
| if (m_freezedStatus != NO_FREEZED) { |
| freeze(false); |
| emit freezeStateChanged(false); |
| } |
| |
| m_referenceMode = referenceMode; |
| invalidateAll(); |
| emit onZoomChanged(); |
| } |
| |
| |
| |
| void SceneViewer::freeze(bool on) { |
| if (!on) { |
| m_viewGrabImage = TRaster32P(); |
| m_freezedStatus = NO_FREEZED; |
| } else { |
| setCursor(Qt::ForbiddenCursor); |
| m_freezedStatus = UPDATE_FREEZED; |
| } |
| GLInvalidateAll(); |
| } |
| |
| |
| |
| void SceneViewer::enablePreview(int previewMode) { |
| if (m_previewMode == previewMode) return; |
| |
| TApp *app = TApp::instance(); |
| if (app->getCurrentFrame()->isEditingLevel() && previewMode != NO_PREVIEW) |
| app->getCurrentFrame()->setFrame(app->getCurrentFrame()->getFrame()); |
| |
| if (m_freezedStatus != NO_FREEZED) { |
| freeze(false); |
| emit freezeStateChanged(false); |
| } |
| |
| if (m_previewMode != NO_PREVIEW) { |
| Previewer::instance(m_previewMode == SUBCAMERA_PREVIEW) |
| ->removeListener(this); |
| Previewer::instance(m_previewMode == SUBCAMERA_PREVIEW) |
| ->clearAllUnfinishedFrames(); |
| } |
| |
| m_previewMode = previewMode; |
| |
| |
| if (m_previewMode != NO_PREVIEW) { |
| Previewer *previewer = |
| Previewer::instance(m_previewMode == SUBCAMERA_PREVIEW); |
| |
| previewer->addListener(this); |
| |
| |
| |
| if (EnvViewerPreviewBehavior == 1) { |
| int r0, r1, step; |
| ToonzScene *scene = app->getCurrentScene()->getScene(); |
| scene->getProperties()->getPreviewProperties()->getRange(r0, r1, step); |
| if (r0 > r1) { |
| r0 = 0; |
| r1 = scene->getFrameCount() - 1; |
| } |
| int currentFrame = app->getCurrentFrame()->getFrame(); |
| std::vector<int> queueFrames; |
| for (int f = currentFrame; f <= r1; f += step) queueFrames.push_back(f); |
| for (int f = r0; f < currentFrame; f += step) queueFrames.push_back(f); |
| |
| previewer->addFramesToRenderQueue(queueFrames); |
| } else if (EnvViewerPreviewBehavior == 2) { |
| TCellSelection *cellSel = |
| dynamic_cast<TCellSelection *>(TSelection::getCurrent()); |
| if (cellSel && !cellSel->isEmpty()) { |
| int r0, c0, r1, c1; |
| cellSel->getSelectedCells(r0, c0, r1, c1); |
| if (r0 < r1) { |
| std::vector<int> queueFrames; |
| for (int f = r0; f <= r1; f++) queueFrames.push_back(f); |
| previewer->addFramesToRenderQueue(queueFrames); |
| } |
| } |
| } |
| previewer->update(); |
| } |
| |
| GLInvalidateAll(); |
| |
| |
| emit previewToggled(); |
| } |
| |
| |
| |
| TPointD SceneViewer::winToWorld(const QPointF &pos) const { |
| |
| |
| TPointD pp(pos.x() - (double)width() / 2.0, |
| -pos.y() + (double)height() / 2.0); |
| if (is3DView()) { |
| TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet(); |
| TStageObjectId cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); |
| double z = xsh->getStageObject(cameraId)->getZ( |
| TApp::instance()->getCurrentFrame()->getFrame()); |
| |
| TPointD p(pp.x - m_pan3D.x, pp.y - m_pan3D.y); |
| p = p * (1 / m_zoomScale3D); |
| double theta = m_theta3D * M_PI_180; |
| double phi = m_phi3D * M_PI_180; |
| double cs_phi = cos(phi); |
| double sn_phi = sin(phi); |
| double cs_theta = cos(theta); |
| double sn_theta = sin(theta); |
| TPointD a(cs_phi, sn_theta * sn_phi); |
| TPointD b(0, cs_theta); |
| TPointD c(sn_phi, -sn_theta * cs_phi); |
| TPointD aa = rotate90(a); |
| TPointD bb = rotate90(b); |
| |
| double abb = a * bb; |
| double baa = b * aa; |
| if (fabs(abb) > 0.001 && fabs(baa) > 0.001) { |
| p -= c * z; |
| TPointD g((p * bb) / (a * bb), (p * aa) / (b * aa)); |
| return TAffine() * g; |
| } else |
| return TAffine() * TPointD(0, 0); |
| } |
| |
| return getViewMatrix().inv() * pp; |
| } |
| |
| |
| |
| TPointD SceneViewer::winToWorld(const TPointD &winPos) const { |
| return winToWorld(QPointF(winPos.x, height() - winPos.y)); |
| } |
| |
| |
| |
| TPointD SceneViewer::worldToPos(const TPointD &worldPos) const { |
| TPointD p = getViewMatrix() * worldPos; |
| return TPointD(width() / 2 + p.x, height() / 2 + p.y); |
| } |
| |
| |
| |
| void SceneViewer::showEvent(QShowEvent *) { |
| m_visualSettings.m_sceneProperties = |
| TApp::instance()->getCurrentScene()->getScene()->getProperties(); |
| |
| |
| |
| if (m_previewMode != NO_PREVIEW) |
| Previewer::instance(m_previewMode == SUBCAMERA_PREVIEW)->addListener(this); |
| |
| TApp *app = TApp::instance(); |
| |
| TSceneHandle *sceneHandle = app->getCurrentScene(); |
| bool ret = connect(sceneHandle, SIGNAL(sceneSwitched()), this, |
| SLOT(resetSceneViewer())); |
| ret = ret && connect(sceneHandle, SIGNAL(sceneChanged()), this, |
| SLOT(onSceneChanged())); |
| ret = ret && connect(sceneHandle, SIGNAL(preferenceChanged(const QString &)), |
| this, SLOT(onPreferenceChanged(const QString &))); |
| |
| TFrameHandle *frameHandle = app->getCurrentFrame(); |
| ret = ret && connect(frameHandle, SIGNAL(frameSwitched()), this, |
| SLOT(onFrameSwitched())); |
| |
| TPaletteHandle *paletteHandle = |
| app->getPaletteController()->getCurrentLevelPalette(); |
| ret = ret && connect(paletteHandle, SIGNAL(colorStyleChanged(bool)), this, |
| SLOT(update())); |
| |
| ret = ret && connect(app->getCurrentObject(), SIGNAL(objectSwitched()), this, |
| SLOT(onObjectSwitched())); |
| ret = ret && connect(app->getCurrentObject(), SIGNAL(objectChanged(bool)), |
| this, SLOT(update())); |
| |
| ret = |
| ret && connect(app->getCurrentOnionSkin(), SIGNAL(onionSkinMaskChanged()), |
| this, SLOT(onOnionSkinMaskChanged())); |
| |
| ret = ret && connect(app->getCurrentLevel(), SIGNAL(xshLevelChanged()), this, |
| SLOT(update())); |
| ret = ret && connect(app->getCurrentLevel(), SIGNAL(xshCanvasSizeChanged()), |
| this, SLOT(update())); |
| |
| |
| ret = ret && |
| connect(app->getCurrentLevel(), SIGNAL(xshLevelSwitched(TXshLevel *)), |
| this, SLOT(onLevelSwitched())); |
| |
| ret = ret && connect(app->getCurrentXsheet(), SIGNAL(xsheetChanged()), this, |
| SLOT(onXsheetChanged())); |
| ret = ret && connect(app->getCurrentXsheet(), SIGNAL(xsheetSwitched()), this, |
| SLOT(update())); |
| |
| |
| ret = ret && connect(app->getCurrentTool(), SIGNAL(toolChanged()), this, |
| SLOT(onToolChanged())); |
| ret = ret && connect(app->getCurrentTool(), SIGNAL(toolCursorTypeChanged()), |
| this, SLOT(onToolChanged())); |
| |
| ret = ret && |
| connect(app, SIGNAL(tabletLeft()), this, SLOT(resetTabletStatus())); |
| #if defined(x64) |
| if (m_stopMotion) { |
| ret = ret && connect(m_stopMotion, SIGNAL(newLiveViewImageReady()), this, |
| SLOT(onNewStopMotionImageReady())); |
| ret = ret && connect(m_stopMotion, SIGNAL(liveViewStopped()), this, |
| SLOT(onStopMotionLiveViewStopped())); |
| } |
| #endif |
| assert(ret); |
| |
| if (m_hRuler && m_vRuler) { |
| if (!viewRulerToggle.getStatus()) { |
| m_hRuler->hide(); |
| m_vRuler->hide(); |
| } else { |
| m_hRuler->show(); |
| m_vRuler->show(); |
| } |
| } |
| if (m_shownOnce == false) { |
| fitToCamera(); |
| m_shownOnce = true; |
| } |
| TApp::instance()->setActiveViewer(this); |
| |
| onPreferenceChanged("ColorCalibration"); |
| update(); |
| } |
| |
| |
| |
| void SceneViewer::hideEvent(QHideEvent *) { |
| |
| |
| if (m_previewMode != NO_PREVIEW) |
| Previewer::instance(m_previewMode == SUBCAMERA_PREVIEW) |
| ->removeListener(this); |
| |
| TApp *app = TApp::instance(); |
| |
| TSceneHandle *sceneHandle = app->getCurrentScene(); |
| if (sceneHandle) sceneHandle->disconnect(this); |
| |
| TFrameHandle *frameHandle = app->getCurrentFrame(); |
| if (frameHandle) frameHandle->disconnect(this); |
| |
| TPaletteHandle *paletteHandle = |
| app->getPaletteController()->getCurrentLevelPalette(); |
| if (paletteHandle) paletteHandle->disconnect(this); |
| |
| TObjectHandle *objectHandle = app->getCurrentObject(); |
| if (objectHandle) objectHandle->disconnect(this); |
| |
| TOnionSkinMaskHandle *onionHandle = app->getCurrentOnionSkin(); |
| if (onionHandle) onionHandle->disconnect(this); |
| |
| TXshLevelHandle *levelHandle = app->getCurrentLevel(); |
| if (levelHandle) levelHandle->disconnect(this); |
| |
| TXsheetHandle *xsheetHandle = app->getCurrentXsheet(); |
| if (xsheetHandle) xsheetHandle->disconnect(this); |
| |
| ToolHandle *toolHandle = app->getCurrentTool(); |
| if (toolHandle) toolHandle->disconnect(this); |
| |
| disconnect(app, SIGNAL(tabletLeft()), this, SLOT(resetTabletStatus())); |
| |
| #if defined(x64) |
| if (m_stopMotion) { |
| disconnect(m_stopMotion, SIGNAL(newImageReady()), this, |
| SLOT(onNewStopMotionImageReady())); |
| disconnect(m_stopMotion, SIGNAL(liveViewStopped()), this, |
| SLOT(onStopMotionLiveViewStopped())); |
| } |
| #endif |
| |
| |
| if (m_locator && m_locator->isVisible()) m_locator->hide(); |
| } |
| |
| int SceneViewer::getVGuideCount() { |
| if (viewGuideToggle.getStatus()) |
| return m_vRuler->getGuideCount(); |
| else |
| return 0; |
| } |
| int SceneViewer::getHGuideCount() { |
| if (viewGuideToggle.getStatus()) |
| return m_hRuler->getGuideCount(); |
| else |
| return 0; |
| } |
| |
| double SceneViewer::getVGuide(int index) { return m_vRuler->getGuide(index); } |
| double SceneViewer::getHGuide(int index) { return m_hRuler->getGuide(index); } |
| |
| #if defined(x64) |
| |
| |
| void SceneViewer::onNewStopMotionImageReady() { |
| if (m_stopMotion->m_hasLineUpImage) { |
| |
| m_stopMotionLineUpImage = |
| (TRasterImageP)m_stopMotion->m_lineUpImage->clone(); |
| m_stopMotionLineUpImage->setDpi(m_stopMotion->m_liveViewDpi.x, |
| m_stopMotion->m_liveViewDpi.y); |
| m_hasStopMotionLineUpImage = true; |
| } |
| if (m_stopMotion->m_hasLiveViewImage) { |
| |
| m_stopMotionImage = m_stopMotion->m_liveViewImage->clone(); |
| m_stopMotionImage->setDpi(m_stopMotion->m_liveViewDpi.x, |
| m_stopMotion->m_liveViewDpi.y); |
| m_hasStopMotionImage = true; |
| if (m_stopMotion->m_canon->m_pickLiveViewZoom) { |
| setToolCursor(this, ToolCursor::ZoomCursor); |
| } |
| onSceneChanged(); |
| } |
| } |
| |
| |
| |
| void SceneViewer::onStopMotionLiveViewStopped() { |
| m_hasStopMotionImage = false; |
| m_hasStopMotionLineUpImage = false; |
| onSceneChanged(); |
| } |
| |
| #endif // x64 |
| |
| |
| void SceneViewer::onPreferenceChanged(const QString &prefName) { |
| if (prefName == "ColorCalibration") { |
| if (Preferences::instance()->isColorCalibrationEnabled()) { |
| |
| |
| if (!context()) return; |
| makeCurrent(); |
| if (!m_lutCalibrator) |
| m_lutCalibrator = new LutCalibrator(); |
| else |
| m_lutCalibrator->cleanup(); |
| m_lutCalibrator->initialize(); |
| connect(context(), SIGNAL(aboutToBeDestroyed()), this, |
| SLOT(onContextAboutToBeDestroyed())); |
| if (m_lutCalibrator->isValid() && !m_fbo) { |
| if (Preferences::instance()->is30bitDisplayEnabled()) { |
| QOpenGLFramebufferObjectFormat format; |
| format.setInternalTextureFormat(TGL_TexFmt10); |
| m_fbo = new QOpenGLFramebufferObject(width(), height(), format); |
| } else |
| m_fbo = new QOpenGLFramebufferObject(width(), height()); |
| } |
| doneCurrent(); |
| } |
| update(); |
| } |
| } |
| |
| |
| void SceneViewer::initializeGL() { |
| initializeOpenGLFunctions(); |
| |
| registerContext(); |
| |
| |
| if (m_lutCalibrator && !m_lutCalibrator->isInitialized()) { |
| m_lutCalibrator->initialize(); |
| connect(context(), SIGNAL(aboutToBeDestroyed()), this, |
| SLOT(onContextAboutToBeDestroyed())); |
| } |
| |
| |
| glClear(GL_COLOR_BUFFER_BIT); |
| |
| if (m_firstInitialized) |
| m_firstInitialized = false; |
| else { |
| resizeGL(width(), height()); |
| update(); |
| } |
| |
| m_tableDLId = -1; |
| } |
| |
| |
| |
| void SceneViewer::resizeGL(int w, int h) { |
| w *= getDevPixRatio(); |
| h *= getDevPixRatio(); |
| glViewport(0, 0, w, h); |
| glMatrixMode(GL_PROJECTION); |
| glLoadIdentity(); |
| glOrtho(0, w, 0, h, -4000, 4000); |
| m_projectionMatrix.setToIdentity(); |
| m_projectionMatrix.ortho(0, w, 0, h, -4000, 4000); |
| |
| glMatrixMode(GL_MODELVIEW); |
| glLoadIdentity(); |
| glTranslatef(0.375, 0.375, 0.0); |
| |
| glTranslated(w * 0.5, h * 0.5, 0); |
| |
| if (m_freezedStatus == NORMAL_FREEZED) m_freezedStatus = UPDATE_FREEZED; |
| |
| if (m_previewMode != NO_PREVIEW) requestTimedRefresh(); |
| |
| |
| if (m_lutCalibrator && m_lutCalibrator->isValid()) { |
| if (m_fbo) delete m_fbo; |
| if (Preferences::instance()->is30bitDisplayEnabled()) { |
| QOpenGLFramebufferObjectFormat format; |
| format.setInternalTextureFormat(TGL_TexFmt10); |
| m_fbo = new QOpenGLFramebufferObject(w, h, format); |
| } else |
| m_fbo = new QOpenGLFramebufferObject(w, h); |
| } |
| |
| |
| emit refreshNavi(); |
| } |
| |
| |
| |
| void SceneViewer::drawBuildVars() { |
| TApp *app = TApp::instance(); |
| |
| int frame = app->getCurrentFrame()->getFrame(); |
| TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); |
| |
| |
| TStageObjectId cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); |
| TStageObject *camera = xsh->getStageObject(cameraId); |
| TAffine cameraPlacement = camera->getPlacement(frame); |
| double cameraZ = camera->getZ(frame); |
| |
| m_drawCameraAff = |
| getViewMatrix() * cameraPlacement * TScale((1000 + cameraZ) / 1000); |
| |
| |
| TStageObject *table = xsh->getStageObject(TStageObjectId::TableId); |
| TAffine tablePlacement = table->getPlacement(frame); |
| double tableZ = table->getZ(frame); |
| TAffine placement; |
| |
| m_drawIsTableVisible = TStageObject::perspective( |
| placement, cameraPlacement, cameraZ, tablePlacement, tableZ, 0); |
| m_drawTableAff = getViewMatrix() * tablePlacement; |
| |
| |
| m_drawCameraTest = CameraTestCheck::instance()->isEnabled(); |
| |
| if (m_previewMode == NO_PREVIEW) { |
| m_drawEditingLevel = app->getCurrentFrame()->isEditingLevel(); |
| m_viewMode = m_drawEditingLevel ? LEVEL_VIEWMODE : SCENE_VIEWMODE; |
| m_draw3DMode = is3DView() && (m_previewMode != SUBCAMERA_PREVIEW); |
| } else { |
| m_drawEditingLevel = false; |
| m_viewMode = app->getCurrentFrame()->isEditingLevel(); |
| m_draw3DMode = false; |
| } |
| |
| |
| if (!m_clipRect.isEmpty() && !m_draw3DMode) { |
| m_actualClipRect = getActualClipRect(getViewMatrix()); |
| m_actualClipRect += TPoint(width() * 0.5, height() * 0.5); |
| } |
| |
| TTool *tool = app->getCurrentTool()->getTool(); |
| if (tool && !m_isLocator) tool->setViewer(this); |
| } |
| |
| |
| |
| void SceneViewer::drawEnableScissor() { |
| if (!m_clipRect.isEmpty() && !m_draw3DMode) { |
| glEnable(GL_SCISSOR_TEST); |
| glScissor(m_actualClipRect.x0, m_actualClipRect.y0, |
| m_actualClipRect.getLx(), m_actualClipRect.getLy()); |
| } |
| } |
| |
| |
| |
| void SceneViewer::drawDisableScissor() { |
| if (!m_clipRect.isEmpty() && !m_draw3DMode) { |
| glDisable(GL_SCISSOR_TEST); |
| } |
| |
| m_clipRect.empty(); |
| } |
| |
| |
| |
| void SceneViewer::drawBackground() { |
| TApp *app = TApp::instance(); |
| ToonzScene *scene = app->getCurrentScene()->getScene(); |
| |
| if (m_visualSettings.m_colorMask == 0) { |
| TPixel32 bgColor; |
| |
| if (isPreviewEnabled()) |
| bgColor = Preferences::instance()->getPreviewBgColor(); |
| else |
| bgColor = Preferences::instance()->getViewerBgColor(); |
| glClearColor(bgColor.r / 255.0f, bgColor.g / 255.0f, bgColor.b / 255.0f, |
| 1.0); |
| } else |
| glClearColor(0, 0, 0, 1.0); |
| |
| glClear(GL_COLOR_BUFFER_BIT); |
| if (glGetError() == GL_INVALID_FRAMEBUFFER_OPERATION) { |
| |
| |
| GLenum status = 0; |
| #ifdef _WIN32 |
| PROC proc = wglGetProcAddress("glCheckFramebufferStatusEXT"); |
| if (proc != nullptr) |
| status = reinterpret_cast<PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC>(proc)( |
| GL_FRAMEBUFFER); |
| #else |
| status = glCheckFramebufferStatus(GL_FRAMEBUFFER); |
| #endif |
| printf("GL_INVALID_FRAMEBUFFER_OPERATION: framebuffer:%d\n", status); |
| } |
| } |
| |
| static bool check_framebuffer_status() { |
| #ifdef _WIN32 |
| PROC proc = wglGetProcAddress("glCheckFramebufferStatusEXT"); |
| if (proc == nullptr) return true; |
| GLenum s = reinterpret_cast<PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC>(proc)( |
| GL_FRAMEBUFFER); |
| #else |
| GLenum s = glCheckFramebufferStatus(GL_FRAMEBUFFER); |
| #endif |
| if (s == GL_FRAMEBUFFER_UNDEFINED) |
| printf("Warning: FB undefined: %d\n", s); |
| else if (s == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT) |
| printf("Warning: FB incomplete(attachment): %d\n", s); |
| else if (s == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) |
| printf("Warning: FB incomplete(missing attachment): %d\n", s); |
| else if (s == GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER) |
| printf("Warning: FB incomplete(draw buffer): %d\n", s); |
| else if (s == GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER) |
| printf("Warning: FB incomplete(read buffer): %d\n", s); |
| else if (s == GL_FRAMEBUFFER_UNSUPPORTED) |
| printf("Warning: FB unsupported: %d\n", s); |
| else if (s == GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE) |
| printf("Warning: FB incomplete(multi-sample): %d\n", s); |
| else if (s == GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS) |
| printf("Warning: FB incomplete(multi-sample): %d\n", s); |
| else if (s == GL_FRAMEBUFFER_COMPLETE) |
| ; |
| else |
| printf("Warning: FB not complete(unknown cause): %d\n", s); |
| return s == GL_FRAMEBUFFER_COMPLETE; |
| } |
| |
| |
| |
| void SceneViewer::drawCameraStand() { |
| GLint e = glGetError(); |
| check_framebuffer_status(); |
| assert(e == GL_NO_ERROR); |
| |
| TXshSimpleLevel::m_rasterizePli = rasterizePliToggle.getStatus(); |
| |
| |
| if (m_visualSettings.m_blankColor != TPixel::Transparent) { |
| glClearColor(m_visualSettings.m_blankColor.r / 255.0f, |
| m_visualSettings.m_blankColor.g / 255.0f, |
| m_visualSettings.m_blankColor.b / 255.0f, 1.0); |
| glClear(GL_COLOR_BUFFER_BIT); |
| return; |
| } |
| |
| |
| if (m_draw3DMode) { |
| glEnable(GL_DEPTH_TEST); |
| glDepthFunc(GL_ALWAYS); |
| glClear(GL_DEPTH_BUFFER_BIT); |
| glPushMatrix(); |
| mult3DMatrix(); |
| } else |
| glDisable(GL_DEPTH_TEST); |
| |
| assert(glGetError() == GL_NO_ERROR); |
| |
| |
| if (!m_draw3DMode && viewTableToggle.getStatus() && m_drawIsTableVisible && |
| m_visualSettings.m_colorMask == 0 && m_drawEditingLevel == false && |
| !m_drawCameraTest) { |
| glPushMatrix(); |
| tglMultMatrix(m_drawTableAff); |
| ViewerDraw::drawDisk(m_tableDLId); |
| glPopMatrix(); |
| } |
| |
| |
| |
| if (m_drawEditingLevel == false && viewClcToggle.getStatus() && |
| !m_drawCameraTest) { |
| glPushMatrix(); |
| tglMultMatrix(m_drawCameraAff); |
| glEnable(GL_BLEND); |
| glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
| ViewerDraw::drawColorcard(m_visualSettings.m_colorMask); |
| glDisable(GL_BLEND); |
| glPopMatrix(); |
| } |
| |
| |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| if (m_drawEditingLevel && tool && tool->isEnabled()) { |
| if (!m_isLocator) tool->setViewer(this); |
| glPushMatrix(); |
| if (m_referenceMode == CAMERA3D_REFERENCE) { |
| mult3DMatrix(); |
| tglMultMatrix(tool->getMatrix()); |
| } else { |
| tglMultMatrix(getViewMatrix() * tool->getMatrix()); |
| } |
| glScaled(m_dpiScale.x, m_dpiScale.y, 1); |
| |
| TImageP image = tool->getImage(false); |
| |
| TToonzImageP ti = image; |
| TRasterImageP ri = image; |
| if (ti) { |
| TRect imgRect(0, 0, ti->getSize().lx - 1, ti->getSize().ly - 1); |
| TRectD bbox = ToonzImageUtils::convertRasterToWorld(imgRect, ti); |
| |
| TPixel32 imgRectColor; |
| |
| if (ToonzCheck::instance()->getChecks() & ToonzCheck::eBlackBg) |
| imgRectColor = TPixel::Black; |
| else |
| imgRectColor = Preferences::instance()->getLevelEditorBoxColor(); |
| ToolUtils::fillRect(bbox * ti->getSubsampling(), imgRectColor); |
| } else if (ri) { |
| TRectD bbox = ri->getBBox(); |
| bbox.x0 -= ri->getBBox().getLx() * 0.5; |
| bbox.x1 -= ri->getBBox().getLx() * 0.5; |
| bbox.y0 -= ri->getBBox().getLy() * 0.5; |
| bbox.y1 -= ri->getBBox().getLy() * 0.5; |
| |
| TPixel32 imgRectColor; |
| |
| if (ToonzCheck::instance()->getChecks() & ToonzCheck::eBlackBg) |
| imgRectColor = TPixel::Black; |
| else |
| imgRectColor = Preferences::instance()->getLevelEditorBoxColor(); |
| ToolUtils::fillRect(bbox * ri->getSubsampling(), imgRectColor); |
| } |
| glPopMatrix(); |
| } |
| |
| |
| if (m_draw3DMode) { |
| glDepthFunc(GL_LEQUAL); |
| ViewerDraw::draw3DFrame(m_minZ, m_phi3D); |
| glDepthFunc(GL_ALWAYS); |
| } |
| |
| |
| assert(glGetError() == GL_NO_ERROR); |
| drawScene(); |
| assert((glGetError()) == GL_NO_ERROR); |
| } |
| |
| |
| |
| void SceneViewer::drawPreview() { |
| const double inch = Stage::inch; |
| TApp *app = TApp::instance(); |
| int row = app->getCurrentFrame()->getFrame(); |
| TCamera *currCamera = app->getCurrentScene()->getScene()->getCurrentCamera(); |
| TDimensionD cameraSize = currCamera->getSize(); |
| |
| Previewer *previewer = |
| Previewer::instance(m_previewMode == SUBCAMERA_PREVIEW); |
| |
| TRasterP ras = |
| previewer->getRaster(row, m_visualSettings.m_recomputeIfNeeded); |
| if (ras) { |
| TRectD previewStageRectD, cameraStageRectD = currCamera->getStageRect(); |
| |
| TRect subCameraRect(currCamera->getInterestRect()); |
| if (m_previewMode == SUBCAMERA_PREVIEW && subCameraRect.getLx() > 0 && |
| subCameraRect.getLy() > 0) |
| previewStageRectD = currCamera->getInterestStageRect(); |
| else |
| previewStageRectD = cameraStageRectD; |
| |
| TAffine rasterToStageRef( |
| previewStageRectD.getLx() / ras->getLx(), 0.0, |
| previewStageRectD.x0 + 0.5 * previewStageRectD.getLx(), 0.0, |
| previewStageRectD.getLy() / ras->getLy(), |
| previewStageRectD.y0 + 0.5 * previewStageRectD.getLy()); |
| |
| TDimension dim(width(), height()); |
| TAffine finalAff = m_drawCameraAff * rasterToStageRef; |
| m_visualSettings.m_useTexture = !Preferences::instance()->useDrawPixel(); |
| ImagePainter::paintImage(TRasterImageP(ras), ras->getSize(), dim, finalAff, |
| m_visualSettings, m_compareSettings, TRect()); |
| } |
| |
| glPushMatrix(); |
| tglMultMatrix(m_drawCameraAff); |
| |
| TRectD frameRect(cameraSize); |
| frameRect.x1 *= inch; |
| frameRect.y1 *= inch; |
| frameRect -= 0.5 * (frameRect.getP00() + frameRect.getP11()); |
| |
| if (m_visualSettings.m_blankColor != TPixel::Transparent) { |
| tglColor(m_visualSettings.m_blankColor); |
| tglFillRect(frameRect); |
| } |
| |
| if (!previewer->isFrameReady(row) || |
| (app->getCurrentFrame()->isPlaying() && previewer->isBusy())) { |
| glColor3d(1, 0, 0); |
| |
| tglDrawRect(frameRect); |
| tglDrawRect(frameRect.enlarge(5)); |
| } |
| |
| glPopMatrix(); |
| } |
| |
| |
| |
| void SceneViewer::drawOverlay() { |
| TApp *app = TApp::instance(); |
| |
| |
| if (m_referenceMode == CAMERA_REFERENCE && !m_drawCameraTest) { |
| glPushMatrix(); |
| tglMultMatrix(m_drawCameraAff); |
| ViewerDraw::drawCameraMask(this); |
| glPopMatrix(); |
| } |
| |
| |
| if (fieldGuideToggle.getStatus()) { |
| glPushMatrix(); |
| tglMultMatrix(m_drawTableAff); |
| ViewerDraw::drawFieldGuide(); |
| glPopMatrix(); |
| } |
| |
| if (!m_drawCameraTest) { |
| |
| if (viewGuideToggle.getStatus() && |
| ((m_vRuler && m_vRuler->getGuideCount()) || |
| (m_hRuler && m_hRuler->getGuideCount()))) { |
| glPushMatrix(); |
| tglMultMatrix(getViewMatrix()); |
| ViewerDraw::drawGridAndGuides( |
| this, (m_draw3DMode) ? m_zoomScale3D : m_viewAff[m_viewMode].det(), |
| m_vRuler, m_hRuler, false); |
| glPopMatrix(); |
| } |
| |
| |
| if (viewCameraToggle.getStatus() && m_drawEditingLevel == false) { |
| unsigned long f = 0; |
| if (m_referenceMode == CAMERA_REFERENCE) |
| f |= ViewerDraw::CAMERA_REFERENCE; |
| if (m_draw3DMode) f |= ViewerDraw::CAMERA_3D; |
| if (m_previewMode == SUBCAMERA_PREVIEW || m_editPreviewSubCamera) |
| f |= ViewerDraw::SUBCAMERA; |
| if (m_draw3DMode) |
| ViewerDraw::draw3DCamera(f, m_minZ, m_phi3D); |
| else { |
| glPushMatrix(); |
| tglMultMatrix(m_drawCameraAff); |
| m_pixelSize = sqrt(tglGetPixelSize2()) * getDevPixRatio(); |
| ViewerDraw::drawCamera(f, m_pixelSize); |
| glPopMatrix(); |
| } |
| } |
| |
| #ifdef WITH_CANON |
| if (m_stopMotion->m_liveViewStatus == StopMotion::LiveViewOpen && |
| app->getCurrentFrame()->getFrame() == |
| m_stopMotion->getXSheetFrameNumber() - 1) { |
| int x0, x1, y0, y1; |
| rect().getCoords(&x0, &y0, &x1, &y1); |
| x0 = (-(x1 / 2)) + 15; |
| y0 = ((y1 / 2)) - 15; |
| tglDrawDisk(TPointD(x0, y0), 10); |
| } |
| |
| |
| if (m_stopMotion->m_liveViewStatus == 2 && |
| m_stopMotion->m_canon->m_pickLiveViewZoom) { |
| glPushMatrix(); |
| tglMultMatrix(m_drawCameraAff); |
| m_pixelSize = sqrt(tglGetPixelSize2()) * getDevPixRatio(); |
| TRect rect = m_stopMotion->m_canon->m_zoomRect; |
| |
| glColor3d(1.0, 0.0, 0.0); |
| |
| |
| glBegin(GL_LINE_STRIP); |
| glVertex2d(rect.x0, rect.y0); |
| glVertex2d(rect.x0, rect.y1 - m_pixelSize); |
| glVertex2d(rect.x1 - m_pixelSize, rect.y1 - m_pixelSize); |
| glVertex2d(rect.x1 - m_pixelSize, rect.y0); |
| glVertex2d(rect.x0, rect.y0); |
| glEnd(); |
| |
| glPopMatrix(); |
| } |
| |
| #endif |
| |
| |
| if (safeAreaToggle.getStatus() && m_drawEditingLevel == false && |
| !is3DView()) { |
| glPushMatrix(); |
| tglMultMatrix(m_drawCameraAff); |
| ViewerDraw::drawSafeArea(); |
| glPopMatrix(); |
| } |
| |
| |
| if (app->getCurrentFrame()->isPlaying()) |
| m_FPS = getActualFrameRate(); |
| else |
| m_FPS = 0; |
| |
| if (m_freezedStatus != NO_FREEZED) { |
| tglColor(TPixel32::Red); |
| tglDrawText(TPointD(0, 0), "FROZEN"); |
| } |
| assert(glGetError() == GL_NO_ERROR); |
| |
| } |
| |
| |
| if (m_draw3DMode && !m_isPicking) { |
| tglColor(TPixel32::Black); |
| |
| GLdouble modelView3D[16]; |
| GLdouble projection3D[16]; |
| GLint viewport3D[4]; |
| |
| glGetDoublev(GL_MODELVIEW_MATRIX, modelView3D); |
| glGetDoublev(GL_PROJECTION_MATRIX, projection3D); |
| glGetIntegerv(GL_VIEWPORT, viewport3D); |
| |
| if (m_phi3D > 0) { |
| T3DPointD topRasterPos3D = computeNew3DPosition( |
| T3DPointD(500, 500, 1000), TPointD(-10, -10), m_topRasterPos, |
| modelView3D, projection3D, viewport3D, getDevPixRatio()); |
| glRasterPos3f(topRasterPos3D.x, topRasterPos3D.y, topRasterPos3D.z); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
| glDrawPixels(m_3DTop->getWrap(), m_3DTop->getLy(), TGL_FMT, TGL_TYPE, |
| m_3DTop->getRawData()); |
| |
| T3DPointD sideRasterPos3D = computeNew3DPosition( |
| T3DPointD(-500, -500, 1000), TPointD(-10, -10), m_sideRasterPos, |
| modelView3D, projection3D, viewport3D, getDevPixRatio()); |
| glRasterPos3f(sideRasterPos3D.x, sideRasterPos3D.y, sideRasterPos3D.z); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
| glDrawPixels(m_3DSideR->getWrap(), m_3DSideR->getLy(), TGL_FMT, TGL_TYPE, |
| m_3DSideR->getRawData()); |
| } else { |
| T3DPointD topRasterPos3D = computeNew3DPosition( |
| T3DPointD(-500, 500, 1000), TPointD(-10, -10), m_topRasterPos, |
| modelView3D, projection3D, viewport3D, getDevPixRatio()); |
| glRasterPos3f(topRasterPos3D.x, topRasterPos3D.y, topRasterPos3D.z); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
| glDrawPixels(m_3DTop->getWrap(), m_3DTop->getLy(), TGL_FMT, TGL_TYPE, |
| m_3DTop->getRawData()); |
| |
| T3DPointD sideRasterPos3D = computeNew3DPosition( |
| T3DPointD(500, -500, 1000), TPointD(-10, -10), m_sideRasterPos, |
| modelView3D, projection3D, viewport3D, getDevPixRatio()); |
| glRasterPos3f(sideRasterPos3D.x, sideRasterPos3D.y, sideRasterPos3D.z); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
| glDrawPixels(m_3DSideL->getWrap(), m_3DSideL->getLy(), TGL_FMT, TGL_TYPE, |
| m_3DSideL->getRawData()); |
| } |
| } |
| |
| if (m_draw3DMode) { |
| glDisable(GL_DEPTH_TEST); |
| glPopMatrix(); |
| assert(glGetError() == GL_NO_ERROR); |
| } |
| |
| |
| TTool *tool = app->getCurrentTool()->getTool(); |
| TXshSimpleLevel *sl = app->getCurrentLevel()->getSimpleLevel(); |
| |
| if (tool && (tool->isEnabled() || (sl && sl->isReadOnly()))) { |
| |
| |
| glPushMatrix(); |
| if (m_draw3DMode) { |
| mult3DMatrix(); |
| tglMultMatrix(tool->getMatrix()); |
| } else |
| tglMultMatrix(getViewMatrix() * tool->getMatrix()); |
| if (tool->getToolType() & TTool::LevelTool && |
| !app->getCurrentObject()->isSpline()) |
| glScaled(m_dpiScale.x, m_dpiScale.y, 1); |
| m_pixelSize = sqrt(tglGetPixelSize2()) * getDevPixRatio(); |
| |
| unsigned int hints = tool->getToolHints(); |
| |
| |
| m_toolHasAssistants = false; |
| if (hints & TTool::HintAssistantsAll) { |
| m_toolHasAssistants = TAssistant::scanAssistants( |
| tool, |
| &m_toolPos, 1, |
| nullptr, |
| true, |
| false, |
| hints & TTool::HintAssistantsEnabled, |
| true, |
| nullptr ); |
| } |
| |
| |
| if (hints & TTool::HintReplicatorsAll) { |
| TReplicator::scanReplicators( |
| tool, |
| nullptr, |
| true, |
| false, |
| hints & TTool::HintReplicatorsEnabled, |
| nullptr ); |
| } |
| |
| |
| tool->draw(); |
| |
| glPopMatrix(); |
| |
| |
| |
| |
| |
| |
| |
| if (tool->getName() == "T_RGBPicker") tool->onImageChanged(); |
| |
| |
| if (m_isLocator) { |
| glColor3d(1.0, 0.0, 0.0); |
| tglDrawSegment(TPointD(-4, 0), TPointD(5, 0)); |
| tglDrawSegment(TPointD(0, -4), TPointD(0, 5)); |
| } |
| } |
| } |
| |
| |
| |
| static void drawFpsGraph(int t0, int t1) { |
| glDisable(GL_BLEND); |
| static std::deque<std::pair<int, int>> times; |
| times.push_back(std::make_pair(t0, t1)); |
| while (times.size() > 200) times.pop_front(); |
| double x0 = 10, y0 = 10; |
| double x1 = x0 + 200; |
| double y1 = y0 + 150; |
| glPushMatrix(); |
| glLoadIdentity(); |
| glColor3d(0, 0, 0); |
| glRectd(x0, y0, x1, y1); |
| glColor3d(0, 0.5, 1); |
| glBegin(GL_LINE_STRIP); |
| glVertex2d(x0, y0); |
| glVertex2d(x1, y0); |
| glVertex2d(x1, y1); |
| glVertex2d(x0, y1); |
| glVertex2d(x0, y0); |
| glEnd(); |
| glColor3d(0.5, 0.5, 0.5); |
| glBegin(GL_LINES); |
| for (int y = y0 + 5; y < y1; y += 20) { |
| glVertex2d(x0, y); |
| glVertex2d(x1, y); |
| } |
| for (int i = 0; i < (int)times.size(); i++) { |
| double x = x1 - i; |
| glColor3d(1, 0, 0); |
| glVertex2d(x, y0); |
| glVertex2d(x, y0 + 5 + times[i].first / 5); |
| glColor3d(0, 1, 0); |
| glVertex2d(x, y0 + 5 + times[i].first / 5); |
| glVertex2d(x, y0 + 5 + times[i].second / 5); |
| } |
| glEnd(); |
| glPopMatrix(); |
| } |
| |
| |
| |
| |
| |
| void SceneViewer::paintGL() { |
| #ifdef _DEBUG |
| if (!check_framebuffer_status()) { |
| |
| |
| return; |
| } |
| #endif |
| #ifdef MACOSX |
| |
| |
| |
| if (m_isMouseEntered && m_forceGlFlush) { |
| m_isMouseEntered = false; |
| m_forceGlFlush = false; |
| glDrawBuffer(GL_FRONT); |
| glFlush(); |
| glDrawBuffer(GL_BACK); |
| } |
| #endif |
| |
| #ifdef FPS_HISTOGRAM |
| QTime time; |
| time.start(); |
| #endif |
| |
| if (!m_isPicking && m_lutCalibrator && m_lutCalibrator->isValid()) |
| m_fbo->bind(); |
| |
| if (m_hRuler && m_vRuler) { |
| if (!viewRulerToggle.getStatus() && |
| (m_hRuler->isVisible() || m_vRuler->isVisible())) { |
| m_hRuler->hide(); |
| m_vRuler->hide(); |
| } else if (viewRulerToggle.getStatus() && |
| (!m_hRuler->isVisible() || !m_vRuler->isVisible())) { |
| m_hRuler->show(); |
| m_vRuler->show(); |
| } |
| } |
| |
| |
| if (m_freezedStatus == NORMAL_FREEZED) { |
| assert(!!m_viewGrabImage); |
| m_viewGrabImage->lock(); |
| glPushMatrix(); |
| glLoadIdentity(); |
| |
| glRasterPos2d(0, 0); |
| glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
| |
| glDrawPixels(m_viewGrabImage->getLx(), m_viewGrabImage->getLy(), TGL_FMT, |
| TGL_TYPE, m_viewGrabImage->getRawData()); |
| |
| glPopMatrix(); |
| m_viewGrabImage->unlock(); |
| |
| if (!m_isPicking && m_lutCalibrator && m_lutCalibrator->isValid()) |
| m_lutCalibrator->onEndDraw(m_fbo); |
| |
| return; |
| } |
| |
| drawBuildVars(); |
| |
| |
| |
| |
| drawEnableScissor(); |
| drawBackground(); |
| |
| if (m_previewMode != FULL_PREVIEW) { |
| drawCameraStand(); |
| } |
| |
| if (isPreviewEnabled()) drawPreview(); |
| |
| drawOverlay(); |
| |
| drawDisableScissor(); |
| |
| |
| if (m_freezedStatus == UPDATE_FREEZED) { |
| m_viewGrabImage = rasterFromQImage(grabFramebuffer()); |
| m_freezedStatus = NORMAL_FREEZED; |
| } |
| |
| #ifdef FPS_HISTOGRAM |
| int t0 = time.elapsed(); |
| glFlush(); |
| glFinish(); |
| int t1 = time.elapsed(); |
| drawFpsGraph(t0, t1); |
| #endif |
| |
| |
| if (!m_isPicking && m_lutCalibrator && m_lutCalibrator->isValid()) |
| m_lutCalibrator->onEndDraw(m_fbo); |
| } |
| |
| |
| |
| void SceneViewer::drawScene() { |
| TApp *app = TApp::instance(); |
| ToonzScene *scene = app->getCurrentScene()->getScene(); |
| int frame = app->getCurrentFrame()->getFrame(); |
| TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); |
| TRect clipRect = getActualClipRect(getViewMatrix()); |
| clipRect += TPoint(width() * 0.5, height() * 0.5); |
| |
| ChildStack *childStack = scene->getChildStack(); |
| bool editInPlace = editInPlaceToggle.getStatus() && |
| !app->getCurrentFrame()->isEditingLevel(); |
| |
| bool fillFullColorRaster = TXshSimpleLevel::m_fillFullColorRaster; |
| TXshSimpleLevel::m_fillFullColorRaster = false; |
| |
| |
| int useGuidedDrawing = Preferences::instance()->getGuidedDrawingType(); |
| TTool *tool = app->getCurrentTool()->getTool(); |
| int guidedFrontStroke = tool ? tool->getViewer()->getGuidedFrontStroke() : -1; |
| int guidedBackStroke = tool ? tool->getViewer()->getGuidedBackStroke() : -1; |
| |
| m_minZ = 0; |
| if (is3DView()) { |
| Stage::OpenGlPainter painter(getViewMatrix(), clipRect, m_visualSettings, |
| true, false); |
| painter.enableCamera3D(true); |
| painter.setPhi(m_phi3D); |
| int xsheetLevel = 0; |
| std::pair<TXsheet *, int> xr; |
| if (editInPlace) { |
| xr = childStack->getAncestor(frame); |
| xsheetLevel = childStack->getAncestorCount(); |
| } else |
| xr = std::make_pair(xsh, frame); |
| |
| Stage::VisitArgs args; |
| args.m_scene = scene; |
| args.m_xsh = xr.first; |
| args.m_row = xr.second; |
| args.m_col = app->getCurrentColumn()->getColumnIndex(); |
| OnionSkinMask osm = app->getCurrentOnionSkin()->getOnionSkinMask(); |
| args.m_osm = &osm; |
| args.m_camera3d = true; |
| args.m_xsheetLevel = xsheetLevel; |
| args.m_currentFrameId = |
| app->getCurrentXsheet() |
| ->getXsheet() |
| ->getCell(app->getCurrentFrame()->getFrame(), args.m_col) |
| .getFrameId(); |
| args.m_isGuidedDrawingEnabled = useGuidedDrawing; |
| args.m_guidedFrontStroke = guidedFrontStroke; |
| args.m_guidedBackStroke = guidedBackStroke; |
| |
| |
| Stage::visit(painter, args); |
| |
| m_minZ = painter.getMinZ(); |
| } else { |
| |
| TDimension viewerSize(width(), height()); |
| |
| TAffine viewAff = getViewMatrix(); |
| |
| if (editInPlace) { |
| TAffine aff; |
| if (scene->getChildStack()->getAncestorAffine(aff, frame)) |
| viewAff = viewAff * aff.inv(); |
| } |
| |
| m_visualSettings.m_showBBox = viewBBoxToggle.getStatus(); |
| |
| Stage::RasterPainter painter(viewerSize, viewAff, clipRect, |
| m_visualSettings, true); |
| |
| |
| |
| painter.setRasterDarkenBlendedView( |
| Preferences::instance() |
| ->isShowRasterImagesDarkenBlendedInViewerEnabled()); |
| |
| TFrameHandle *frameHandle = TApp::instance()->getCurrentFrame(); |
| if (app->getCurrentFrame()->isEditingLevel()) { |
| Stage::visit(painter, app->getCurrentLevel()->getLevel(), |
| app->getCurrentFrame()->getFid(), |
| app->getCurrentOnionSkin()->getOnionSkinMask(), |
| frameHandle->isPlaying(), useGuidedDrawing, guidedBackStroke, |
| guidedFrontStroke); |
| } else { |
| std::pair<TXsheet *, int> xr; |
| int xsheetLevel = 0; |
| if (editInPlace) { |
| xr = scene->getChildStack()->getAncestor(frame); |
| xsheetLevel = scene->getChildStack()->getAncestorCount(); |
| } else |
| xr = std::make_pair(xsh, frame); |
| |
| Stage::VisitArgs args; |
| args.m_scene = scene; |
| args.m_xsh = xr.first; |
| args.m_row = xr.second; |
| args.m_col = app->getCurrentColumn()->getColumnIndex(); |
| OnionSkinMask osm = app->getCurrentOnionSkin()->getOnionSkinMask(); |
| args.m_osm = &osm; |
| args.m_xsheetLevel = xsheetLevel; |
| args.m_isPlaying = frameHandle->isPlaying(); |
| if (app->getCurrentLevel() && app->getCurrentLevel()->getLevel() && |
| !app->getCurrentLevel()->getLevel()->getSoundLevel()) |
| args.m_currentFrameId = |
| app->getCurrentXsheet() |
| ->getXsheet() |
| ->getCell(app->getCurrentFrame()->getFrame(), args.m_col) |
| .getFrameId(); |
| args.m_isGuidedDrawingEnabled = useGuidedDrawing; |
| args.m_guidedFrontStroke = guidedFrontStroke; |
| args.m_guidedBackStroke = guidedBackStroke; |
| |
| #if defined(x64) |
| if (m_stopMotion->m_alwaysUseLiveViewImages && |
| m_stopMotion->m_liveViewStatus > 0 && |
| frame != m_stopMotion->getXSheetFrameNumber() - 1 && |
| m_hasStopMotionImage && !m_stopMotion->m_reviewTimer->isActive()) { |
| TRaster32P image; |
| bool hasImage = m_stopMotion->loadLiveViewImage(frame, image); |
| if (hasImage) { |
| Stage::Player smPlayer; |
| double dpiX, dpiY; |
| m_stopMotionImage->getDpi(dpiX, dpiY); |
| smPlayer.m_dpiAff = TScale(Stage::inch / dpiX, Stage::inch / dpiY); |
| smPlayer.m_opacity = 255; |
| smPlayer.m_sl = m_stopMotion->m_sl; |
| args.m_liveViewImage = static_cast<TRasterImageP>(image); |
| args.m_liveViewPlayer = smPlayer; |
| |
| |
| } |
| } |
| if ( |
| m_stopMotion->m_liveViewStatus == 2 && |
| ( |
| frame == m_stopMotion->getXSheetFrameNumber() - 1)) { |
| if (m_hasStopMotionLineUpImage && m_stopMotion->m_showLineUpImage) { |
| Stage::Player smPlayer; |
| double dpiX, dpiY; |
| m_stopMotionLineUpImage->getDpi(dpiX, dpiY); |
| smPlayer.m_dpiAff = TScale(Stage::inch / dpiX, Stage::inch / dpiY); |
| smPlayer.m_opacity = 255; |
| smPlayer.m_sl = m_stopMotion->m_sl; |
| args.m_lineupImage = m_stopMotionLineUpImage; |
| args.m_lineupPlayer = smPlayer; |
| |
| |
| } |
| if (m_hasStopMotionImage) { |
| Stage::Player smPlayer; |
| double dpiX, dpiY; |
| m_stopMotionImage->getDpi(dpiX, dpiY); |
| smPlayer.m_dpiAff = TScale(Stage::inch / dpiX, Stage::inch / dpiY); |
| bool hide_opacity = false; |
| #ifdef WITH_CANON |
| hide_opacity = m_stopMotion->m_canon->m_zooming || |
| m_stopMotion->m_canon->m_pickLiveViewZoom || |
| !m_hasStopMotionLineUpImage; |
| #endif |
| smPlayer.m_opacity = |
| hide_opacity ? 255.0 : m_stopMotion->getOpacity(); |
| smPlayer.m_sl = m_stopMotion->m_sl; |
| args.m_liveViewImage = m_stopMotionImage; |
| args.m_liveViewPlayer = smPlayer; |
| |
| } |
| } |
| #endif // x64 |
| Stage::visit(painter, args); |
| } |
| |
| assert(glGetError() == 0); |
| painter.flushRasterImages(); |
| |
| TXshSimpleLevel::m_fillFullColorRaster = fillFullColorRaster; |
| |
| assert(glGetError() == 0); |
| if (m_viewMode != LEVEL_VIEWMODE) |
| drawSpline(getViewMatrix(), clipRect, |
| m_referenceMode == CAMERA3D_REFERENCE, m_pixelSize); |
| assert(glGetError() == 0); |
| |
| |
| |
| std::vector<TStroke *> guidedStrokes = painter.getGuidedStrokes(); |
| for (auto itr = guidedStrokes.begin(); itr != guidedStrokes.end(); ++itr) { |
| m_guidedDrawingBBox += (*itr)->getBBox(); |
| } |
| } |
| } |
| |
| |
| |
| void SceneViewer::mult3DMatrix() { |
| glTranslated(m_pan3D.x, m_pan3D.y, 0); |
| glScaled(m_zoomScale3D, m_zoomScale3D, 1); |
| glRotated(m_theta3D, 1, 0, 0); |
| glRotated(m_phi3D, 0, 1, 0); |
| } |
| |
| |
| |
| double SceneViewer::projectToZ(const TPointD &delta) { |
| glPushMatrix(); |
| mult3DMatrix(); |
| GLint viewport[4]; |
| double modelview[16], projection[16]; |
| glGetIntegerv(GL_VIEWPORT, viewport); |
| for (int i = 0; i < 16; i++) |
| projection[i] = (double)m_projectionMatrix.constData()[i]; |
| glGetDoublev(GL_MODELVIEW_MATRIX, modelview); |
| |
| double ax, ay, az, bx, by, bz; |
| gluProject(0, 0, 0, modelview, projection, viewport, &ax, &ay, &az); |
| gluProject(0, 0, 1, modelview, projection, viewport, &bx, &by, &bz); |
| |
| glPopMatrix(); |
| TPointD zdir(bx - ax, by - ay); |
| double zdirLength2 = norm2(zdir); |
| if (zdirLength2 > 0.0) { |
| double dz = (delta * zdir) / zdirLength2; |
| return dz; |
| } else |
| return 0.0; |
| } |
| |
| |
| |
| TRect SceneViewer::getActualClipRect(const TAffine &aff) { |
| TDimensionD viewerSize(width(), height()); |
| TRectD clipRect(viewerSize); |
| |
| if (is3DView()) { |
| TPointD p00 = winToWorld(clipRect.getP00()); |
| TPointD p01 = winToWorld(clipRect.getP01()); |
| TPointD p10 = winToWorld(clipRect.getP10()); |
| TPointD p11 = winToWorld(clipRect.getP11()); |
| clipRect = TRectD(TPointD(std::min(p00.x, p01.x), std::min(p00.y, p10.y)), |
| TPointD(std::max(p11.x, p10.x), std::max(p11.y, p01.y))); |
| } |
| |
| |
| else if (m_clipRect.isEmpty()) |
| clipRect -= TPointD(viewerSize.lx / 2, viewerSize.ly / 2); |
| else { |
| clipRect = aff * (m_clipRect.enlarge(3)); |
| } |
| |
| clipRect *= TRectD(viewerSize) - TPointD(viewerSize.lx/2, viewerSize.ly/2); |
| return convert(clipRect); |
| } |
| |
| |
| |
| TAffine4 SceneViewer::get3dViewMatrix() const { |
| if (is3DView()) { |
| TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet(); |
| TStageObjectId cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); |
| double z = xsh->getStageObject(cameraId)->getZ( |
| TApp::instance()->getCurrentFrame()->getFrame()); |
| |
| TAffine4 affine; |
| affine *= TAffine4::translation(m_pan3D.x, m_pan3D.y, z); |
| affine *= TAffine4::scale(m_zoomScale3D, m_zoomScale3D, m_zoomScale3D); |
| affine *= TAffine4::rotationX(M_PI_180*m_theta3D); |
| affine *= TAffine4::rotationY(M_PI_180*m_phi3D); |
| return affine; |
| } |
| |
| int viewMode = TApp::instance()->getCurrentFrame()->isEditingLevel() |
| ? LEVEL_VIEWMODE |
| : SCENE_VIEWMODE; |
| |
| if (m_referenceMode == CAMERA_REFERENCE) { |
| int frame = TApp::instance()->getCurrentFrame()->getFrame(); |
| TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet(); |
| TAffine aff = xsh->getCameraAff(frame); |
| return TAffine4(m_viewAff[viewMode] * aff.inv()); |
| } |
| |
| return TAffine4(m_viewAff[viewMode]); |
| } |
| |
| |
| |
| TAffine SceneViewer::getViewMatrix() const { |
| int viewMode = TApp::instance()->getCurrentFrame()->isEditingLevel() |
| ? LEVEL_VIEWMODE |
| : SCENE_VIEWMODE; |
| if (is3DView()) return TAffine(); |
| if (m_referenceMode == CAMERA_REFERENCE) { |
| int frame = TApp::instance()->getCurrentFrame()->getFrame(); |
| TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet(); |
| TAffine aff = xsh->getCameraAff(frame); |
| return m_viewAff[viewMode] * aff.inv(); |
| } else |
| return m_viewAff[viewMode]; |
| } |
| |
| |
| |
| TAffine SceneViewer::getSceneMatrix() const { |
| int viewMode = TApp::instance()->getCurrentFrame()->isEditingLevel() |
| ? LEVEL_VIEWMODE |
| : SCENE_VIEWMODE; |
| if (is3DView()) return TAffine(); |
| return m_viewAff[viewMode]; |
| } |
| |
| |
| |
| void SceneViewer::setViewMatrix(const TAffine &aff, int viewMode) { |
| m_viewAff[viewMode] = aff; |
| |
| if (m_previewMode != NO_PREVIEW) requestTimedRefresh(); |
| } |
| |
| |
| |
| bool SceneViewer::is3DView() const { |
| bool isCameraTest = CameraTestCheck::instance()->isEnabled(); |
| return (m_referenceMode == CAMERA3D_REFERENCE && !isCameraTest); |
| } |
| |
| |
| |
| void SceneViewer::invalidateAll() { |
| m_clipRect = InvalidateAllRect; |
| update(); |
| if (m_vRuler) m_vRuler->update(); |
| if (m_hRuler) m_hRuler->update(); |
| } |
| |
| |
| |
| |
| void SceneViewer::navigatorPan(const QPoint &delta) { |
| panQt(delta); |
| m_pos += delta; |
| } |
| |
| |
| |
| void SceneViewer::GLInvalidateAll() { |
| m_clipRect = InvalidateAllRect; |
| update(); |
| if (m_vRuler) m_vRuler->update(); |
| if (m_hRuler) m_hRuler->update(); |
| } |
| |
| |
| |
| void SceneViewer::GLInvalidateRect(const TRectD &rect) { |
| |
| |
| if (m_clipRect == InvalidateAllRect) |
| return; |
| else if (rect.isEmpty()) |
| m_clipRect = InvalidateAllRect; |
| else { |
| m_clipRect += rect; |
| if (!m_guidedDrawingBBox.isEmpty()) { |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| TPointD topLeft = tool->getMatrix() * m_guidedDrawingBBox.getP00(); |
| TPointD bottomRight = tool->getMatrix() * m_guidedDrawingBBox.getP11(); |
| m_clipRect += TRectD(topLeft, bottomRight); |
| } |
| } |
| update(); |
| if (m_vRuler) m_vRuler->update(); |
| if (m_hRuler) m_hRuler->update(); |
| m_guidedDrawingBBox.empty(); |
| } |
| |
| |
| |
| void SceneViewer::panQt(const QPointF &delta) { |
| if (delta == QPointF()) return; |
| if (is3DView()) |
| m_pan3D += TPointD(delta.x(), -delta.y()); |
| else { |
| |
| |
| setViewMatrix(TTranslation(delta.x(), -delta.y()) * m_viewAff[m_viewMode], |
| m_viewMode); |
| } |
| invalidateAll(); |
| emit refreshNavi(); |
| } |
| |
| |
| |
| void SceneViewer::zoomQt(bool forward, bool reset) { |
| TPointD delta(m_lastMousePos.x() - width() / 2, |
| -m_lastMousePos.y() + height() / 2); |
| |
| if (is3DView()) { |
| if (reset || ((m_zoomScale3D < 500 || !forward) && |
| (m_zoomScale3D > 0.01 || forward))) { |
| double oldZoomScale = m_zoomScale3D; |
| m_zoomScale3D = |
| reset ? 1 |
| : ImageUtils::getQuantizedZoomFactor(m_zoomScale3D, forward); |
| |
| m_pan3D = -(m_zoomScale3D / oldZoomScale) * -m_pan3D; |
| } |
| } else { |
| |
| double dpiFactor = getDpiFactor(); |
| |
| |
| double zoomScaleFittingWithScreen = 0.0f; |
| if (dpiFactor != 1.0) { |
| |
| ImageUtils::FullScreenWidget *fsWidget = |
| dynamic_cast<ImageUtils::FullScreenWidget *>(parentWidget()); |
| if (fsWidget && (fsWidget->windowState() & Qt::WindowFullScreen) != 0) |
| zoomScaleFittingWithScreen = getZoomScaleFittingWithScreen(); |
| } |
| |
| int i; |
| |
| for (i = 0; i < 2; i++) { |
| TAffine &viewAff = m_viewAff[i]; |
| if (m_isFlippedX) viewAff = viewAff * TScale(-1, 1); |
| if (m_isFlippedX) viewAff = viewAff * TScale(1, -1); |
| double scale2 = std::abs(viewAff.det()); |
| if (m_isFlippedX) viewAff = viewAff * TScale(-1, 1); |
| if (m_isFlippedX) viewAff = viewAff * TScale(1, -1); |
| if (reset || ((scale2 < 100000 || !forward) && |
| (scale2 > 0.001 * 0.05 || forward))) { |
| double oldZoomScale = sqrt(scale2) * dpiFactor; |
| double zoomScale = |
| reset ? 1 |
| : ImageUtils::getQuantizedZoomFactor(oldZoomScale, forward); |
| |
| |
| if ((oldZoomScale - zoomScaleFittingWithScreen) * |
| (zoomScale - zoomScaleFittingWithScreen) < |
| -0.001) |
| zoomScale = zoomScaleFittingWithScreen; |
| |
| if (Preferences::instance()->getViewerZoomCenter()) |
| setViewMatrix(TScale(zoomScale / oldZoomScale) * viewAff, i); |
| |
| else |
| setViewMatrix(TTranslation(delta) * TScale(zoomScale / oldZoomScale) * |
| TTranslation(-delta) * viewAff, |
| i); |
| } |
| } |
| } |
| |
| GLInvalidateAll(); |
| emit onZoomChanged(); |
| } |
| |
| |
| |
| |
| double SceneViewer::getDpiFactor() { |
| |
| double cameraDpi = TApp::instance() |
| ->getCurrentScene() |
| ->getScene() |
| ->getCurrentCamera() |
| ->getDpi() |
| .x; |
| if (Preferences::instance()->getPixelsOnly()) { |
| return Stage::inch / Stage::standardDpi; |
| } |
| |
| |
| else if (isPreviewEnabled()) { |
| return Stage::inch / cameraDpi; |
| } |
| |
| else if (TApp::instance()->getCurrentFrame()->isEditingLevel()) { |
| TXshSimpleLevel *sl; |
| sl = TApp::instance()->getCurrentLevel()->getSimpleLevel(); |
| if (!sl) return Stage::inch / cameraDpi; |
| if (sl->getType() == PLI_XSHLEVEL) return Stage::inch / cameraDpi; |
| if (sl->getImageDpi() != TPointD()) |
| return Stage::inch / sl->getImageDpi().x; |
| if (sl->getDpi() != TPointD()) return Stage::inch / sl->getDpi().x; |
| |
| return Stage::inch / cameraDpi; |
| } |
| |
| |
| |
| else if (Preferences::instance() |
| ->isActualPixelViewOnSceneEditingModeEnabled()) { |
| if (CleanupPreviewCheck::instance()->isEnabled() || |
| CameraTestCheck::instance()->isEnabled()) { |
| double cleanupCameraDpi = TApp::instance() |
| ->getCurrentScene() |
| ->getScene() |
| ->getProperties() |
| ->getCleanupParameters() |
| ->m_camera.getDpi() |
| .x; |
| return Stage::inch / cleanupCameraDpi; |
| } else { |
| TXshSimpleLevel *sl; |
| sl = TApp::instance()->getCurrentLevel()->getSimpleLevel(); |
| if (!sl) return Stage::inch / cameraDpi; |
| if (sl->getType() == PLI_XSHLEVEL) return Stage::inch / cameraDpi; |
| if (sl->getDpi() == TPointD()) return Stage::inch / cameraDpi; |
| |
| |
| return Stage::inch / sl->getDpi().x; |
| } |
| } |
| |
| else { |
| return Stage::inch / cameraDpi; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| double SceneViewer::getZoomScaleFittingWithScreen() { |
| TDimension imgSize; |
| |
| |
| |
| if (isPreviewEnabled()) |
| imgSize = TApp::instance() |
| ->getCurrentScene() |
| ->getScene() |
| ->getCurrentCamera() |
| ->getRes(); |
| else if (TApp::instance()->getCurrentFrame()->isEditingLevel()) { |
| TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel(); |
| if (!sl || sl->getType() == PLI_XSHLEVEL || sl->getImageDpi() == TPointD()) |
| return 0.0; |
| |
| imgSize = sl->getResolution(); |
| } else if (Preferences::instance() |
| ->isActualPixelViewOnSceneEditingModeEnabled() && |
| !CleanupPreviewCheck::instance()->isEnabled() && |
| !CameraTestCheck::instance()->isEnabled()) { |
| TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel(); |
| if (!sl || sl->getType() == PLI_XSHLEVEL || sl->getDpi() == TPointD()) |
| return 0.0; |
| imgSize = sl->getResolution(); |
| |
| } else |
| return 0.0; |
| |
| |
| int margin = 20; |
| |
| QRect rec = QApplication::desktop()->screenGeometry(); |
| |
| |
| int moni_x = rec.width() - (margin * 2); |
| int moni_y = rec.height() - (margin * 2); |
| return std::min((double)moni_x / (double)imgSize.lx, |
| (double)moni_y / (double)imgSize.ly); |
| } |
| |
| |
| |
| |
| void SceneViewer::zoomQt(const QPoint ¢er, double factor) { |
| if (factor == 1.0) return; |
| TPointD delta(center.x() - width() / 2, -center.y() + height() / 2); |
| double oldZoomScale = m_zoomScale3D; |
| |
| if (is3DView()) { |
| if ((m_zoomScale3D < 500 || factor < 1) && |
| (m_zoomScale3D > 0.01 || factor > 1)) { |
| m_zoomScale3D *= factor; |
| m_pan3D = -(m_zoomScale3D / oldZoomScale) * (delta - m_pan3D) + delta; |
| } |
| } else { |
| int i; |
| for (i = 0; i < 2; i++) { |
| TAffine &viewAff = m_viewAff[i]; |
| double scale2 = fabs(viewAff.det()); |
| if ((scale2 < 100000 || factor < 1) && |
| (scale2 > 0.001 * 0.05 || factor > 1)) { |
| if (i == m_viewMode) { |
| |
| |
| setViewMatrix(TTranslation(delta) * TScale(factor) * |
| TTranslation(-delta) * viewAff, |
| i); |
| } else { |
| |
| setViewMatrix(TScale(factor) * viewAff, i); |
| } |
| } |
| } |
| } |
| |
| GLInvalidateAll(); |
| emit onZoomChanged(); |
| } |
| |
| void SceneViewer::zoom(const TPointD ¢er, double factor) { |
| zoomQt(QPoint(center.x, height() - center.y), factor); |
| } |
| |
| |
| |
| void SceneViewer::flipX() { |
| double flipAngle0 = (m_rotationAngle[0] * -1) * 2; |
| double flipAngle1 = (m_rotationAngle[1] * -1) * 2; |
| m_rotationAngle[0] += flipAngle0; |
| m_rotationAngle[1] += flipAngle1; |
| if (m_isFlippedX != m_isFlippedY) { |
| flipAngle0 = -flipAngle0; |
| flipAngle1 = -flipAngle1; |
| } |
| m_viewAff[0] = m_viewAff[0] * TRotation(flipAngle0) * TScale(-1, 1); |
| m_viewAff[1] = m_viewAff[1] * TRotation(flipAngle1) * TScale(-1, 1); |
| m_viewAff[0].a13 *= -1; |
| m_viewAff[1].a13 *= -1; |
| m_isFlippedX = !m_isFlippedX; |
| invalidateAll(); |
| emit onZoomChanged(); |
| emit onFlipHChanged(m_isFlippedX); |
| } |
| |
| |
| |
| void SceneViewer::flipY() { |
| double flipAngle0 = (m_rotationAngle[0] * -1) * 2; |
| double flipAngle1 = (m_rotationAngle[1] * -1) * 2; |
| m_rotationAngle[0] += flipAngle0; |
| m_rotationAngle[1] += flipAngle1; |
| if (m_isFlippedX != m_isFlippedY) { |
| flipAngle0 = -flipAngle0; |
| flipAngle1 = -flipAngle1; |
| } |
| m_viewAff[0] = m_viewAff[0] * TRotation(flipAngle0) * TScale(1, -1); |
| m_viewAff[1] = m_viewAff[1] * TRotation(flipAngle1) * TScale(1, -1); |
| m_viewAff[0].a23 *= -1; |
| m_viewAff[1].a23 *= -1; |
| m_isFlippedY = !m_isFlippedY; |
| invalidateAll(); |
| emit onZoomChanged(); |
| emit onFlipVChanged(m_isFlippedY); |
| } |
| |
| |
| |
| void SceneViewer::zoomIn() { |
| m_lastMousePos = rect().center(); |
| zoomQt(true, false); |
| } |
| |
| |
| |
| void SceneViewer::zoomOut() { |
| m_lastMousePos = rect().center(); |
| zoomQt(false, false); |
| } |
| |
| |
| |
| void SceneViewer::rotate(const TPointD ¢er, double angle) { |
| if (angle == 0) return; |
| if (m_isFlippedX != m_isFlippedY) angle = -angle; |
| m_rotationAngle[m_viewMode] += angle; |
| TPointD realCenter = m_viewAff[m_viewMode] * center; |
| setViewMatrix(TRotation(realCenter, angle) * m_viewAff[m_viewMode], |
| m_viewMode); |
| invalidateAll(); |
| } |
| |
| |
| |
| void SceneViewer::rotate3D(double dPhi, double dTheta) { |
| if (dPhi == 0 && dTheta == 0) return; |
| m_phi3D = (float)tcrop(m_phi3D + dPhi, -90.0, 90.0); |
| m_theta3D = (float)tcrop(m_theta3D + dTheta, 0.0, 90.0); |
| invalidateAll(); |
| } |
| |
| |
| |
| void SceneViewer::regeneratePreview() { |
| Previewer::instance(m_previewMode == SUBCAMERA_PREVIEW)->clear(); |
| update(); |
| } |
| |
| |
| |
| void SceneViewer::regeneratePreviewFrame() { |
| Previewer::instance(m_previewMode == SUBCAMERA_PREVIEW) |
| ->clear(TApp::instance()->getCurrentFrame()->getFrame()); |
| |
| update(); |
| } |
| |
| |
| |
| void SceneViewer::swapCompared() { |
| m_compareSettings.m_swapCompared = !m_compareSettings.m_swapCompared; |
| update(); |
| } |
| |
| |
| |
| void SceneViewer::fitToCamera() { |
| |
| bool tempIsFlippedX = m_isFlippedX; |
| bool tempIsFlippedY = m_isFlippedY; |
| resetSceneViewer(); |
| |
| m_isFlippedX = tempIsFlippedX; |
| m_isFlippedY = tempIsFlippedY; |
| |
| TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet(); |
| int frame = TApp::instance()->getCurrentFrame()->getFrame(); |
| TStageObjectId cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); |
| TStageObject *camera = xsh->getStageObject(cameraId); |
| TAffine cameraPlacement = camera->getPlacement(frame); |
| double cameraZ = camera->getZ(frame); |
| TAffine cameraAff = |
| getViewMatrix() * cameraPlacement * TScale((1000 + cameraZ) / 1000); |
| |
| QRect viewRect = rect(); |
| TRectD cameraRect = ViewerDraw::getCameraRect(); |
| TPointD P00 = cameraAff * cameraRect.getP00(); |
| TPointD P10 = cameraAff * cameraRect.getP10(); |
| TPointD P01 = cameraAff * cameraRect.getP01(); |
| TPointD P11 = cameraAff * cameraRect.getP11(); |
| TPointD p0 = TPointD(std::min({P00.x, P01.x, P10.x, P11.x}), |
| std::min({P00.y, P01.y, P10.y, P11.y})); |
| TPointD p1 = TPointD(std::max({P00.x, P01.x, P10.x, P11.x}), |
| std::max({P00.y, P01.y, P10.y, P11.y})); |
| cameraRect = TRectD(p0.x, p0.y, p1.x, p1.y); |
| |
| |
| if (!is3DView()) { |
| TPointD cameraCenter = (cameraRect.getP00() + cameraRect.getP11()) * 0.5; |
| panQt(QPoint(-cameraCenter.x, cameraCenter.y)); |
| } |
| |
| double xratio = (double)viewRect.width() / cameraRect.getLx(); |
| double yratio = (double)viewRect.height() / cameraRect.getLy(); |
| double ratio = std::min(xratio, yratio); |
| if (ratio == 0.0) return; |
| if (tempIsFlippedX) |
| setViewMatrix(TScale(-1, 1) * m_viewAff[m_viewMode], m_viewMode); |
| if (tempIsFlippedY) |
| setViewMatrix(TScale(1, -1) * m_viewAff[m_viewMode], m_viewMode); |
| |
| QPoint c = viewRect.center(); |
| zoom(TPointD(c.x(), c.y()), ratio); |
| emit onFlipHChanged(m_isFlippedX); |
| emit onFlipVChanged(m_isFlippedY); |
| } |
| |
| |
| |
| void SceneViewer::fitToCameraOutline() { |
| TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet(); |
| int frame = TApp::instance()->getCurrentFrame()->getFrame(); |
| TStageObjectId cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); |
| TStageObject *camera = xsh->getStageObject(cameraId); |
| TAffine cameraPlacement = camera->getPlacement(frame); |
| double cameraZ = camera->getZ(frame); |
| TAffine cameraAff = |
| getViewMatrix() * cameraPlacement * TScale((1000 + cameraZ) / 1000); |
| |
| QRect viewRect = rect(); |
| TRectD cameraRect = ViewerDraw::getCameraRect(); |
| TPointD P00 = cameraAff * cameraRect.getP00(); |
| TPointD P10 = cameraAff * cameraRect.getP10(); |
| TPointD P01 = cameraAff * cameraRect.getP01(); |
| TPointD P11 = cameraAff * cameraRect.getP11(); |
| TPointD p0 = TPointD(std::min({P00.x, P01.x, P10.x, P11.x}), |
| std::min({P00.y, P01.y, P10.y, P11.y})); |
| TPointD p1 = TPointD(std::max({P00.x, P01.x, P10.x, P11.x}), |
| std::max({P00.y, P01.y, P10.y, P11.y})); |
| cameraRect = TRectD(p0.x, p0.y, p1.x, p1.y); |
| |
| |
| if (!is3DView()) { |
| TPointD cameraCenter = (cameraRect.getP00() + cameraRect.getP11()) * 0.5; |
| panQt(QPoint(-cameraCenter.x, cameraCenter.y)); |
| } |
| |
| double xratio = (double)viewRect.width() / cameraRect.getLx(); |
| double yratio = (double)viewRect.height() / cameraRect.getLy(); |
| double ratio = std::min(xratio, yratio); |
| if (ratio == 0.0) return; |
| |
| |
| QPoint c = viewRect.center(); |
| zoom(TPointD(c.x(), c.y()), ratio); |
| zoom(TPointD(c.x(), c.y()), 0.95); |
| } |
| |
| |
| |
| void SceneViewer::resetSceneViewer() { |
| m_visualSettings.m_sceneProperties = |
| TApp::instance()->getCurrentScene()->getScene()->getProperties(); |
| |
| for (int i = 0; i < m_viewAff.size(); ++i) { |
| setViewMatrix(getNormalZoomScale(), i); |
| m_rotationAngle[i] = 0.0; |
| } |
| |
| m_pos = QPoint(0, 0); |
| m_pan3D = TPointD(0, 0); |
| m_zoomScale3D = 0.1; |
| m_theta3D = 20; |
| m_phi3D = 30; |
| m_isFlippedX = false; |
| m_isFlippedY = false; |
| fitToCameraOutline(); |
| emit onZoomChanged(); |
| emit onFlipHChanged(m_isFlippedX); |
| emit onFlipVChanged(m_isFlippedY); |
| invalidateAll(); |
| } |
| |
| |
| |
| void SceneViewer::resetZoom() { |
| TPointD realCenter(m_viewAff[m_viewMode].a13, m_viewAff[m_viewMode].a23); |
| TAffine aff = |
| getNormalZoomScale() * TRotation(realCenter, m_rotationAngle[m_viewMode]); |
| aff.a13 = realCenter.x; |
| aff.a23 = realCenter.y; |
| if (m_isFlippedX) aff = aff * TScale(-1, 1); |
| if (m_isFlippedY) aff = aff * TScale(1, -1); |
| setViewMatrix(aff, m_viewMode); |
| invalidateAll(); |
| emit onZoomChanged(); |
| } |
| |
| |
| |
| void SceneViewer::resetRotation() { |
| double reverseRotatation = m_rotationAngle[m_viewMode] * -1; |
| if (m_isFlippedX) reverseRotatation *= -1; |
| if (m_isFlippedY) reverseRotatation *= -1; |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| TPointD center = m_viewAff[m_viewMode].inv() * TPointD(0, 0); |
| if (tool->getName() == "T_Rotate" && |
| tool->getProperties(0) |
| ->getProperty("Rotate On Camera Center") |
| ->getValueAsString() == "1") |
| center = TPointD(0, 0); |
| rotate(center, reverseRotatation); |
| } |
| |
| |
| |
| void SceneViewer::resetPosition() { |
| m_viewAff[m_viewMode].a13 = 0.0; |
| m_viewAff[m_viewMode].a23 = 0.0; |
| invalidateAll(); |
| } |
| |
| |
| |
| void SceneViewer::setActualPixelSize() { |
| TApp *app = TApp::instance(); |
| TXshLevel *l = app->getCurrentLevel()->getLevel(); |
| TXshSimpleLevel *sl = l ? l->getSimpleLevel() : 0; |
| if (!sl) return; |
| |
| TFrameId fid(app->getCurrentFrame()->getFid()); |
| |
| TPointD dpi; |
| if (CleanupPreviewCheck::instance()->isEnabled()) { |
| |
| |
| |
| CleanupParameters *cleanupParams = app->getCurrentScene() |
| ->getScene() |
| ->getProperties() |
| ->getCleanupParameters(); |
| |
| TDimension dim(0, 0); |
| cleanupParams->getOutputImageInfo(dim, dpi.x, dpi.y); |
| } else |
| dpi = sl->getDpi(fid); |
| |
| const double inch = Stage::inch; |
| TAffine tempAff = getNormalZoomScale(); |
| if (m_isFlippedX) tempAff = tempAff * TScale(-1, 1); |
| if (m_isFlippedY) tempAff = tempAff * TScale(1, -1); |
| TPointD tempScale = dpi; |
| if (m_isFlippedX) tempScale.x = -tempScale.x; |
| if (m_isFlippedY) tempScale.y = -tempScale.y; |
| for (int i = 0; i < m_viewAff.size(); ++i) |
| setViewMatrix(dpi == TPointD(0, 0) |
| ? tempAff |
| : TScale(tempScale.x / inch, tempScale.y / inch), |
| i); |
| |
| m_pos = QPoint(0, 0); |
| m_pan3D = TPointD(0, 0); |
| m_zoomScale3D = 0.1; |
| m_theta3D = 20; |
| m_phi3D = 30; |
| emit onZoomChanged(); |
| |
| invalidateAll(); |
| } |
| |
| |
| |
| void SceneViewer::onLevelChanged() { |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| if (tool) { |
| TXshLevel *level = TApp::instance()->getCurrentLevel()->getLevel(); |
| if (level && level->getSimpleLevel()) |
| m_dpiScale = |
| getCurrentDpiScale(level->getSimpleLevel(), tool->getCurrentFid()); |
| else |
| m_dpiScale = TPointD(1, 1); |
| } |
| } |
| |
| |
| |
| |
| void SceneViewer::onLevelSwitched() { |
| invalidateToolStatus(); |
| TApp *app = TApp::instance(); |
| TTool *tool = app->getCurrentTool()->getTool(); |
| TXshLevel *level = app->getCurrentLevel()->getLevel(); |
| if (level && level->getSimpleLevel()) |
| m_dpiScale = |
| getCurrentDpiScale(level->getSimpleLevel(), tool->getCurrentFid()); |
| else |
| m_dpiScale = TPointD(1, 1); |
| } |
| |
| |
| |
| void SceneViewer::onXsheetChanged() { |
| m_forceGlFlush = true; |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| if (tool && tool->isEnabled()) tool->updateMatrix(); |
| onLevelChanged(); |
| GLInvalidateAll(); |
| } |
| |
| |
| |
| void SceneViewer::onObjectSwitched() { |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| if (tool && tool->isEnabled()) tool->updateMatrix(); |
| onLevelChanged(); |
| GLInvalidateAll(); |
| } |
| |
| |
| |
| void SceneViewer::onSceneChanged() { |
| onLevelChanged(); |
| GLInvalidateAll(); |
| } |
| |
| |
| |
| void SceneViewer::onFrameSwitched() { |
| invalidateToolStatus(); |
| |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| if (tool && tool->isEnabled()) { |
| tool->setViewer(this); |
| tool->updateMatrix(); |
| tool->onEnter(); |
| } |
| |
| GLInvalidateAll(); |
| } |
| |
| |
| |
| |
| void SceneViewer::onToolChanged() { |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| if (tool) setToolCursor(this, tool->getCursorId()); |
| GLInvalidateAll(); |
| } |
| |
| |
| |
| int SceneViewer::pick(const TPointD &point) { |
| |
| |
| |
| |
| m_isPicking = true; |
| makeCurrent(); |
| assert(glGetError() == GL_NO_ERROR); |
| GLint viewport[4]; |
| glGetIntegerv(GL_VIEWPORT, viewport); |
| std::array<GLuint, 512> selectBuffer; |
| glSelectBuffer(selectBuffer.size(), selectBuffer.data()); |
| glRenderMode(GL_SELECT); |
| |
| |
| glMatrixMode(GL_PROJECTION); |
| GLdouble mat[16]; |
| glGetDoublev(GL_PROJECTION_MATRIX, mat); |
| glPushMatrix(); |
| glLoadIdentity(); |
| gluPickMatrix(point.x, point.y, 5, 5, viewport); |
| glMultMatrixd(mat); |
| assert(glGetError() == GL_NO_ERROR); |
| |
| |
| glMatrixMode(GL_MODELVIEW); |
| glPushMatrix(); |
| glInitNames(); |
| assert(glGetError() == GL_NO_ERROR); |
| |
| |
| |
| |
| |
| |
| int previewMode = m_previewMode; |
| m_previewMode = NO_PREVIEW; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| TRectD oldClipRect(m_clipRect); |
| m_clipRect = TRectD(point.x, point.y, point.x + 1, point.y + 1); |
| |
| paintGL(); |
| |
| m_clipRect = oldClipRect; |
| |
| m_previewMode = previewMode; |
| |
| assert(glGetError() == GL_NO_ERROR); |
| glPopMatrix(); |
| |
| |
| glMatrixMode(GL_PROJECTION); |
| glPopMatrix(); |
| glMatrixMode(GL_MODELVIEW); |
| |
| assert(glGetError() == GL_NO_ERROR); |
| |
| |
| int ret = -1; |
| int hitCount = glRenderMode(GL_RENDER); |
| GLuint *p = selectBuffer.data(); |
| for (int i = 0; i < hitCount; ++i) { |
| GLuint nameCount = *p++; |
| GLuint zmin = *p++; |
| GLuint zmax = *p++; |
| if (nameCount > 0) { |
| GLuint name = *p; |
| ret = name; |
| } |
| p += nameCount; |
| } |
| assert(glGetError() == GL_NO_ERROR); |
| m_isPicking = false; |
| return ret; |
| } |
| |
| |
| |
| int SceneViewer::posToColumnIndex(const TPointD &p, double distance, |
| bool includeInvisible) const { |
| std::vector<int> ret; |
| posToColumnIndexes(p, ret, distance, includeInvisible); |
| return ret.empty() ? -1 : ret.back(); |
| } |
| |
| |
| |
| void SceneViewer::posToColumnIndexes(const TPointD &p, |
| std::vector<int> &indexes, double distance, |
| bool includeInvisible) const { |
| int oldRasterizePli = TXshSimpleLevel::m_rasterizePli; |
| TApp *app = TApp::instance(); |
| ToonzScene *scene = app->getCurrentScene()->getScene(); |
| TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); |
| int frame = app->getCurrentFrame()->getFrame(); |
| int currentColumnIndex = app->getCurrentColumn()->getColumnIndex(); |
| OnionSkinMask osm = app->getCurrentOnionSkin()->getOnionSkinMask(); |
| |
| TPointD pos = TPointD(p.x - width() / 2, p.y - height() / 2); |
| Stage::Picker picker(getViewMatrix(), pos, m_visualSettings, |
| getDevPixRatio()); |
| picker.setMinimumDistance(distance); |
| |
| TXshSimpleLevel::m_rasterizePli = 0; |
| |
| Stage::VisitArgs args; |
| args.m_scene = scene; |
| args.m_xsh = xsh; |
| args.m_row = frame; |
| args.m_col = currentColumnIndex; |
| args.m_osm = &osm; |
| args.m_onlyVisible = includeInvisible; |
| |
| Stage::visit(picker, args); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| TXshSimpleLevel::m_rasterizePli = oldRasterizePli; |
| picker.getColumnIndexes(indexes); |
| } |
| |
| |
| |
| int SceneViewer::posToRow(const TPointD &p, double distance, |
| bool includeInvisible, bool currentColumnOnly) const { |
| int oldRasterizePli = TXshSimpleLevel::m_rasterizePli; |
| TApp *app = TApp::instance(); |
| OnionSkinMask osm = app->getCurrentOnionSkin()->getOnionSkinMask(); |
| |
| TPointD pos = TPointD(p.x - width() / 2, p.y - height() / 2); |
| Stage::Picker picker(getViewMatrix(), pos, m_visualSettings, |
| getDevPixRatio()); |
| picker.setMinimumDistance(distance); |
| |
| if (app->getCurrentFrame()->isEditingLevel()) { |
| Stage::visit(picker, app->getCurrentLevel()->getLevel(), |
| app->getCurrentFrame()->getFid(), osm, |
| app->getCurrentFrame()->isPlaying(), false); |
| } else { |
| ToonzScene *scene = app->getCurrentScene()->getScene(); |
| TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); |
| int frame = app->getCurrentFrame()->getFrame(); |
| int currentColumnIndex = app->getCurrentColumn()->getColumnIndex(); |
| |
| TXshSimpleLevel::m_rasterizePli = 0; |
| |
| Stage::VisitArgs args; |
| args.m_scene = scene; |
| args.m_xsh = xsh; |
| args.m_row = frame; |
| args.m_col = currentColumnIndex; |
| args.m_osm = &osm; |
| args.m_onlyVisible = includeInvisible; |
| |
| if (currentColumnOnly) picker.setCurrentColumnIndex(currentColumnIndex); |
| |
| Stage::visit(picker, args); |
| } |
| TXshSimpleLevel::m_rasterizePli = oldRasterizePli; |
| return picker.getRow(); |
| } |
| |
| |
| |
| void drawSpline(const TAffine &viewMatrix, const TRect &clipRect, bool camera3d, |
| double pixelsize) { |
| TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet(); |
| |
| TStageObjectId objId = TApp::instance()->getCurrentObject()->getObjectId(); |
| |
| TStageObject *pegbar = |
| objId != TStageObjectId::NoneId ? xsh->getStageObject(objId) : 0; |
| const TStroke *stroke = 0; |
| if (pegbar && pegbar->getSpline()) stroke = pegbar->getSpline()->getStroke(); |
| if (!stroke) return; |
| |
| int frame = TApp::instance()->getCurrentFrame()->getFrame(); |
| |
| TAffine aff; |
| double objZ = 0, objNoScaleZ = 0; |
| if (objId != TStageObjectId::NoneId) { |
| aff = xsh->getParentPlacement(objId, frame); |
| objZ = xsh->getZ(objId, frame); |
| objNoScaleZ = xsh->getStageObject(objId)->getGlobalNoScaleZ(); |
| } |
| |
| glPushMatrix(); |
| if (camera3d) { |
| tglMultMatrix(aff); |
| aff = TAffine(); |
| glTranslated(0, 0, objZ); |
| } else { |
| TStageObjectId cameraId = xsh->getStageObjectTree()->getCurrentCameraId(); |
| double camZ = xsh->getZ(cameraId, frame); |
| TAffine camAff = xsh->getPlacement(cameraId, frame); |
| TAffine tmp; |
| TStageObject::perspective(tmp, camAff, camZ, aff, objZ, objNoScaleZ); |
| aff = viewMatrix * tmp; |
| } |
| |
| if (TApp::instance()->getCurrentObject()->isSpline()) { |
| glColor3d(1.0, 0.5, 0); |
| glLineStipple(1, 0x18FF); |
| } else { |
| glLineStipple(1, 0xCCCC); |
| glColor3d(1, 0, 1); |
| } |
| |
| glEnable(GL_LINE_STIPPLE); |
| tglMultMatrix(aff); |
| |
| double pixelSize = std::max(0.1, pixelsize); |
| double strokeLength = stroke->getLength(); |
| int n = (int)(5 + (strokeLength / pixelSize) * 0.1); |
| |
| glBegin(GL_LINE_STRIP); |
| for (int i = 0; i < n; i++) |
| tglVertex(stroke->getPoint((double)i / (double)(n - 1))); |
| glEnd(); |
| glDisable(GL_LINE_STIPPLE); |
| int cpCount = stroke->getControlPointCount(); |
| for (int i = 0; i * 4 < cpCount; i++) { |
| double t = stroke->getParameterAtControlPoint(i * 4); |
| TPointD pos = stroke->getPoint(t); |
| tglDrawText(pos, QString::number(i).toStdString().c_str()); |
| } |
| |
| if (pegbar) { |
| TAffine parentAff = xsh->getParentPlacement(objId, frame); |
| TAffine aff = xsh->getPlacement(objId, frame); |
| TPointD center = Stage::inch * xsh->getCenter(objId, frame); |
| glPushMatrix(); |
| tglMultMatrix(parentAff.inv() * TTranslation(aff * center)); |
| center = TPointD(); |
| |
| |
| |
| tglDrawDisk(center, sqrt(tglGetPixelSize2()) * 5); |
| |
| glPopMatrix(); |
| } |
| |
| glPopMatrix(); |
| } |
| |
| |
| |
| void SceneViewer::resetInputMethod() { |
| QGuiApplication::inputMethod()->reset(); |
| } |
| |
| |
| |
| void SceneViewer::set3DLeftSideView() { |
| m_phi3D = -90; |
| m_theta3D = 0; |
| invalidateAll(); |
| } |
| |
| |
| |
| void SceneViewer::set3DRightSideView() { |
| m_phi3D = 90; |
| m_theta3D = 0; |
| invalidateAll(); |
| } |
| |
| |
| |
| void SceneViewer::set3DTopView() { |
| m_phi3D = 0; |
| m_theta3D = 90; |
| invalidateAll(); |
| } |
| |
| |
| |
| bool SceneViewer::canSwapCompared() const { |
| return m_visualSettings.m_doCompare && m_previewMode != NO_PREVIEW; |
| } |
| |
| |
| |
| TAffine SceneViewer::getNormalZoomScale() { |
| return TScale(getDpiFactor()).inv(); |
| } |
| |
| |
| |
| void SceneViewer::invalidateToolStatus() { |
| m_toolHasAssistants = false; |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| if (tool) { |
| m_toolDisableReason = tool->updateEnabled(); |
| if (tool->isEnabled()) { |
| setToolCursor(this, tool->getCursorId()); |
| tool->setViewer(this); |
| tool->updateMatrix(); |
| } else |
| setCursor(Qt::ForbiddenCursor); |
| } else |
| setCursor(Qt::ForbiddenCursor); |
| } |
| |
| |
| |
| |
| |
| |
| |
| TRectD SceneViewer::getGeometry() const { |
| int devPixRatio = getDevPixRatio(); |
| TTool *tool = TApp::instance()->getCurrentTool()->getTool(); |
| TPointD topLeft = |
| tool->getMatrix().inv() * winToWorld(geometry().topLeft() * devPixRatio); |
| TPointD bottomRight = tool->getMatrix().inv() * |
| winToWorld(geometry().bottomRight() * devPixRatio); |
| |
| TObjectHandle *objHandle = TApp::instance()->getCurrentObject(); |
| if (tool->getToolType() & TTool::LevelTool && !objHandle->isSpline()) { |
| topLeft.x /= m_dpiScale.x; |
| topLeft.y /= m_dpiScale.y; |
| bottomRight.x /= m_dpiScale.x; |
| bottomRight.y /= m_dpiScale.y; |
| } |
| |
| return TRectD(topLeft, bottomRight); |
| } |
| |
| |
| |
| TRectD SceneViewer::getCameraRect() const { |
| TRectD cameraRect = TApp::instance() |
| ->getCurrentScene() |
| ->getScene() |
| ->getCurrentCamera() |
| ->getStageRect(); |
| |
| |
| |
| return m_drawCameraAff * cameraRect; |
| } |
| |
| |
| |
| |
| void SceneViewer::doDeleteSubCamera() { |
| PreviewSubCameraManager::instance()->deleteSubCamera(this); |
| } |
| |
| |
| |
| void SceneViewer::bindFBO() { |
| if (m_fbo) m_fbo->bind(); |
| } |
| |
| |
| |
| void SceneViewer::releaseFBO() { |
| if (m_fbo) m_fbo->release(); |
| } |
| |
| |
| |
| void SceneViewer::onContextAboutToBeDestroyed() { |
| if (!m_lutCalibrator) return; |
| makeCurrent(); |
| m_lutCalibrator->cleanup(); |
| doneCurrent(); |
| disconnect(context(), SIGNAL(aboutToBeDestroyed()), this, |
| SLOT(onContextAboutToBeDestroyed())); |
| } |
| |
| |
| |
| |
| void SceneViewer::registerContext() { |
| |
| |
| bool hasOldContext; |
| #ifdef _WIN32 |
| hasOldContext = |
| (m_currentContext.first != nullptr && m_currentContext.second != nullptr); |
| #else |
| hasOldContext = m_currentContext != nullptr; |
| #endif |
| if (hasOldContext) { |
| int ret = l_contexts.erase(m_currentContext); |
| if (ret) |
| TGLDisplayListsManager::instance()->releaseContext(m_currentContext); |
| } |
| |
| |
| int displayListId; |
| if (TApp::instance()->getMainWindow() && |
| TApp::instance()->getMainWindow()->isAncestorOf(this) && |
| QThread::currentThread() == qGuiApp->thread()) { |
| |
| if (l_mainDisplayListsSpaceId == -1) |
| l_mainDisplayListsSpaceId = |
| TGLDisplayListsManager::instance()->storeProxy(new DummyProxy); |
| |
| displayListId = l_mainDisplayListsSpaceId; |
| } |
| |
| |
| |
| else |
| displayListId = |
| TGLDisplayListsManager::instance()->storeProxy(new DummyProxy); |
| TGlContext tglContext(tglGetCurrentContext()); |
| TGLDisplayListsManager::instance()->attachContext(displayListId, tglContext); |
| l_contexts.insert(tglContext); |
| } |