/////////////////////////////////////////////////////////////
// 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
{
	LONG a,b,c,d;

public:
	CPolygon(void) {}
	CPolygon(LONG t_a, LONG t_b, LONG t_c) { a=t_a; b=t_b; c=d=t_c; }
	CPolygon(LONG t_a, LONG t_b, LONG t_c, LONG t_d) { a=t_a; b=t_b; c=t_c; d=t_d; }

	LONG &operator[](LONG index) const { return ((LONG*)this)[index&3]; }
	Bool IsTriangle(void) const { return (c == d); }
	LONG Find(LONG index) const { return ((d == index?3:(c == index?2:(b == index?1:(a == index?0:NOTOK))))); }
	LONG FindEdge(LONG index1, LONG 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(LONG edge, LONG &a, LONG &b) const
	{
		a = ((LONG*)this)[edge&3];
		b = ((LONG*)this)[(edge+1)&3];
	}
	LONG &GetPoint(LONG index) const { if (c == d) return ((LONG*)this)[(index+(3<<24))%3]; return ((LONG*)this)[index&3]; }
};

struct Tangent
{
	Vector vl,vr;
};

struct Segment
{
	LONG	cnt;
	Bool	closed;
};

struct ObjectColorProperties
{
	LONG		usecolor;
	Vector	color;
	Bool		xray;
};

class HierarchyHelp
{
	private:
		HierarchyHelp();
		~HierarchyHelp();
	public:
		Real 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 ); }

		Real	 GetVisibility(Real 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); }

		LONG	 GetEditorMode(void);
		void   SetEditorMode(LONG mode);

		LONG	 GetRenderMode(void);
		void   SetRenderMode(LONG mode);

		Bool	 GetDeformMode(void);
		void   SetDeformMode(Bool mode);

		LONG   GetUniqueIP(void);
		void	 SetUniqueIP(LONG 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(LONG type, LONG nr=0) { return C4DOS.Bo->GetTag(this,type,nr); }
		const void	*GetTagDataR(LONG type, LONG nr=0) const { return C4DOS.Bo->GetTagDataR(this,type,nr); }
		void				*GetTagDataW(LONG type, LONG nr=0) { return C4DOS.Bo->GetTagData(this,type,nr); }
		LONG				GetTagDataCount(LONG type) const { return C4DOS.Bo->GetTagDataCount(this,type); }
		BaseTag			*MakeTag (LONG type, BaseTag *pred=NULL);
		VariableTag *MakeVariableTag(LONG type, LONG count, BaseTag *pred=NULL);
		void				InsertTag(BaseTag *tp, BaseTag *pred=NULL);
		void        KillTag (LONG type, LONG nr=0);

		BaseObject	*GetCache(HierarchyHelp *hh=NULL) { 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, LONG visible, LONG variable, LONG hierarchical, AliasTrans *trans);

		Bool				SetPhong(Bool on, Bool anglelimit, Real 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);

		LONG				GetHighlightHandle(BaseDraw *bd) { return C4DOS.Bo->GetHighlightHandle(this,bd); }

		static BaseObject *Alloc(LONG 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 ); }
  
    LULONG GetGUID() { return C4DOS.Bo->GetGUID(this); }
};

class CameraObject: public BaseObject
{
	private:
		CameraObject();
		~CameraObject();
	public:
		LONG				GetProjection(void);
		Real				GetFocus(void);
		Real				GetZoom(void);
		Vector			GetOffset(void);
		Real				GetAperture(void);
		Bool				SetProjection(LONG projection);
		Bool				SetFocus(Real v);
		Bool				SetAperture(Real v);
		Bool				SetZoom(Real zoom);
		Bool				SetOffset(const Vector &offset);

		LONG				StereoGetCameraCount(BaseDocument* doc, BaseDraw* bd, RenderData* rd, LONG flags) const;
		Bool				StereoGetCameraInfo(BaseDocument* doc, BaseDraw* bd, RenderData* rd, LONG n, StereoCameraInfo &info, LONG 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); }
		LONG					GetPointCount(void) const { return GetTagDataCount(Tpoint); }

		SReal					*CalcVertexMap(BaseObject *modifier);

		Bool					ResizeObject(LONG pcnt);
		void					IncreaseBoundingBox(LONG cnt, Vector* v); // increases the bounding box of the object without making the object dirty
};

