///////////////////////////////////////////////////////////// // CINEMA 4D SDK // ///////////////////////////////////////////////////////////// // (c) MAXON Computer GmbH, all rights reserved // ///////////////////////////////////////////////////////////// #ifndef __C4DBASEOBJECT_H #define __C4DBASEOBJECT_H #ifdef __API_INTERN__ abc def xyz #endif #include "c4d_baselist.h" #include "c4d_basecontainer.h" #include "operatingsystem.h" class BaseTag; class BaseDocument; class BaseContainer; class LineObject; class BaseThread; class BaseSelect; class Neighbor; #define MODE_ON 0 #define MODE_OFF 1 #define MODE_UNDEF 2 struct CPolygon { Int32 a, b, c, d; public: CPolygon(void) { } CPolygon(Int32 t_a, Int32 t_b, Int32 t_c) { a = t_a; b = t_b; c = d = t_c; } CPolygon(Int32 t_a, Int32 t_b, Int32 t_c, Int32 t_d) { a = t_a; b = t_b; c = t_c; d = t_d; } Int32& operator[](Int32 index) const { return ((Int32*)this)[index & 3]; } Bool IsTriangle(void) const { return c == d; } Int32 Find(Int32 index) const { return (d == index ? 3 : (c == index ? 2 : (b == index ? 1 : (a == index ? 0 : NOTOK)))); } Int32 FindEdge(Int32 index1, Int32 index2) const { if (d == index1) return a == index2 ? 3 : (c == d ? (b == index2 ? 1 : NOTOK) : (c == index2 ? 2 : NOTOK)); if (c == index1) return b == index2 ? 1 : (c == d ? (a == index2 ? 3 : NOTOK) : (d == index2 ? 2 : NOTOK)); if (b == index1) return c == index2 ? 1 : (a == index2 ? 0 : NOTOK); if (a == index1) return b == index2 ? 0 : (d == index2 ? 3 : NOTOK); return NOTOK; } void EdgePoints(Int32 edge, Int32& a, Int32& b) const { a = ((Int32*)this)[edge & 3]; b = ((Int32*)this)[(edge + 1) & 3]; } Int32& GetPoint(Int32 index) const { if (c == d) return ((Int32*)this)[(index + (3 << 24)) % 3]; return ((Int32*)this)[index & 3]; } }; struct Tangent { Vector vl, vr; }; struct Segment { Int32 cnt; Bool closed; }; struct ObjectColorProperties { Int32 usecolor; Vector color; Bool xray; }; class HierarchyHelp { private: HierarchyHelp(); ~HierarchyHelp(); public: Float GetLOD(void) { return C4DOS.Bd->HhGetLOD(this); } BUILDFLAGS GetBuildFlags(void) { return C4DOS.Bd->HhGetBuildFlags(this); } const Matrix& GetMg(void) { return C4DOS.Bd->HhGetMg(this); } BaseThread* GetThread(void) { return C4DOS.Bd->HhGetThread(this); } BaseDocument* GetDocument(void) { return C4DOS.Bd->HhGetDocument(this); } }; class BaseObject : public BaseList2D { private: BaseObject(); ~BaseObject(); public: BaseObject* GetNext (void) { return (BaseObject*)AtCall(GetNext) (); } BaseObject* GetPred (void) { return (BaseObject*)AtCall(GetPred) (); } BaseObject* GetUp (void) { return (BaseObject*)AtCall(GetUp) (); } BaseObject* GetDown (void) { return (BaseObject*)AtCall(GetDown) (); } BaseObject* GetDownLast(void) { return (BaseObject*)AtCall(GetDownLast) (); } Float GetVisibility(Float parent); Vector GetAbsPos() const { return BoCall(GetAbsPos) (); } void SetAbsPos(const Vector& v) { BoCall(SetAbsPos) (v); } Vector GetAbsScale() const { return BoCall(GetAbsScale) (); } void SetAbsScale(const Vector& v) { BoCall(SetAbsScale) (v); } Vector GetAbsRot() const { return BoCall(GetAbsRot) (); } void SetAbsRot(const Vector& v) { BoCall(SetAbsRot) (v); } Vector GetFrozenPos() const { return BoCall(GetFrozenPos) (); } void SetFrozenPos(const Vector& v) { BoCall(SetFrozenPos) (v); } Vector GetFrozenScale() const { return BoCall(GetFrozenScale) (); } void SetFrozenScale(const Vector& v) { BoCall(SetFrozenScale) (v); } Vector GetFrozenRot() const { return BoCall(GetFrozenRot) (); } void SetFrozenRot(const Vector& v) { BoCall(SetFrozenRot) (v); } Vector GetRelPos() const { return BoCall(GetRelPos) (); } void SetRelPos(const Vector& v) { BoCall(SetRelPos) (v); } Vector GetRelScale() const { return BoCall(GetRelScale) (); } void SetRelScale(const Vector& v) { BoCall(SetRelScale) (v); } Vector GetRelRot() const { return BoCall(GetRelRot) (); } void SetRelRot(const Vector& v) { BoCall(SetRelRot) (v); } const Matrix& GetMl(void) const { return BoCall(GetMl) (); } void SetMl(const Matrix& m) { BoCall(SetMl) (m); } Matrix GetFrozenMln() const { return BoCall(GetFrozenMln) (); } Matrix GetRelMln() const { return BoCall(GetRelMln) (); } Matrix GetRelMl() const { return BoCall(GetRelMl) (); } void SetRelMl(const Matrix& m) { BoCall(SetRelMl) (m); } Matrix GetMg() const { return BoCall(GetMg) (); } void SetMg(const Matrix& m) { BoCall(SetMg) (m); } Matrix GetMln() const { return BoCall(GetMln) (); } Matrix GetMgn() const { return BoCall(GetMgn) (); } Matrix GetUpMg() const { return BoCall(GetUpMg) (); } void CopyMatrixTo(BaseObject* dst) { C4DOS.Bo->CopyMatrixTo(this, dst); } Vector GetMp (void) { return C4DOS.Bo->GetMp(this); } Vector GetRad(void) { return C4DOS.Bo->GetRad(this); } Int32 GetEditorMode(void); void SetEditorMode(Int32 mode); Int32 GetRenderMode(void); void SetRenderMode(Int32 mode); Bool GetDeformMode(void); void SetDeformMode(Bool mode); Int32 GetUniqueIP(void); void SetUniqueIP(Int32 ip); void SetOrigin(BaseObject* origin); BaseObject* GetOrigin(Bool safe); BaseObject* GetTopOrigin(Bool parent, Bool safe); BaseObject* GetEditObject(BaseObject** psds, DISPLAYEDITSTATE state); BaseTag* GetFirstTag(void); BaseTag* GetTag(Int32 type, Int32 nr = 0) { return C4DOS.Bo->GetTag(this, type, nr); } const void* GetTagDataR(Int32 type, Int32 nr = 0) const { return C4DOS.Bo->GetTagDataR(this, type, nr); } void* GetTagDataW(Int32 type, Int32 nr = 0) { return C4DOS.Bo->GetTagData(this, type, nr); } Int32 GetTagDataCount(Int32 type) const { return C4DOS.Bo->GetTagDataCount(this, type); } BaseTag* MakeTag (Int32 type, BaseTag* pred = nullptr); VariableTag* MakeVariableTag(Int32 type, Int32 count, BaseTag* pred = nullptr); void InsertTag(BaseTag* tp, BaseTag* pred = nullptr); void KillTag (Int32 type, Int32 nr = 0); BaseObject* GetCache(HierarchyHelp* hh = nullptr) { return C4DOS.Bo->GetCache(this, hh); } BaseObject* GetDeformCache(void) { return C4DOS.Bo->GetDeformCache(this); } LineObject* GetIsoparm(void) { return C4DOS.Bo->GetIsoparm(this); } void SetIsoparm(LineObject* l); BaseObject* GetCacheParent(void); Bool CopyTagsTo(BaseObject* dest, Int32 visible, Int32 variable, Int32 hierarchical, AliasTrans* trans); Bool SetPhong(Bool on, Bool anglelimit, Float angle); Bool IsDirty(DIRTYFLAGS flags) { return C4DOS.Bo->IsDirty(this, flags); } void SetDirty(DIRTYFLAGS flags) { C4DOS.Bo->SetDirty(this, flags); } Bool CheckCache(HierarchyHelp* hh) { return C4DOS.Bo->CheckCache(this, hh); } void Touch(void); void SetColorProperties(ObjectColorProperties* prop); void GetColorProperties(ObjectColorProperties* prop); SplineObject* GetRealSpline(void); Int32 GetHighlightHandle(BaseDraw* bd) { return C4DOS.Bo->GetHighlightHandle(this, bd); } static BaseObject* Alloc(Int32 type); static void Free(BaseObject*& bl); const Matrix& GetModelingAxis(BaseDocument* doc) { return C4DOS.Bo->GetModelingAxis(this, doc); } void SetModelingAxis(const Matrix& m) { C4DOS.Bo->SetModelingAxis(this, m); } BaseObject* GetAndCheckHierarchyClone(HierarchyHelp* hh, BaseObject* op, HIERARCHYCLONEFLAGS flags, Bool* dirty, AliasTrans* trans, Bool allchildren); BaseObject* GetHierarchyClone(HierarchyHelp* hh, BaseObject* op, HIERARCHYCLONEFLAGS flags, Bool* dirty, AliasTrans* trans); void NewDependenceList(void); Bool CompareDependenceList(void); void AddDependence(HierarchyHelp* hh, BaseObject* op); void TouchDependenceList(void); void RemoveFromCache(void); Bool SearchHierarchy(BaseObject* op) { return C4DOS.Bo->SearchHierarchy(this, op); } void SetRotationOrder(ROTATIONORDER order) { BoCall(SetRotationOrder) (order); } ROTATIONORDER GetRotationOrder(void) const { return BoCall(GetRotationOrder) (); } UInt64 GetGUID() { return C4DOS.Bo->GetGUID(this); } }; class CameraObject : public BaseObject { private: CameraObject(); ~CameraObject(); public: Int32 GetProjection(void); Float GetFocus(void); Float GetZoom(void); Vector GetOffset(void); Float GetAperture(void); Bool SetProjection(Int32 projection); Bool SetFocus(Float v); Bool SetAperture(Float v); Bool SetZoom(Float zoom); Bool SetOffset(const Vector& offset); Int32 StereoGetCameraCount(BaseDocument* doc, BaseDraw* bd, RenderData* rd, Int32 flags) const; Bool StereoGetCameraInfo(BaseDocument* doc, BaseDraw* bd, RenderData* rd, Int32 n, StereoCameraInfo& info, Int32 flags) const; static CameraObject* Alloc(); static void Free(CameraObject*& bl); }; class PointObject : public BaseObject { private: PointObject(); ~PointObject(); public: BaseSelect* GetPointS(void); BaseSelect* GetPointH(void); const Vector* GetPointR(void) const { return (const Vector*)GetTagDataR(Tpoint); } Vector* GetPointW(void) { return (Vector*)GetTagDataW(Tpoint); } Int32 GetPointCount(void) const { return GetTagDataCount(Tpoint); } Float32* CalcVertexMap(BaseObject* modifier); Bool ResizeObject(Int32 pcnt); void IncreaseBoundingBox(Int32 cnt, Vector* v); // increases the bounding box of the object without making the object dirty }; struct CLine { Float t, pos; }; class LineObject : public PointObject { private: LineObject(); ~LineObject(); public: const Segment* GetSegmentR(void) { return (const Segment*)GetTagDataR(Tsegment); } Segment* GetSegmentW(void) { return (Segment*)GetTagDataW(Tsegment); } Int32 GetSegmentCount(void) { return GetTagDataCount(Tsegment); } const CLine* GetLineR(void) { return (const CLine*)GetTagDataR(Tline); } CLine* GetLineW(void) { return (CLine*)GetTagDataW(Tline); } Bool ResizeObject(Int32 pcnt, Int32 scnt); PolygonObject* Triangulate(Float regular, BaseThread* bt); static LineObject* Alloc(Int32 pcnt, Int32 scnt); static void Free(LineObject*& bl); }; #define POLYOBJECT_VBO_VERTEX 0x00000001 #define POLYOBJECT_VBO_PHONG_NORMAL 0x00000002 #define POLYOBJECT_VBO_POLYGON_NORMAL 0x00000004 #define POLYOBJECT_VBO_DISPLACE_NORMAL 0x00000008 #define POLYOBJECT_VBO_STICK_TEXTURE 0x00000010 #define POLYOBJECT_VBO_COLOR 0x00000020 class PolygonObject : public PointObject { private: PolygonObject(); ~PolygonObject(); public: BaseSelect* GetPolygonS(void); BaseSelect* GetPolygonH(void); BaseSelect* GetEdgeS(void); BaseSelect* GetEdgeH(void); BaseSelect* GetPhongBreak(void); const CPolygon* GetPolygonR(void) { return (const CPolygon*)GetTagDataR(Tpolygon); } CPolygon* GetPolygonW(void) { return (CPolygon*)GetTagDataW(Tpolygon); } Int32 GetPolygonCount(void) { return GetTagDataCount(Tpolygon); } Bool ResizeObject(Int32 pcnt, Int32 vcnt); Bool ResizeObject(Int32 pcnt, Int32 vcnt, Int32 ncnt); Bool ResizeObject(Int32 pcnt, Int32 vcnt, Int32 ncnt, Int32 vc_flags); BaseSelect* GetSelectedEdges(Neighbor* e, EDGESELECTIONTYPE ltype); BaseSelect* GetSelectedEdges(Neighbor* e, BaseSelect* sel); Bool SetSelectedEdges(Neighbor* e, BaseSelect* pSel, EDGESELECTIONTYPE ltype); Vector32* CreatePhongNormals(); Bool GetPolygonTranslationMap(Int32& ngoncnt, Int32*& polymap); // polygon index -> ngon index Bool GetNGonTranslationMap(Int32 ngoncnt, Int32* polymap, Int32**& ngons); // ngon index -> polygons Pgon* GetAndBuildNgon(void); Int32 GetNgonCount(void); void GetSelectedNgons(BaseSelect* sel); void GetHiddenNgons(BaseSelect* sel); NgonBase* GetNgonBase(); Bool ValidateEdgeSelection(BaseSelect* sel); Bool ValidateEdgeSelection(); Bool GetEdgeSelection(BaseSelect* sel, EDGESELECTIONTYPE type); void GetNgonEdgesCompact(UChar*& edges); UInt32 VBOInitUpdate(BaseDraw* bd); Bool VBOStartUpdate(BaseDraw* bd, GlVertexBufferAccessFlags access, Bool latemap); const GlVertexBufferAttributeInfo* VBOUpdateVectorGetAttribute(UInt32 flags); void VBOUpdateVector(Int32 i, const Vector32& v, const GlVertexBufferAttributeInfo* pInfo) { C4DOS.Bo->PyVBOUpdateVector(this, i, v, pInfo); } void VBOUpdateFaceVector(Int32 i, const Vector32& v, const GlVertexBufferAttributeInfo* pInfo) { C4DOS.Bo->PyVBOUpdateFaceVector(this, i, v, pInfo); } void VBOInvalidate() { C4DOS.Bo->PyVBOInvalidate(this); } void VBOEndUpdate(BaseDraw* bd); void VBOFreeUpdate(); static PolygonObject* Alloc(Int32 pcnt, Int32 vcnt); static void Free(PolygonObject*& bl); }; class SplineLengthData { private: SplineLengthData(); ~SplineLengthData(); public: Bool Init(SplineObject* op, Int32 segment = 0, const Vector* padr = nullptr); Float UniformToNatural(Float t); Float GetLength(void); Float GetSegmentLength(Int32 a, Int32 b); static SplineLengthData* Alloc(); static void Free(SplineLengthData*& bl); }; class SplineObject : public PointObject { private: SplineObject(); ~SplineObject(); public: SPLINETYPE GetInterpolationType(void) const; Bool IsClosed(void); Vector GetSplinePoint (Float t, Int32 segment = 0, const Vector* padr = nullptr); Vector GetSplineTangent(Float t, Int32 segment = 0, const Vector* padr = nullptr); Bool SetDefaultCoeff(void); Bool ResizeObject(Int32 pcnt, Int32 scnt); const Segment* GetSegmentR(void) { return (const Segment*)GetTagDataR(Tsegment); } Segment* GetSegmentW(void) { return (Segment*)GetTagDataW(Tsegment); } Int32 GetSegmentCount(void) { return GetTagDataCount(Tsegment); } const Tangent* GetTangentR(void) { return (Tangent*)GetTagDataR(Ttangent); } Tangent* GetTangentW(void) { return (Tangent*)GetTagDataW(Ttangent); } Int32 GetTangentCount(void) { return GetTagDataCount(Ttangent); } LineObject* GetLineObject(BaseDocument* doc, Float lod, BaseThread* thread = nullptr); static SplineObject* Alloc(Int32 pcnt, SPLINETYPE type); static void Free(SplineObject*& bl); }; BaseObject* GeneratePrimitive(BaseDocument* doc, Int32 type, const BaseContainer& bc, Float lod, Bool isoparm, BaseThread* bt = nullptr); BaseObject* GenerateSplinePrimitive(BaseDocument* doc, Int32 type, const BaseContainer& bc, Float lod, BaseThread* bt = nullptr); #define ToPoint(op) ((PointObject*)(op)) #define ToPoly(op) ((PolygonObject*)(op)) #define ToSpline(op) ((SplineObject*)(op)) inline Vector CalcFaceNormal(const Vector* padr, const CPolygon& v) { if (v.c == v.d) return !Cross((padr[v.b] - padr[v.a]), (padr[v.c] - padr[v.a])); else return !Cross((padr[v.b] - padr[v.d]), (padr[v.c] - padr[v.a])); } class Safety { private: ObjectSafety* os; public: Safety(void); ~Safety(void); Bool Init(BaseObject* op); void Detach(void); }; Int32 CalcLOD(Int32 val, Float lod, Int32 min, Int32 max); Bool DisjointMesh(PointObject* op); SplineObject* FitCurve(Vector* padr, Int32 pcnt, Float error, BaseThread* bt); Bool Triangulate(const Vector* padr, Int32 pcnt, CPolygon** vadr, Int32* vcnt); Bool TriangulateStandard(const Vector* padr, Int32 pcnt, Int32* list, Int32 lcnt, CPolygon*& vadr, Int32& vcnt, BaseThread* thread); Bool TriangulateRegular(const Vector* pinp, Int32 pinp_cnt, Int32* list, Int32 lcnt, Vector*& padr, Int32& pcnt, CPolygon*& vadr, Int32& vcnt, Float regular_width, BaseThread* thread); BaseObject* GenerateText(BaseContainer* cp, BaseThread* bt, Bool separate); Bool CheckDisplayFilter(BaseObject* op, Int32 filter); Int32 IntersectionTest(PolygonObject* op, BaseDraw* bd, Float x, Float y, const Matrix& mg, Float* z, MODELINGCOMMANDMODE mode, UChar* pPointSelect, Int32 lSelectCount); struct PolyInfo { Int32 face[4]; Int32 edge[4]; Char mark[4]; }; struct NgonNeighbor { struct NgonNeighborSegment { Int32 ptcnt; // number of points in this segment Int32* pts; // points Int32* edges; // edges Int32* nbr; // neighbor polygons }; Int32 segcnt; // number of segments (always >= 1) NgonNeighborSegment* segments; // always != nullptr }; class Neighbor { private: EnumerateEdges* ee; public: Neighbor(void); virtual ~Neighbor(void); virtual Bool Init(Int32 pcnt, const CPolygon* vadr, Int32 vcnt, BaseSelect* bs); void GetEdgePolys(Int32 a, Int32 b, Int32* first, Int32* second) { C4DOS.Nb->GetEdgePolys(ee, a, b, first, second); } void GetPointPolys(Int32 pnt, Int32** dadr, Int32* dcnt) { C4DOS.Nb->GetPointPolys(ee, pnt, dadr, dcnt); } Int32 GetEdgeCount(void); PolyInfo* GetPolyInfo(Int32 poly) { return C4DOS.Nb->GetPolyInfo(ee, poly); } Int32 GetNeighbor(Int32 a, Int32 b, Int32 poly); Bool GetNGons(PolygonObject* op, Int32& ngoncnt, NgonNeighbor*& ngons) { return C4DOS.Nb->GetNGons(ee, op, ngoncnt, ngons); } void Flush() { C4DOS.Nb->Free(ee); ee = nullptr; } void ResetAddress(const CPolygon* a_polyadr) { C4DOS.Nb->ResetAddress(ee, a_polyadr); } }; BaseObject* GetVirtualLineObject(BaseObject* op, HierarchyHelp* hh, const Matrix& mloc, Bool keep_spline, Bool recurse, Matrix* mres, Bool* dirty); UVWTag* GenerateUVW(BaseObject* op, const Matrix& opmg, TextureTag* tp, const Matrix& texopmg, BaseView* view); // special handling: light object void CutReal(BaseContainer& data, Int32 id, Float min, Float max); void CutVector(BaseContainer& data, Int32 id, Float min, Float max); Bool CalculateVisiblePoints(BaseDraw* bd, PolygonObject* op, Vector* padr, UChar* pset, Bool select_visibonly); // for triangulating #define POLY_TRIANG_CONSTRAINED_OUTLINE 1 // all points form the outline, the segments are ignored #define POLY_TRIANG_QUADS 8 // untriangulate where possible #define POLY_TRIANG_NGON 32 // must be set if an ngon is to be triangulated. #define POLY_TRIANG_FORCE_VORONOI 64 // force Voronoi triangulation #define POLY_TRIANG_FORCE_NGON (128 | POLY_TRIANG_NGON) // force special ngon triangulation #define POLY_TRIANG_FILL_HOLES 256 // fill segment holes (only used for ngon triangulation) #define TRIANGSTATE_SKIP_EDGE 1 #define TRIANGSTATE_MISSING_CONSTRAINT 2 class PolyTriangulate { private: PolyTriangulate(); ~PolyTriangulate(); public: static PolyTriangulate* Alloc(); static void Free(PolyTriangulate*& pTriang); // Don't store pPolys for later use. It will get invalid after the next Triangulate call // or when this class instance is destroyed. // Use TriangulateRelease if you need to store the result for a later use. // lConstraints and plConstrainedEdges are reserved for later use Bool Triangulate(const Vector* pvPoints, Int32 lPointCount, const Int32* plSegments, Int32 lSegCnt, CPolygon*& pPolys, Int32& lPolyCount, Int32 lFlags = 0, const Int32* plMap = nullptr, BaseThread* pThread = nullptr, Int32 lConstraints = 0, const Int32* plConstrainedEdges = nullptr); // You must call DeleteMem(pPolys) to free memory Bool TriangulateRelease(const Vector* pvPoints, Int32 lPointCount, const Int32* plSegments, Int32 lSegCnt, CPolygon*& pPolys, Int32& lPolyCount, Int32 lFlags = 0, const Int32* plMap = nullptr, BaseThread* pThread = nullptr, Int32 lConstraints = 0, const Int32* plConstrainedEdges = nullptr); #ifdef __FLOAT_32_BIT Bool Triangulate(const Vector64* pvPoints, Int32 lPointCount, const Int32* plSegments, Int32 lSegCnt, CPolygon*& pPolys, Int32& lPolyCount, Int32 lFlags = 0, const Int32* plMap = nullptr, BaseThread* pThread = nullptr, Int32 lConstraints = 0, const Int32* plConstrainedEdges = nullptr); Bool TriangulateRelease(const Vector64* pvPoints, Int32 lPointCount, const Int32* plSegments, Int32 lSegCnt, CPolygon*& pPolys, Int32& lPolyCount, Int32 lFlags = 0, const Int32* plMap = nullptr, BaseThread* pThread = nullptr, Int32 lConstraints = 0, const Int32* plConstrainedEdges = nullptr); #endif Bool HasIdentical(); void SetPolygonMatrix(Matrix64* m); UInt32 GetState(); }; #endif