22 #ifndef __ND_POLYHEDRA_H__
23 #define __ND_POLYHEDRA_H__
25 #include "ndCoreStdafx.h"
32 #include "ndClassAlloc.h"
41 typedef ndInt64 ndEdgeKey;
47 ndEdge (ndInt32 vertex, ndInt32 face, ndUnsigned64 userdata = 0);
50 ndInt32 m_incidentVertex;
51 ndInt32 m_incidentFace;
52 ndUnsigned64 m_userData;
57 } D_GCC_NEWTON_ALIGN_32 ;
70 :m_key(ndUnsigned64(key))
74 ndPairKey(ndInt32 keyHigh, ndInt32 keyLow)
75 :m_keyLow(ndUnsigned32 (keyLow))
76 ,m_keyHigh(ndUnsigned32 (keyHigh))
80 ndInt64 GetVal()
const
82 return ndInt64(m_key);
85 ndInt32 GetLowKey()
const
87 return ndInt32(m_keyLow);
90 ndInt32 GetHighKey()
const
92 return ndInt32(m_keyHigh);
95 bool operator<(
const ndPairKey& key)
const
97 return m_key < key.m_key;
100 bool operator>(
const ndPairKey& key)
const
102 return m_key > key.m_key;
112 ndUnsigned32 m_keyLow;
113 ndUnsigned32 m_keyHigh;
122 virtual bool ReportProgress(ndFloat32)
const {
return true;}
124 virtual void BeginFace();
125 ndEdge* AddFace (ndInt32 v0, ndInt32 v1, ndInt32 v2);
126 ndEdge* AddFace (ndInt32 count,
const ndInt32*
const index);
127 D_CORE_API
ndEdge* AddFace (ndInt32 count,
const ndInt32*
const index,
const ndInt64*
const userdata);
128 D_CORE_API
virtual bool EndFace ();
129 D_CORE_API
virtual void DeleteFace(
ndEdge*
const edge);
131 D_CORE_API ndInt32 GetFaceCount()
const;
132 ndInt32 GetEdgeCount()
const;
133 ndInt32 GetLastVertexIndex()
const;
135 ndInt32 IncLRU()
const;
136 ndInt32 GetLRU()
const;
137 void SetLRU(ndInt32 lru)
const;
139 ndEdge* FindEdge (ndInt32 v0, ndInt32 v1)
const;
140 ndNode* FindEdgeNode (ndInt32 v0, ndInt32 v1)
const;
142 D_CORE_API
ndEdge* AddHalfEdge (ndInt32 v0, ndInt32 v1);
143 D_CORE_API
void DeleteEdge (
ndEdge*
const edge);
144 void DeleteEdge (ndInt32 v0, ndInt32 v1);
148 D_CORE_API
bool FlipEdge (
ndEdge*
const edge);
149 D_CORE_API
ndEdge* SpliteEdge (ndInt32 newIndex,
ndEdge*
const edge);
150 D_CORE_API
ndBigVector FaceNormal (
const ndEdge*
const face,
const ndFloat64*
const vertex, ndInt32 strideInBytes)
const;
152 D_CORE_API
void SavePLY(
const char*
const fileName,
const ndFloat64*
const vertex, ndInt32 strideInBytes)
const;
154 void BeginConectedSurface()
const;
155 D_CORE_API
bool GetConectedSurface (
ndPolyhedra &polyhedra)
const;
156 void EndConectedSurface()
const;
158 D_CORE_API
ndMatrix CalculateSphere(
ndBigVector& size,
const ndFloat64*
const vertex, ndInt32 strideInBytes)
const;
160 D_CORE_API
void ChangeEdgeIncidentVertex (
ndEdge*
const edge, ndInt32 newIndex);
161 D_CORE_API
void DeleteDegenerateFaces (
const ndFloat64*
const pool, ndInt32 dstStrideInBytes, ndFloat64 minArea);
163 D_CORE_API
bool Optimize (
const ndFloat64*
const pool, ndInt32 strideInBytes, ndFloat64 tol, ndInt32 maxFaceCount = 1<<28);
164 D_CORE_API
void Triangulate (
const ndFloat64*
const vertex, ndInt32 strideInBytes,
ndPolyhedra*
const leftOversOut);
165 D_CORE_API
void ConvexPartition (
const ndFloat64*
const vertex, ndInt32 strideInBytes,
ndPolyhedra*
const leftOversOut);
166 D_CORE_API
bool IsFaceConvex(
ndEdge*
const face,
const ndFloat64*
const pool, ndInt32 strideInBytes)
const;
170 D_CORE_API
bool PolygonizeFace(
ndEdge*
const face,
const ndFloat64*
const pool, ndInt32 stride);
171 D_CORE_API
bool TriangulateFace(
ndEdge*
const face,
const ndFloat64*
const pool, ndInt32 stride);
174 void RefineTriangulation (
const ndFloat64*
const vertex, ndInt32 stride);
175 void RefineTriangulation (
const ndFloat64*
const vertex, ndInt32 stride,
const ndBigVector& normal, ndInt32 perimeterCount,
ndEdge**
const perimeter);
176 void OptimizeTriangulation (
const ndFloat64*
const vertex, ndInt32 strideInBytes);
177 void RemoveInteriorEdges (
ndPolyhedra& polyhedraOut,
const ndFloat64*
const vertex, ndInt32 strideInBytes);
178 void MarkAdjacentCoplanarFaces (
ndPolyhedra& polyhedraOut,
ndEdge*
const face,
const ndFloat64*
const pool, ndInt32 strideInBytes);
182 void RemoveHalfEdge (
ndEdge*
const edge);
185 ndFloat64 EdgePenalty (
const ndBigVector*
const pool,
ndEdge*
const edge, ndFloat64 dist)
const;
191 static ndInt32 GetInteriorDiagonals (
ndPolyhedra& polyhedra,
ndEdge**
const diagonals, ndInt32 maxCount);
192 static ndBigPlane UnboundedLoopPlane (ndInt32 i0, ndInt32 i1, ndInt32 i2,
const ndBigVector*
const pool);
193 static void RemoveOuterColinearEdges(
ndPolyhedra& flatFace,
const ndFloat64*
const vertex, ndInt32 stride);
194 static void RemoveInteriorColinearEdges(
ndPolyhedra& flatFace,
const ndFloat64*
const vertex, ndInt32 stride);
195 static bool IsEssensialDiagonal (
ndEdge*
const diagonal,
const ndBigVector& normal,
const ndFloat64*
const pool, ndInt32 stride);
196 static bool IsEssensialPointDiagonal (
ndEdge*
const diagonal,
const ndBigVector& normal,
const ndFloat64*
const pool, ndInt32 stride);
198 mutable ndInt32 m_baseMark;
199 mutable ndInt32 m_edgeMark;
200 mutable ndInt32 m_faceSecuence;
201 friend class dPolyhedraDescriptor;
204 inline ndEdge::ndEdge ()
208 inline ndEdge::ndEdge (ndInt32 vertex, ndInt32 face, ndUnsigned64 userdata)
209 :m_incidentVertex(vertex)
210 ,m_incidentFace(face)
211 ,m_userData(userdata)
219 inline ndEdge::~ndEdge ()
223 inline void ndPolyhedra::BeginFace ()
227 inline ndEdge* ndPolyhedra::AddFace (ndInt32 count,
const ndInt32*
const index)
229 return AddFace (count, index,
nullptr);
232 inline ndEdge* ndPolyhedra::AddFace (ndInt32 v0, ndInt32 v1, ndInt32 v2)
239 return AddFace (3, vertex,
nullptr);
242 inline ndInt32 ndPolyhedra::GetEdgeCount()
const
245 ndInt32 edgeCount = 0;
246 Iterator iter(*
this);
247 for (iter.Begin(); iter; iter ++)
251 ndAssert (edgeCount == GetCount());;
256 inline ndPolyhedra::ndPolyhedra()
264 inline ndInt32 ndPolyhedra::GetLastVertexIndex()
const
266 ndInt32 maxVertexIndex = -1;
267 Iterator iter(*
this);
268 for (iter.Begin(); iter; iter ++)
270 const ndEdge*
const edge = &(*iter);
271 if (edge->m_incidentVertex > maxVertexIndex)
273 maxVertexIndex = edge->m_incidentVertex;
276 return maxVertexIndex + 1;
279 inline ndInt32 ndPolyhedra::IncLRU()
const
282 ndAssert (m_edgeMark < 0x7fffffff);
286 inline ndInt32 ndPolyhedra::GetLRU()
const
291 inline void ndPolyhedra::SetLRU(ndInt32 lru)
const
293 if (lru > m_edgeMark)
299 inline void ndPolyhedra::BeginConectedSurface()
const
301 m_baseMark = IncLRU();
304 inline void ndPolyhedra::EndConectedSurface()
const
308 inline ndPolyhedra::ndNode* ndPolyhedra::FindEdgeNode (ndInt32 i0, ndInt32 i1)
const
310 ndPairKey key (i0, i1);
311 return Find (key.GetVal());
314 inline ndEdge *ndPolyhedra::FindEdge (ndInt32 i0, ndInt32 i1)
const
316 ndNode*
const node = FindEdgeNode (i0, i1);
317 return node ? &node->GetInfo() :
nullptr;
320 inline void ndPolyhedra::DeleteEdge (ndInt32 v0, ndInt32 v1)
322 ndPairKey pairKey (v0, v1);
323 ndNode*
const node = Find(pairKey.GetVal());
324 ndEdge*
const edge = node ? &node->GetInfo() :
nullptr;