struct CLine
{
	Real 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); }
		LONG					GetSegmentCount(void) { return GetTagDataCount(Tsegment); }

		const CLine		*GetLineR(void)  { return (const CLine*)GetTagDataR(Tline); }
		CLine					*GetLineW(void) { return (CLine*)GetTagDataW(Tline); }

		Bool					ResizeObject(LONG pcnt, LONG scnt);
		PolygonObject *Triangulate(Real regular, BaseThread *bt);

		static LineObject *Alloc(LONG pcnt, LONG 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); }
		LONG				GetPolygonCount(void) { return GetTagDataCount(Tpolygon); }

		Bool				ResizeObject(LONG pcnt, LONG vcnt);
		Bool				ResizeObject(LONG pcnt, LONG vcnt, LONG ncnt);
		Bool				ResizeObject(LONG pcnt, LONG vcnt, LONG ncnt, LONG vc_flags);

		BaseSelect* GetSelectedEdges(Neighbor *e, EDGESELECTIONTYPE ltype);
		BaseSelect* GetSelectedEdges(Neighbor *e, BaseSelect* sel);
		Bool SetSelectedEdges(Neighbor *e, BaseSelect* pSel, EDGESELECTIONTYPE ltype);
		SVector *CreatePhongNormals();
		Bool GetPolygonTranslationMap(LONG &ngoncnt, LONG *&polymap); // polygon index -> ngon index
		Bool GetNGonTranslationMap(LONG ngoncnt, LONG *polymap, LONG **&ngons); // ngon index -> polygons
		Pgon *GetAndBuildNgon(void);
		LONG 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);

		ULONG VBOInitUpdate(BaseDraw* bd);
		Bool VBOStartUpdate(BaseDraw* bd, GlVertexBufferAccessFlags access, Bool latemap);
		const GlVertexBufferAttributeInfo* VBOUpdateVectorGetAttribute(ULONG flags);
		void VBOUpdateVector(LONG i, const SVector &v, const GlVertexBufferAttributeInfo* pInfo) { C4DOS.Bo->PyVBOUpdateVector(this, i, v, pInfo); }
		void VBOUpdateFaceVector(LONG i, const SVector &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(LONG pcnt, LONG vcnt);
		static void Free(PolygonObject *&bl);
};

class SplineLengthData
{
	private:
		SplineLengthData();
		~SplineLengthData();
	public:
		Bool Init(SplineObject *op, LONG segment=0, const Vector *padr=NULL);

		Real UniformToNatural(Real t);
		Real GetLength(void);
		Real GetSegmentLength(LONG a, LONG 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  (Real t, LONG segment=0, const Vector *padr=NULL);
		Vector				GetSplineTangent(Real t, LONG segment=0, const Vector *padr=NULL);
		Bool					SetDefaultCoeff(void);
		Bool					ResizeObject(LONG pcnt, LONG scnt);

		const Segment	*GetSegmentR(void)  { return (const Segment*)GetTagDataR(Tsegment); }
		Segment				*GetSegmentW(void) { return (Segment*)GetTagDataW(Tsegment); }
		LONG					GetSegmentCount(void) { return GetTagDataCount(Tsegment); }

		const Tangent	*GetTangentR(void)  {	return (Tangent*)GetTagDataR(Ttangent); }
		Tangent				*GetTangentW(void) {	return (Tangent*)GetTagDataW(Ttangent); }
		LONG					GetTangentCount(void) {	return GetTagDataCount(Ttangent); }

		LineObject   *GetLineObject(BaseDocument *doc, Real lod, BaseThread *thread=NULL);

		static SplineObject *Alloc(LONG pcnt, SPLINETYPE type);
		static void Free(SplineObject *&bl);
};

BaseObject *GeneratePrimitive(BaseDocument *doc, LONG type, const BaseContainer &bc, Real lod, Bool isoparm, BaseThread *bt=NULL);
BaseObject *GenerateSplinePrimitive(BaseDocument *doc, LONG type, const BaseContainer &bc, Real lod, BaseThread *bt=NULL);

#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 !((padr[v.b]-padr[v.a])%(padr[v.c]-padr[v.a]));
	else
		return !((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);
};

LONG CalcLOD(LONG val, Real lod, LONG min, LONG max);
Bool DisjointMesh(PointObject *op);

SplineObject *FitCurve(Vector *padr, LONG pcnt, Real error, BaseThread *bt);
Bool Triangulate(const Vector *padr, LONG pcnt, CPolygon **vadr, LONG *vcnt);
Bool TriangulateStandard(const Vector *padr, LONG pcnt, LONG *list, LONG lcnt, CPolygon *&vadr, LONG &vcnt, BaseThread *thread);
Bool TriangulateRegular(const Vector *pinp, LONG pinp_cnt, LONG *list, LONG lcnt, Vector *&padr, LONG &pcnt, CPolygon *&vadr, LONG &vcnt, Real regular_width, BaseThread *thread);
BaseObject *GenerateText(BaseContainer *cp, BaseThread *bt, Bool separate);
Bool CheckDisplayFilter(BaseObject *op, LONG filter);
LONG IntersectionTest(PolygonObject *op, BaseDraw *bd, Real x, Real y, const Matrix &mg, Real *z, MODELINGCOMMANDMODE mode, UCHAR *pPointSelect, LONG lSelectCount);

struct PolyInfo
{
	LONG face[4];
	LONG edge[4];
	CHAR mark[4];
};

struct NgonNeighbor
{
  struct NgonNeighborSegment
  {
    LONG ptcnt;   // number of points in this segment
    LONG *pts;		// points
    LONG *edges;	// edges
    LONG *nbr;		// neighbor polygons
  };
  LONG segcnt; // number of segments (always >= 1)
  NgonNeighborSegment* segments; // always != NULL
};

class Neighbor
{
	private:
		EnumerateEdges *ee;
	public:
		Neighbor(void);
		virtual ~Neighbor(void);

