diff --git a/toonz/sources/common/tmetaimage/tmetaimage.cpp b/toonz/sources/common/tmetaimage/tmetaimage.cpp index 8a0c5b4..f7af5d5 100644 --- a/toonz/sources/common/tmetaimage/tmetaimage.cpp +++ b/toonz/sources/common/tmetaimage/tmetaimage.cpp @@ -30,7 +30,7 @@ TMetaObject::setType(const TStringId &name) { if (m_handler) delete m_handler; m_type = name; Registry::const_iterator i = registry().find(m_type); - m_handler = i == registry().end() ? NULL : i->second(); + m_handler = i == registry().end() ? NULL : i->second(*this); onVariantChanged(m_data); } } diff --git a/toonz/sources/common/tvariant.cpp b/toonz/sources/common/tvariant.cpp index 2716709..9d26d86 100644 --- a/toonz/sources/common/tvariant.cpp +++ b/toonz/sources/common/tvariant.cpp @@ -208,3 +208,15 @@ TVariant::findCommonParent(const TVariant &other) const { return NULL; } + +//--------------------------------------------------------- + +size_t +TVariant::getMemSize() const { + size_t s = sizeof(*this); + for(TVariantList::const_iterator i = m_list.begin(); i != m_list.end(); ++i) + s += i->getMemSize(); + for(TVariantMap::const_iterator i = m_map.begin(); i != m_map.end(); ++i) + s += sizeof(*i) - sizeof(*this) + i->second.getMemSize(); + return s; +} diff --git a/toonz/sources/include/tmetaimage.h b/toonz/sources/include/tmetaimage.h index 75a876e..f172e48 100644 --- a/toonz/sources/include/tmetaimage.h +++ b/toonz/sources/include/tmetaimage.h @@ -36,14 +36,15 @@ typedef std::vector<TMetaObjectR> TMetaObjectRefList; class DVAPI TMetaObject: public TSmartObject, public TVariantOwner { public: - typedef TMetaObjectHandler* (*Fabric)(); + typedef TMetaObjectHandler* (*Fabric)(TMetaObject&); typedef std::map<TStringId, Fabric> Registry; template<typename T> class Registrator { public: typedef T Type; - static TMetaObjectHandler* fabric() { return new Type(); } + static TMetaObjectHandler* fabric(TMetaObject &obj) + { return new Type(obj); } Registrator(const std::string &typeName) { registerType(typeName, fabric); } Registrator(const TStringId &typeName) @@ -76,7 +77,7 @@ public: template<typename T> const T* getHandler() const - { return dynamic_cast<T*>(m_handler); } + { return dynamic_cast<const T*>(m_handler); } template<typename T> T* getHandler() { return dynamic_cast<T*>(m_handler); } @@ -97,7 +98,7 @@ public: class DVAPI TMetaObjectHandler { private: TMetaObject &m_object; - TAtomicVar m_fixindData; + TAtomicVar m_fixingData; public: TMetaObjectHandler(TMetaObject &object): @@ -119,12 +120,12 @@ protected: public: void dataChanged(const TVariant &value) - { if (m_fixindData != 0) onFixData(); } + { if (m_fixingData == 0) onDataChanged(value); } void fixData() { - ++m_fixindData; - if (m_fixindData == 1) onFixData(); - --m_fixindData; + ++m_fixingData; + if (m_fixingData == 1) onFixData(); + --m_fixingData; } }; diff --git a/toonz/sources/include/tools/assistant.h b/toonz/sources/include/tools/assistant.h index 34c50e9..2578a4b 100644 --- a/toonz/sources/include/tools/assistant.h +++ b/toonz/sources/include/tools/assistant.h @@ -77,10 +77,11 @@ public: Type type; TPointD position; - bool selected; + mutable bool selected; + double radius; - inline explicit TAssistantPoint(Type type = Circle, const TPointD &position = TPointD()): - type(Circle), position(position), selected() { } + explicit TAssistantPoint(Type type = Circle, const TPointD &position = TPointD()); + TAssistantPoint(Type type, const TPointD &position, double radius); }; //***************************************************************************************** @@ -105,17 +106,17 @@ public: inline const int pointsCount() const { return (int)m_points.size(); } - void fixPoints(int index, const TPointD &position); + void fixPoints(); void movePoint(int index, const TPointD &position); - void setPointSelection(int index, bool selected); + void setPointSelection(int index, bool selected) const; - inline void selectPoint(int index) + inline void selectPoint(int index) const { setPointSelection(index, true); } - inline void deselectPoint(int index) + inline void deselectPoint(int index) const { setPointSelection(index, false); } - inline void selectAll() + inline void selectAll() const { for(int i = 0; i < pointsCount(); ++i) setPointSelection(i, false); } - inline void deselectAll() + inline void deselectAll() const { for(int i = 0; i < pointsCount(); ++i) setPointSelection(i, false); } protected: @@ -123,7 +124,7 @@ protected: void onDataChanged(const TVariant &value) override; //! load object data from variant virtual void onAllDataChanged(); - //! fix positions of all points + //! fix positions of all points (as like as all points moved) virtual void onFixPoints(); //! try to move point virtual void onMovePoint(int index, const TPointD &position); diff --git a/toonz/sources/include/tools/tool.h b/toonz/sources/include/tools/tool.h index 0701889..4e79da4 100644 --- a/toonz/sources/include/tools/tool.h +++ b/toonz/sources/include/tools/tool.h @@ -283,13 +283,15 @@ public: MeshImage = 0x8, //!< Will work on mesh images Splines = 0x10, //!< Will work on motion paths - LevelColumns = 0x20, //!< Will work on level columns - MeshColumns = 0x40, //!< Will work on mesh columns + LevelColumns= 0x20, //!< Will work on level columns + MeshColumns = 0x40, //!< Will work on mesh columns EmptyTarget = 0x80, //!< Will work on empty cells/columns + MetaImage = 0x100, //!< Will work on mets images + CommonImages = VectorImage | ToonzImage | RasterImage, - AllImages = CommonImages | MeshImage, + AllImages = CommonImages | MeshImage | MetaImage, Vectors = VectorImage | Splines, CommonLevels = CommonImages | LevelColumns, diff --git a/toonz/sources/include/tools/toolcommandids.h b/toonz/sources/include/tools/toolcommandids.h index 8d2524f..33b78dc 100644 --- a/toonz/sources/include/tools/toolcommandids.h +++ b/toonz/sources/include/tools/toolcommandids.h @@ -30,5 +30,6 @@ #define T_Hand "T_Hand" #define T_Ruler "T_Ruler" #define T_Finger "T_Finger" +#define T_EditAssistants "T_EditAssistants" #endif // TOOL_COMMAND_IDS_H diff --git a/toonz/sources/include/tvariant.h b/toonz/sources/include/tvariant.h index 224e083..b5f6fe4 100644 --- a/toonz/sources/include/tvariant.h +++ b/toonz/sources/include/tvariant.h @@ -359,6 +359,9 @@ public: const TVariant* findCommonParent(const TVariant &other) const; + // memory + size_t getMemSize() const; + // serialization // TODO: }; diff --git a/toonz/sources/tnztools/CMakeLists.txt b/toonz/sources/tnztools/CMakeLists.txt index 247f89c..9e67138 100644 --- a/toonz/sources/tnztools/CMakeLists.txt +++ b/toonz/sources/tnztools/CMakeLists.txt @@ -127,6 +127,7 @@ set(SOURCES modifiers/modifierassistants.cpp assistants/guidelineline.cpp assistants/assistantvanishingpoint.cpp + editassistantstool.cpp ) set(RESOURCES tnztools.qrc) diff --git a/toonz/sources/tnztools/assistant.cpp b/toonz/sources/tnztools/assistant.cpp index e2e5ad7..8e33f1d 100644 --- a/toonz/sources/tnztools/assistant.cpp +++ b/toonz/sources/tnztools/assistant.cpp @@ -22,7 +22,7 @@ TGuideline::drawSegment(const TPointD &p0, const TPointD &p1, double pixelSize, TPointD d = p1 - p0; double k = norm2(d); if (k > TConsts::epsilon*TConsts::epsilon) { - double k = 0.5*pixelSize/sqrt(k); + k = 0.5*pixelSize/sqrt(k); d = TPointD(-k*d.y, k*d.x); glColor4dv(colorWhite); tglDrawSegment(p0 - d, p1 - d); @@ -91,6 +91,32 @@ TGuideline::findBest(const TGuidelineList &guidelines, const TTrack &track, cons //************************************************************************ +// TAssistantPoint implementation +//************************************************************************ + +TAssistantPoint::TAssistantPoint( + Type type, + const TPointD &position +): + type(type), + position(position), + radius(10.0), + selected() { } + +//--------------------------------------------------------------------------------------------------- + +TAssistantPoint::TAssistantPoint( + Type type, + const TPointD &position, + double radius +): + type(type), + position(position), + radius(radius), + selected() { } + + +//************************************************************************ // TAssistant implementation //************************************************************************ @@ -112,7 +138,7 @@ TAssistant::blank() { //--------------------------------------------------------------------------------------------------- void -TAssistant::fixPoints(int index, const TPointD &position) +TAssistant::fixPoints() { onFixPoints(); } //--------------------------------------------------------------------------------------------------- @@ -124,7 +150,7 @@ TAssistant::movePoint(int index, const TPointD &position) //--------------------------------------------------------------------------------------------------- void -TAssistant::setPointSelection(int index, bool selected) { +TAssistant::setPointSelection(int index, bool selected) const { if (index >= 0 && index < pointsCount()) m_points[index].selected = selected; } @@ -159,11 +185,11 @@ TAssistant::onAllDataChanged() { pointData[m_idX].getDouble(), pointData[m_idY].getDouble() ); } + fixPoints(); } //--------------------------------------------------------------------------------------------------- -//! fix positions of all points void TAssistant::onFixPoints() { } @@ -213,45 +239,49 @@ TAssistant::drawSegment(const TPointD &p0, const TPointD &p1, double pixelSize) void TAssistant::drawPoint(const TAssistantPoint &point, double pixelSize) const { - double radius = 10.0; + double radius = point.radius; double crossSize = 1.2*radius; double colorBlack[4] = { 0.0, 0.0, 0.0, 0.5 }; double colorGray[4] = { 0.5, 0.5, 0.5, 0.5 }; double colorWhite[4] = { 1.0, 1.0, 1.0, 0.5 }; + double width = 0.5; if (point.selected) { colorBlack[2] = 1.0; colorGray[2] = 1.0; + width = 2.0; } glPushAttrib(GL_ALL_ATTRIB_BITS); + // fill tglEnableBlending(); - tglEnableLineSmooth(true, 0.5); - if (point.type == TAssistantPoint::CircleFill) { glColor4dv(colorGray); tglDrawDisk(point.position, radius*pixelSize); } - if (point.type == TAssistantPoint::CircleCross) { - TPointD dp(0.5*pixelSize, 0.5*pixelSize); - TPointD dx(pixelSize*crossSize, 0.0); - TPointD dy(0.0, pixelSize*crossSize); + TPointD crossDx(pixelSize*crossSize, 0.0); + TPointD crossDy(0.0, pixelSize*crossSize); - glColor4dv(colorWhite); - tglDrawSegment(point.position - dx + dp, point.position + dx + dp); - tglDrawSegment(point.position - dy + dp, point.position + dy + dp); - glColor4dv(colorBlack); - tglDrawSegment(point.position - dx - dp, point.position + dx - dp); - tglDrawSegment(point.position - dy - dp, point.position + dy - dp); + // back line + tglEnableLineSmooth(true, 2.0*std::max(1.0, width)); + glColor4dv(colorWhite); + if (point.type == TAssistantPoint::CircleCross) { + tglDrawSegment(point.position - crossDx, point.position + crossDx); + tglDrawSegment(point.position - crossDy, point.position + crossDy); } + tglDrawCircle(point.position, radius*pixelSize); - glColor4dv(colorWhite); - tglDrawCircle(point.position, (radius + 0.5)*pixelSize); + // front line + glLineWidth(width); glColor4dv(colorBlack); - tglDrawCircle(point.position, (radius - 0.5)*pixelSize); + if (point.type == TAssistantPoint::CircleCross) { + tglDrawSegment(point.position - crossDx, point.position + crossDx); + tglDrawSegment(point.position - crossDy, point.position + crossDy); + } + tglDrawCircle(point.position, radius*pixelSize); glPopAttrib(); } diff --git a/toonz/sources/tnztools/assistants/assistantvanishingpoint.cpp b/toonz/sources/tnztools/assistants/assistantvanishingpoint.cpp index f500427..73489c0 100644 --- a/toonz/sources/tnztools/assistants/assistantvanishingpoint.cpp +++ b/toonz/sources/tnztools/assistants/assistantvanishingpoint.cpp @@ -7,6 +7,14 @@ #include "tgl.h" + +//***************************************************************************************** +// Registration +//***************************************************************************************** + +static TMetaObject::Registrator<TAssistantVanishingPoint> assistantVanishingPoint("assistantVanishingPoint"); + + //***************************************************************************************** // TAssistantVanishingPoint implementation //***************************************************************************************** diff --git a/toonz/sources/tnztools/assistants/guidelineline.cpp b/toonz/sources/tnztools/assistants/guidelineline.cpp index 3ca0eea..55287df 100644 --- a/toonz/sources/tnztools/assistants/guidelineline.cpp +++ b/toonz/sources/tnztools/assistants/guidelineline.cpp @@ -41,16 +41,17 @@ TGuidelineLineBase::truncateInfiniteLine(const TRectD &bounds, TPointD &p0, TPoi void TGuidelineLineBase::drawInliniteLine(const TPointD &p0, const TPointD &p1, bool ray, bool active) const { - TAffine4 modelview; + TAffine4 modelview, projection; glGetDoublev(GL_MODELVIEW_MATRIX, modelview.a); + glGetDoublev(GL_PROJECTION_MATRIX, projection.a); - TAffine matrix = modelview.get2d(); + TAffine matrix = (projection*modelview).get2d(); TPointD pp0 = matrix*p0; TPointD pp1 = matrix*p1; truncateInfiniteLine(TRectD(-1.0, -1.0, 1.0, 1.0), pp0, pp1); + double pixelSize = sqrt(tglGetPixelSize2()); TAffine matrixInv = matrix.inv(); - double pixelSize = norm(TPointD(matrixInv.a11 + matrixInv.a12, matrixInv.a21 + matrixInv.a22)); drawSegment((ray ? p0 : matrixInv*pp0), matrixInv*pp1, pixelSize, active); } diff --git a/toonz/sources/tnztools/assistants/guidelineline.h b/toonz/sources/tnztools/assistants/guidelineline.h index 470f953..f283940 100644 --- a/toonz/sources/tnztools/assistants/guidelineline.h +++ b/toonz/sources/tnztools/assistants/guidelineline.h @@ -44,8 +44,6 @@ public: class DVAPI TGuidelineLine : public TGuidelineLineBase { public: - const TPointD p0; - const TPointD p1; const TPointD dir; const double dist; @@ -61,8 +59,6 @@ public: class DVAPI TGuidelineInfiniteLine : public TGuidelineLineBase { public: - const TPointD p0; - const TPointD p1; const TPointD dir; TGuidelineInfiniteLine(const TPointD &p0, const TPointD &p1); @@ -77,8 +73,6 @@ public: class DVAPI TGuidelineRay : public TGuidelineLineBase { public: - const TPointD p0; - const TPointD p1; const TPointD dir; TGuidelineRay(const TPointD &p0, const TPointD &p1); diff --git a/toonz/sources/tnztools/editassistantstool.cpp b/toonz/sources/tnztools/editassistantstool.cpp new file mode 100644 index 0000000..4cef33a --- /dev/null +++ b/toonz/sources/tnztools/editassistantstool.cpp @@ -0,0 +1,308 @@ + +// TnzTools includes +#include <tools/tool.h> +#include <tools/toolutils.h> +#include <tools/toolhandle.h> +#include <tools/cursors.h> +#include <tools/assistant.h> + +// TnzLib includes +#include <toonz/tapplication.h> +#include <toonz/txshlevelhandle.h> + +// TnzCore includes +#include <tgl.h> +#include <tproperty.h> +#include <tmetaimage.h> + +// For Qt translation support +#include <QCoreApplication> + +#include <map> + + +//------------------------------------------------------------------- + +//============================================================================= +// Edit Assistants Undo +//----------------------------------------------------------------------------- + +class EditAssistantsUndo final : public ToolUtils::TToolUndo { +private: + bool m_isAssistantCreated; + TMetaObjectP m_metaObject; + TVariant m_oldData; + TVariant m_newData; + size_t m_size; + +public: + EditAssistantsUndo( + TXshSimpleLevel *level, + const TFrameId &frameId, + bool isAssistantCreated, + TMetaObjectR metaObject, + TVariant oldData + ): + ToolUtils::TToolUndo(level, frameId), + m_isAssistantCreated(isAssistantCreated), + m_metaObject(metaObject.getPointer()), + m_oldData(oldData), + m_newData(m_metaObject->data()), + m_size(m_oldData.getMemSize() + m_newData.getMemSize()) + { } + + int getSize() const override + { return m_size; } + QString getToolName() override + { return QString("Edit Assistants Tool"); } + + void undo() const override { + if (TMetaImage *metaImage = dynamic_cast<TMetaImage*>(m_level->getFrame(m_frameId, true).getPointer())) { + TMetaImage::Writer writer(*metaImage); + if (m_isAssistantCreated) { + for(TMetaObjectRefList::iterator i = writer->begin(); i != writer->end(); ++i) + if (*i == m_metaObject) { writer->erase(i); break; } + } else { + m_metaObject->data() = m_oldData; + if (TMetaObjectHandler *handler = m_metaObject->getHandler<TMetaObjectHandler>()) + handler->fixData(); + } + notifyImageChanged(); + } + } + + void redo() const override { + if (TMetaImage *metaImage = dynamic_cast<TMetaImage*>(m_level->getFrame(m_frameId, true).getPointer())) { + TMetaImage::Writer writer(*metaImage); + m_metaObject->data() = m_newData; + if (TMetaObjectHandler *handler = m_metaObject->getHandler<TMetaObjectHandler>()) + handler->fixData(); + if (m_isAssistantCreated) + writer->push_back(TMetaObjectR(m_metaObject.getPointer())); + notifyImageChanged(); + } + } +}; + + +//============================================================================= +// Edit Assistants Tool +//----------------------------------------------------------------------------- + +class EditAssistantsTool final : public TTool { + Q_DECLARE_TR_FUNCTIONS(EditAssistantsTool) +public: + typedef std::map<std::wstring, TStringId> TypeMap; + +protected: + TPropertyGroup m_prop; + TEnumProperty m_assistantType; + TypeMap m_localnameToType; + TStringId m_newAssisnantType; + + bool m_dragging; + bool m_currentAssistantCreated; + int m_currentAssistantIndex; + int m_currentPointIndex; + TPointD m_currentPointOffset; + TVariant m_currentAssistantBackup; + TPointD m_currentPosition; + TGuidelineList m_currentGuidelines; + +public: + EditAssistantsTool(): + TTool("T_EditAssistants"), + m_assistantType("AssistantType"), + m_dragging(), + m_currentAssistantCreated(), + m_currentAssistantIndex(-1), + m_currentPointIndex(-1) + { + bind(MetaImage); + m_prop.add(&m_assistantType); + updateTranslation(); + } + + ~EditAssistantsTool() + { m_prop.clear(); } + + ToolType getToolType() const override + { return TTool::LevelWriteTool; } + int getCursorId() const override + { return ToolCursor::StrokeSelectCursor; } + TPropertyGroup* getProperties(int targetType) override + { return &m_prop; } + void onImageChanged() override + { getViewer()->GLInvalidateAll(); } + + void addAssistantType(const std::string &name, const std::string &typeName) { + const std::wstring localName = tr(name.c_str()).toStdWString(); + if (m_localnameToType.count(localName)) return; + m_localnameToType[localName] = TStringId(typeName); + m_assistantType.addValue(localName); + } + + void updateTranslation() override { + m_assistantType.setQStringName(tr("Assistant Type")); + m_assistantType.deleteAllValues(); + m_localnameToType.clear(); + addAssistantType("--", ""); + addAssistantType("Vanishing Point", "assistantVanishingPoint"); + m_assistantType.setIndex(0); + } + + bool onPropertyChanged(std::string propertyName) override { + TypeMap::const_iterator i = m_localnameToType.find(m_assistantType.getValue()); + m_newAssisnantType = i == m_localnameToType.end() ? TStringId() : i->second; + return true; + } + + void resetCurrentPoint() { + m_currentAssistantCreated = false; + m_currentAssistantIndex = -1; + m_currentPointIndex = -1; + m_currentPointOffset = TPointD(); + m_currentAssistantBackup.reset(); + } + + const TAssistant* findCurrentPoint(const TPointD &position) { + resetCurrentPoint(); + TMetaImage *mi = dynamic_cast<TMetaImage*>(getImage(false)); + if (!mi) return NULL; + + double pixelSize2 = tglGetPixelSize2(); + TMetaImage::Reader reader(*mi); + const TAssistant *currentAssisntant = NULL; + for(TMetaObjectRefList::const_iterator i = reader->begin(); i != reader->end(); ++i) { + if (!*i) continue; + const TAssistant *assistant = (*i)->getHandler<TAssistant>(); + if (!assistant) continue; + assistant->deselectAll(); + for(int j = 0; j < assistant->pointsCount() && m_currentAssistantIndex < 0; ++j) { + const TAssistantPoint &p = assistant->points()[j]; + TPointD offset = p.position - position; + if (norm2(offset) <= p.radius*p.radius*pixelSize2) { + m_currentAssistantIndex = i - reader->begin(); + m_currentPointIndex = j; + m_currentPointOffset = offset; + currentAssisntant = assistant; + assistant->selectPoint(j); + break; + } + } + } + return currentAssisntant; + } + + void mouseMove(const TPointD &position, const TMouseEvent&) override { + if (m_dragging) return; + findCurrentPoint(position); + m_currentPosition = position; + getViewer()->GLInvalidateAll(); + } + + void leftButtonDown(const TPointD &position, const TMouseEvent&) override { + m_dragging = true; + if (m_newAssisnantType) { + // create assistant + resetCurrentPoint(); + if (TMetaImage *mi = dynamic_cast<TMetaImage*>(getImage(true))) { + TMetaImage::Writer writer(*mi); + TMetaObjectR obj(new TMetaObject(m_newAssisnantType)); + if (TAssistant *assistant = obj->getHandler<TAssistant>()) { + if (assistant->pointsCount()) { + assistant->movePoint(0, position); + m_currentAssistantCreated = true; + m_currentAssistantIndex = (int)writer->size(); + m_currentPointIndex = 0; + m_currentPointOffset = TPointD(); + } + writer->push_back(obj); + } + } + m_newAssisnantType.reset(); + } else + if (const TAssistant *assistant = findCurrentPoint(position)) { + m_currentAssistantBackup = assistant->data(); + } + m_currentPosition = position; + getViewer()->GLInvalidateAll(); + } + + void leftButtonDrag(const TPointD &position, const TMouseEvent&) override { + if (m_currentAssistantIndex >= 0) + if (m_currentPointIndex >= 0) + if (TMetaImage *mi = dynamic_cast<TMetaImage*>(getImage(true))) + { + TMetaImage::Writer writer(*mi); + if (m_currentAssistantIndex < (int)writer->size()) + if (TMetaObjectR obj = (*writer)[m_currentAssistantIndex]) + if (TAssistant *assistant = obj->getHandler<TAssistant>()) + if (m_currentPointIndex < assistant->pointsCount()) + { + assistant->movePoint( + m_currentPointIndex, + position + m_currentPointOffset); + } + } + m_currentPosition = position; + getViewer()->GLInvalidateAll(); + } + + void leftButtonUp(const TPointD &position, const TMouseEvent&) override { + if (m_currentAssistantIndex >= 0) + if (m_currentPointIndex >= 0) + if (TMetaImage *mi = dynamic_cast<TMetaImage*>(getImage(true))) + { + TMetaImage::Writer writer(*mi); + if (m_currentAssistantIndex < (int)writer->size()) + if (TMetaObjectR obj = (*writer)[m_currentAssistantIndex]) + if (TAssistant *assistant = obj->getHandler<TAssistant>()) + if (m_currentPointIndex < assistant->pointsCount()) + { + assistant->movePoint( + m_currentPointIndex, + position + m_currentPointOffset); + assistant->fixData(); + TUndoManager::manager()->add(new EditAssistantsUndo( + getApplication()->getCurrentLevel()->getLevel()->getSimpleLevel(), + getCurrentFid(), + m_currentAssistantCreated, + obj, + m_currentAssistantBackup )); + } + } + m_assistantType.setIndex(0); + getApplication()->getCurrentTool()->notifyToolChanged(); + m_currentPosition = position; + getViewer()->GLInvalidateAll(); + m_dragging = false; + } + + void draw() override { + m_currentGuidelines.clear(); + + // draw assistants + TMetaImage *mi = dynamic_cast<TMetaImage*>(getImage(false)); + if (!mi) return; + TMetaImage::Reader reader(*mi); + for(TMetaObjectRefList::const_iterator i = reader->begin(); i != reader->end(); ++i) + if (*i) + if (const TAssistant *assistant = (*i)->getHandler<TAssistant>()) + { + assistant->drawEdit(getViewer()); + assistant->getGuidelines( + m_currentPosition + m_currentPointOffset, + TAffine(), + m_currentGuidelines ); + } + + // draw guidelines + for(TGuidelineList::const_iterator i = m_currentGuidelines.begin(); i != m_currentGuidelines.end(); ++i) + (*i)->draw(); + } +}; + +//------------------------------------------------------------------- + +EditAssistantsTool editAssistantsTool; diff --git a/toonz/sources/tnztools/tool.cpp b/toonz/sources/tnztools/tool.cpp index b97e9bd..36f0e23 100644 --- a/toonz/sources/tnztools/tool.cpp +++ b/toonz/sources/tnztools/tool.cpp @@ -209,6 +209,8 @@ void TTool::bind(int targetType) { std::make_pair(std::make_pair(name, RasterImage), &theDummyTool)); toolTable->insert( std::make_pair(std::make_pair(name, MeshImage), &theDummyTool)); + toolTable->insert( + std::make_pair(std::make_pair(name, MetaImage), &theDummyTool)); ToolSelector *toolSelector = new ToolSelector(name); CommandManager::instance()->setHandler( @@ -224,6 +226,8 @@ void TTool::bind(int targetType) { (*toolTable)[std::make_pair(name, RasterImage)] = this; if (targetType & MeshImage) (*toolTable)[std::make_pair(name, MeshImage)] = this; + if (targetType & MetaImage) + (*toolTable)[std::make_pair(name, MetaImage)] = this; } //----------------------------------------------------------------------------- @@ -1026,6 +1030,11 @@ QString TTool::updateEnabled(int rowIndex, int columnIndex) { return ( enable(false), QObject::tr("The current tool cannot be used on a Mesh Level.")); + + if ((levelType == META_XSHLEVEL) && !(targetType & MetaImage)) + return ( + enable(false), + QObject::tr("The current tool cannot be used on a Assistants (Meta) Level.")); } // Check against impossibly traceable movements on the column diff --git a/toonz/sources/tnztools/toolhandle.cpp b/toonz/sources/tnztools/toolhandle.cpp index bd5d307..be4ff6b 100644 --- a/toonz/sources/tnztools/toolhandle.cpp +++ b/toonz/sources/tnztools/toolhandle.cpp @@ -126,13 +126,16 @@ void ToolHandle::onImageChanged(TImage::Type imageType) { case TImage::TOONZ_RASTER: targetType = TTool::ToonzImage; break; + case TImage::MESH: + targetType = TTool::MeshImage; + break; + case TImage::META: + targetType = TTool::MetaImage; + break; case TImage::VECTOR: default: targetType = TTool::VectorImage; break; - case TImage::MESH: - targetType = TTool::MeshImage; - break; } if (targetType != m_toolTargetType) { diff --git a/toonz/sources/toonz/mainwindow.cpp b/toonz/sources/toonz/mainwindow.cpp index 8345aa2..0959e26 100644 --- a/toonz/sources/toonz/mainwindow.cpp +++ b/toonz/sources/toonz/mainwindow.cpp @@ -2472,6 +2472,7 @@ void MainWindow::defineActions() { createToolAction(T_Plastic, "plastic", QT_TR_NOOP("Plastic Tool"), "X"); createToolAction(T_Ruler, "ruler", QT_TR_NOOP("Ruler Tool"), ""); createToolAction(T_Finger, "finger", QT_TR_NOOP("Finger Tool"), ""); + createToolAction(T_EditAssistants, "geometric", QT_TR_NOOP("Edit Assistants"), ""); /*-- Animate tool + mode switching shortcuts --*/ createAction(MI_EditNextMode, QT_TR_NOOP("Animate Tool - Next Mode"), "", diff --git a/toonz/sources/toonz/tapp.cpp b/toonz/sources/toonz/tapp.cpp index 512b12c..a3cb66b 100644 --- a/toonz/sources/toonz/tapp.cpp +++ b/toonz/sources/toonz/tapp.cpp @@ -325,11 +325,13 @@ int TApp::getCurrentImageType() { return TImage::TOONZ_RASTER; case OVL_XSHLEVEL: return TImage::RASTER; + case META_XSHLEVEL: + return TImage::META; + case MESH_XSHLEVEL: + return TImage::MESH; case PLI_XSHLEVEL: default: return TImage::VECTOR; - case MESH_XSHLEVEL: - return TImage::MESH; } } diff --git a/toonz/sources/toonz/toolbar.cpp b/toonz/sources/toonz/toolbar.cpp index 5dd543a..39b51e8 100755 --- a/toonz/sources/toonz/toolbar.cpp +++ b/toonz/sources/toonz/toolbar.cpp @@ -44,6 +44,7 @@ struct { {T_Tape, false, 0}, {T_Finger, false, 0}, {"Separator_3", false, 0}, {T_StylePicker, false, 0}, {T_RGBPicker, false, 0}, {T_Ruler, false, 0}, + {T_EditAssistants, false, 0}, {"Separator_4", false, 0}, {T_ControlPointEditor, false, 0}, {T_Pinch, true, 0}, {T_Pump, true, 0}, {T_Magnet, true, 0}, {T_Bender, true, 0}, diff --git a/toonz/sources/toonzqt/icongenerator.cpp b/toonz/sources/toonzqt/icongenerator.cpp index c3f8264..0314ce2 100644 --- a/toonz/sources/toonzqt/icongenerator.cpp +++ b/toonz/sources/toonzqt/icongenerator.cpp @@ -1592,7 +1592,7 @@ void IconGenerator::invalidate(TXshLevel *xl, const TFrameId &fid, m_settings)); break; default: - assert(false); + addTask(id, new NoImageIconRenderer(id, getIconSize())); break; } @@ -1630,7 +1630,7 @@ void IconGenerator::invalidate(TXshLevel *xl, const TFrameId &fid, m_settings)); break; default: - assert(false); + addTask(id, new NoImageIconRenderer(id, TDimension(80, 60))); break; }