#pragma once #ifndef SKELETON_INCLUDED #define SKELETON_INCLUDED #include "tgeometry.h" #include #undef DVAPI #undef DVVAR #ifdef TOONZLIB_EXPORTS #define DVAPI DV_EXPORT_API #define DVVAR DV_EXPORT_VAR #else #define DVAPI DV_IMPORT_API #define DVVAR DV_IMPORT_VAR #endif class TXsheet; class TStageObject; //! The Skeleton is the data structure used by the Skeleton Tool class DVAPI Skeleton { public: class DVAPI Bone { public: enum PinnedStatus { FREE, PINNED, TEMP_PINNED }; Bone(TStageObject *pegbar, const TPointD ¢er) : m_parent(0) , m_stageObject(pegbar) , m_center(center) , m_selected(false) , m_pinnedStatus(FREE) {} void setParent(Bone *parent); Bone *getParent() const { return m_parent; } int getChildCount() const { return (int)m_children.size(); } Bone *getChild(int index) const { return 0 <= index && index < getChildCount() ? m_children[index] : 0; } TStageObject *getStageObject() const { return m_stageObject; } int getColumnIndex() const; const TPointD &getCenter() const { return m_center; } void select(bool selected = true) { m_selected = selected; } bool isSelected() const { return m_selected; } PinnedStatus getPinnedStatus() const { return m_pinnedStatus; } void setPinnedStatus(PinnedStatus pinnedStatus) { m_pinnedStatus = pinnedStatus; } private: Bone *m_parent; std::vector m_children; TStageObject *m_stageObject; TPointD m_center; // position of the rotation center of the stageobject, // i.e. the "joint" bool m_selected; // true if the bone belongs to the active chain (i.e. // handle <-> pinned points) PinnedStatus m_pinnedStatus; }; // class Bone private: std::vector m_bones; Bone *m_rootBone; public: Skeleton(); ~Skeleton(); //! create a skeleton containing 'col'. //! tempPinnedColumns contains the column indices of the temporarily pinned //! bones void build(TXsheet *xsh, int row, int col, const std::set &tempPinnedColumns = std::set()); //! reset the skeleton void clear(); int getBoneCount() const { return m_bones.size(); } Bone *getBone(int index) const; Bone *getBoneByColumnIndex(int columnIndex) const; //! the root is the ancestor of each bone in the skeleton Bone *getRootBone() const { return m_rootBone; } //! helper functions. see TPinnedRangeSet //! the root status is TStageObject::IK bool isIKEnabled() const; //! Some bone has a not empty pinned range bool hasPinnedRanges() const; void clearAllPinnedRanges(); }; #endif