| #pragma once |
| |
| #ifndef PLASTICTOOL_H |
| #define PLASTICTOOL_H |
| |
| |
| #include "tproperty.h" |
| #include "tmeshimage.h" |
| |
| |
| #include "tparamchange.h" |
| #include "tdoubleparamrelayproperty.h" |
| |
| |
| #include "ext/plasticskeleton.h" |
| #include "ext/plasticskeletondeformation.h" |
| #include "ext/plasticvisualsettings.h" |
| |
| |
| #include "toonzqt/plasticvertexselection.h" |
| |
| |
| #include "tools/tool.h" |
| #include "tools/cursors.h" |
| #include "tools/tooloptions.h" |
| |
| |
| #include <memory> |
| |
| |
| #include "tcg/tcg_base.h" |
| #include "tcg/tcg_controlled_access.h" |
| |
| |
| #include <QObject> |
| |
| |
| |
| |
| |
| |
| |
| #define HIGHLIGHT_DISTANCE 8 // Pixels distance to highlight |
| #define HANDLE_SIZE 4 // Size of vertex handles |
| #define HIGHLIGHTED_HANDLE_SIZE HIGHLIGHT_DISTANCE // Size of handle highlights |
| #define SELECTED_HANDLE_SIZE \ |
| HIGHLIGHTED_HANDLE_SIZE |
| |
| |
| |
| #define MESH_HIGHLIGHT_DISTANCE 8 |
| #define MESH_HIGHLIGHTED_HANDLE_SIZE 4 |
| #define MESH_SELECTED_HANDLE_SIZE 2 |
| |
| |
| |
| |
| |
| class PlasticTool final : public QObject, |
| public TTool, |
| public TParamObserver, |
| public TSelection::View { |
| Q_OBJECT |
| |
| friend class PlasticToolOptionsBox; |
| |
| public: |
| class TemporaryActivation { |
| bool m_activate; |
| |
| public: |
| TemporaryActivation(int row, int col); |
| ~TemporaryActivation(); |
| }; |
| |
| struct MeshIndex final : public tcg::safe_bool<MeshIndex> { |
| int m_meshIdx, |
| m_idx; |
| |
| explicit MeshIndex(int meshIdx = -1, int idx = -1) |
| : m_meshIdx(meshIdx), m_idx(idx) {} |
| |
| bool operator_bool() const { return (m_meshIdx >= 0) && (m_idx >= 0); } |
| |
| bool operator<(const MeshIndex &other) const { |
| return (m_meshIdx == other.m_meshIdx) ? (m_idx < other.m_idx) |
| : (m_meshIdx < other.m_meshIdx); |
| } |
| }; |
| |
| typedef MultipleSelection<MeshIndex> MeshSelection; |
| |
| private: |
| PlasticSkeletonDeformationP m_sd; |
| int m_skelId; |
| tcg::invalidable<PlasticSkeleton> |
| m_deformedSkeleton; |
| |
| |
| TMeshImageP m_mi; |
| |
| |
| |
| TPropertyGroup |
| *m_propGroup; |
| |
| TEnumProperty m_mode; |
| TStringProperty m_vertexName; |
| |
| TBoolProperty m_interpolate; |
| TBoolProperty m_snapToMesh; |
| |
| TDoubleProperty m_thickness; |
| TEnumProperty |
| m_rigidValue; |
| |
| |
| TBoolProperty |
| m_globalKey; |
| TBoolProperty |
| m_keepDistance; |
| |
| TStringProperty m_minAngle, |
| m_maxAngle; |
| |
| TPropertyGroup m_relayGroup; |
| |
| TDoubleParamRelayProperty |
| m_distanceRelay; |
| TDoubleParamRelayProperty m_angleRelay; |
| TDoubleParamRelayProperty m_soRelay; |
| |
| TDoubleParamRelayProperty |
| m_skelIdRelay; |
| |
| |
| |
| TPointD m_pos; |
| TPointD m_pressedPos; |
| bool m_dragged; |
| |
| std::vector<TPointD> |
| m_pressedVxsPos; |
| SkDKey m_pressedSkDF; |
| |
| |
| |
| int m_svHigh, |
| m_seHigh; |
| PlasticVertexSelection m_svSel; |
| |
| MeshIndex m_mvHigh, |
| m_meHigh; |
| MeshSelection m_mvSel, |
| m_meSel; |
| |
| |
| |
| PlasticVisualSettings m_pvs; |
| |
| |
| |
| std::unique_ptr<tcg::polymorphic> m_rigidityPainter; |
| |
| |
| bool m_showSkeletonOS; |
| |
| |
| |
| bool m_recompileOnMouseRelease; |
| |
| |
| public: |
| enum Modes { |
| MESH_IDX = 0, |
| RIGIDITY_IDX, |
| BUILD_IDX, |
| ANIMATE_IDX, |
| MODES_COUNT |
| }; |
| |
| public: |
| PlasticTool(); |
| ~PlasticTool(); |
| |
| ToolType getToolType() const override; |
| int getCursorId() const override { return ToolCursor::SplineEditorCursor; } |
| |
| ToolOptionsBox *createOptionsBox() override; |
| |
| TPropertyGroup *getProperties(int idx) override { return &m_propGroup[idx]; } |
| |
| void updateTranslation() override; |
| |
| void onSetViewer() override; |
| |
| void onActivate() override; |
| void onDeactivate() override; |
| |
| void onEnter() override; |
| void onLeave() override; |
| |
| void addContextMenuItems(QMenu *menu) override; |
| |
| void reset() override; |
| |
| bool onPropertyChanged(std::string propertyName) override; |
| |
| public: |
| |
| void mouseMove(const TPointD &pos, const TMouseEvent &me) override; |
| void leftButtonDown(const TPointD &pos, const TMouseEvent &me) override; |
| void leftButtonDrag(const TPointD &pos, const TMouseEvent &me) override; |
| void leftButtonUp(const TPointD &pos, const TMouseEvent &me) override; |
| |
| void draw() override; |
| |
| public: |
| |
| |
| void setSkeletonSelection(const PlasticVertexSelection &vSel); |
| void toggleSkeletonSelection(const PlasticVertexSelection &vSel); |
| void clearSkeletonSelections(); |
| |
| const PlasticVertexSelection &skeletonVertexSelection() const { |
| return m_svSel; |
| } |
| PlasticVertexSelection branchSelection(int vIdx) const; |
| |
| void moveVertex_build(const std::vector<TPointD> &originalVxsPos, |
| const TPointD &posShift); |
| void addVertex(const PlasticSkeletonVertex &vx); |
| void insertVertex(const PlasticSkeletonVertex &vx, int e); |
| void insertVertex(const PlasticSkeletonVertex &vx, int parent, |
| const std::vector<int> &children); |
| void removeVertex(); |
| void setVertexName(QString &name); |
| |
| int addSkeleton(const PlasticSkeletonP &skeleton); |
| void addSkeleton(int skelId, const PlasticSkeletonP &skeleton); |
| void removeSkeleton(int skelId); |
| |
| PlasticSkeletonP skeleton() const; |
| void touchSkeleton(); |
| |
| PlasticSkeletonDeformationP deformation() const { return m_sd; } |
| void touchDeformation(); |
| |
| void storeDeformation(); |
| |
| void storeSkeletonId(); |
| |
| |
| void onChange(); |
| |
| public: |
| |
| |
| const MeshSelection &meshVertexesSelection() const { return m_mvSel; } |
| const MeshSelection &meshEdgesSelection() const { return m_meSel; } |
| |
| void setMeshVertexesSelection(const MeshSelection &vSel); |
| void toggleMeshVertexesSelection(const MeshSelection &vSel); |
| |
| void setMeshEdgesSelection(const MeshSelection &eSel); |
| void toggleMeshEdgesSelection(const MeshSelection &eSel); |
| |
| void clearMeshSelections(); |
| |
| void storeMeshImage(); |
| |
| void moveVertex_mesh(const std::vector<TPointD> &originalVxsPos, |
| const TPointD &posShift); |
| |
| public: |
| |
| int addSkeleton_undo(const PlasticSkeletonP &skeleton); |
| void addSkeleton_undo(int skelId, const PlasticSkeletonP &skeleton); |
| |
| void removeSkeleton_undo(int skelId); |
| void removeSkeleton_withKeyframes_undo(int skelId); |
| |
| void editSkelId_undo(int skelId); |
| |
| public slots: |
| |
| void swapEdge_mesh_undo(); |
| void collapseEdge_mesh_undo(); |
| void splitEdge_mesh_undo(); |
| void cutEdges_mesh_undo(); |
| |
| void deleteSelectedVertex_undo(); |
| |
| void setKey_undo(); |
| void setGlobalKey_undo(); |
| void setRestKey_undo(); |
| void setGlobalRestKey_undo(); |
| |
| void copySkeleton(); |
| void pasteSkeleton_undo(); |
| void copyDeformation(); |
| void pasteDeformation_undo(); |
| |
| signals: |
| |
| void skelIdsListChanged(); |
| void skelIdChanged(); |
| |
| protected: |
| void mouseMove_mesh(const TPointD &pos, const TMouseEvent &me); |
| void leftButtonDown_mesh(const TPointD &pos, const TMouseEvent &me); |
| void leftButtonDrag_mesh(const TPointD &pos, const TMouseEvent &me); |
| void leftButtonUp_mesh(const TPointD &pos, const TMouseEvent &me); |
| void addContextMenuActions_mesh(QMenu *menu); |
| |
| void mouseMove_build(const TPointD &pos, const TMouseEvent &me); |
| void leftButtonDown_build(const TPointD &pos, const TMouseEvent &me); |
| void leftButtonDrag_build(const TPointD &pos, const TMouseEvent &me); |
| void leftButtonUp_build(const TPointD &pos, const TMouseEvent &me); |
| void addContextMenuActions_build(QMenu *menu); |
| |
| void mouseMove_rigidity(const TPointD &pos, const TMouseEvent &me); |
| void leftButtonDown_rigidity(const TPointD &pos, const TMouseEvent &me); |
| void leftButtonDrag_rigidity(const TPointD &pos, const TMouseEvent &me); |
| void leftButtonUp_rigidity(const TPointD &pos, const TMouseEvent &me); |
| void addContextMenuActions_rigidity(QMenu *menu); |
| |
| void mouseMove_animate(const TPointD &pos, const TMouseEvent &me); |
| void leftButtonDown_animate(const TPointD &pos, const TMouseEvent &me); |
| void leftButtonDrag_animate(const TPointD &pos, const TMouseEvent &me); |
| void leftButtonUp_animate(const TPointD &pos, const TMouseEvent &me); |
| void addContextMenuActions_animate(QMenu *menu); |
| |
| void draw_mesh(); |
| void draw_build(); |
| void draw_rigidity(); |
| void draw_animate(); |
| |
| private: |
| |
| |
| PlasticSkeleton &deformedSkeleton(); |
| void updateDeformedSkeleton(PlasticSkeleton &deformedSkeleton); |
| |
| |
| |
| void keyFunc_undo(void (PlasticTool::*keyFunc)()); |
| |
| void setKey(); |
| void setGlobalKey(); |
| void setRestKey(); |
| void setGlobalRestKey(); |
| |
| |
| static std::unique_ptr<tcg::polymorphic> createRigidityPainter(); |
| |
| |
| |
| void drawSkeleton(const PlasticSkeleton &skel, double pixelSize, |
| UCHAR alpha = 255); |
| void drawOnionSkinSkeletons_build(double pixelSize); |
| void drawOnionSkinSkeletons_animate(double pixelSize); |
| |
| void drawHighlights(const SkDP &sd, const PlasticSkeleton *skel, |
| double pixelSize); |
| void drawSelections(const SkDP &sd, const PlasticSkeleton &skel, |
| double pixelSize); |
| |
| void drawAngleLimits(const SkDP &sd, int skeId, int v, double pixelSize); |
| |
| |
| |
| void setMeshSelection(MeshSelection &target, const MeshSelection &newSel); |
| void toggleMeshSelection(MeshSelection &target, |
| const MeshSelection &addedSel); |
| |
| void onSelectionChanged() override; |
| void enableCommands() override; |
| |
| |
| |
| void onChange(const TParamChange &) override; |
| |
| private slots: |
| |
| void onFrameSwitched() override; |
| void onColumnSwitched(); |
| void onXsheetChanged(); |
| |
| void onShowMeshToggled(bool on); |
| void onShowSOToggled(bool on); |
| void onShowRigidityToggled(bool on); |
| void onShowSkelOSToggled(bool on); |
| }; |
| |
| |
| |
| |
| |
| class PlasticToolOptionsBox final : public GenericToolOptionsBox, |
| public TProperty::Listener { |
| Q_OBJECT |
| |
| public: |
| PlasticToolOptionsBox(QWidget *parent, TTool *tool, |
| TPaletteHandle *pltHandle); |
| |
| private: |
| class SkelIdsComboBox; |
| |
| private: |
| TTool *m_tool; |
| GenericToolOptionsBox **m_subToolbars; |
| |
| SkelIdsComboBox *m_skelIdComboBox; |
| QPushButton *m_addSkelButton, *m_removeSkelButton; |
| |
| private: |
| void showEvent(QShowEvent *se) override; |
| void hideEvent(QHideEvent *he) override; |
| |
| void onPropertyChanged() override; |
| |
| private slots: |
| |
| void onSkelIdsListChanged(); |
| void onSkelIdChanged(); |
| void onSkelIdEdited(); |
| |
| void onAddSkeleton(); |
| void onRemoveSkeleton(); |
| }; |
| |
| |
| |
| |
| |
| namespace PlasticToolLocals { |
| |
| extern PlasticTool l_plasticTool; |
| extern bool l_suspendParamsObservation; |
| |
| |
| |
| |
| |
| |
| TPointD projection( |
| const PlasticSkeleton &skeleton, int e, |
| const TPointD &pos); |
| |
| |
| |
| double frame(); |
| int row(); |
| |
| int column(); |
| TXshColumn *xshColumn(); |
| TStageObject *stageObject(); |
| |
| const TXshCell &xshCell(); |
| void setCell( |
| int row, |
| int col); |
| |
| int skeletonId(); |
| double sdFrame(); |
| |
| |
| |
| |
| |
| void setKeyframe( |
| TDoubleParamP ¶m, |
| double frame); |
| void setKeyframe( |
| SkVD *vd, |
| double frame); |
| void setKeyframe( |
| const PlasticSkeletonDeformationP &sd, |
| double frame); |
| |
| void invalidateXsheet(); |
| |
| |
| |
| void drawSquare(const TPointD &pos, |
| double radius); |
| void drawFullSquare(const TPointD &pos, |
| double radius); |
| |
| |
| |
| std::pair<double, PlasticTool::MeshIndex> closestVertex(const TMeshImage &mi, |
| const TPointD &pos); |
| std::pair<double, PlasticTool::MeshIndex> closestEdge(const TMeshImage &mi, |
| const TPointD &pos); |
| |
| } |
| |
| #endif // PLASTICTOOL_H |