		virtual Bool Init(LONG pcnt, const CPolygon *vadr, LONG vcnt, BaseSelect *bs);
		void GetEdgePolys(LONG a, LONG b,LONG *first,LONG *second) { C4DOS.Nb->GetEdgePolys(ee,a,b,first,second); }
		void GetPointPolys(LONG pnt, LONG **dadr, LONG *dcnt)  { C4DOS.Nb->GetPointPolys(ee,pnt,dadr,dcnt); }
		LONG GetEdgeCount(void);
		PolyInfo *GetPolyInfo(LONG poly) { return C4DOS.Nb->GetPolyInfo(ee,poly); }
		LONG GetNeighbor(LONG a, LONG b, LONG poly);
		Bool GetNGons(PolygonObject* op, LONG &ngoncnt, NgonNeighbor *&ngons) { return C4DOS.Nb->GetNGons(ee, op, ngoncnt, ngons); }
		void Flush() { C4DOS.Nb->Free(ee); ee=NULL; }
		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, LONG id, Real min, Real max);
void CutVector(BaseContainer &data, LONG id, Real min, Real 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, LONG lPointCount, const LONG* plSegments, LONG lSegCnt,
			CPolygon*& pPolys, LONG& lPolyCount, LONG lFlags = 0, const LONG* plMap = NULL, BaseThread* pThread = NULL,
			LONG lConstraints = 0, const LONG* plConstrainedEdges = NULL);
		// You must call GeFree(pPolys) to free memory
		Bool TriangulateRelease(const Vector* pvPoints, LONG lPointCount, const LONG* plSegments, LONG lSegCnt,
			CPolygon*& pPolys, LONG& lPolyCount, LONG lFlags = 0, const LONG* plMap = NULL, BaseThread* pThread = NULL,
			LONG lConstraints = 0, const LONG* plConstrainedEdges = NULL);

#ifdef __SINGLEPRECISION
		Bool Triangulate(const LVector* pvPoints, LONG lPointCount, const LONG* plSegments, LONG lSegCnt,
			CPolygon*& pPolys, LONG& lPolyCount, LONG lFlags = 0, const LONG* plMap = NULL, BaseThread* pThread = NULL,
			LONG lConstraints = 0, const LONG* plConstrainedEdges = NULL);

		Bool TriangulateRelease(const LVector* pvPoints, LONG lPointCount, const LONG* plSegments, LONG lSegCnt,
			CPolygon*& pPolys, LONG& lPolyCount, LONG lFlags = 0, const LONG* plMap = NULL, BaseThread* pThread = NULL,
			LONG lConstraints = 0, const LONG* plConstrainedEdges = NULL);
#endif

		Bool HasIdentical();
		void SetPolygonMatrix(LMatrix* m);
		ULONG GetState();
};

#endif
