Newton Dynamics  4.00
dPolyhedra.h
1 /* Copyright (c) <2003-2019> <Julio Jerez, Newton Game Dynamics>
2 *
3 * This software is provided 'as-is', without any express or implied
4 * warranty. In no event will the authors be held liable for any damages
5 * arising from the use of this software.
6 *
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely, subject to the following restrictions:
10 *
11 * 1. The origin of this software must not be misrepresented; you must not
12 * claim that you wrote the original software. If you use this software
13 * in a product, an acknowledgment in the product documentation would be
14 * appreciated but is not required.
15 *
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 *
19 * 3. This notice may not be removed or altered from any source distribution.
20 */
21 
22 #ifndef __D_POLYHEDRA_H__
23 #define __D_POLYHEDRA_H__
24 
25 #include "dCoreStdafx.h"
26 #include "dTypes.h"
27 #include "dList.h"
28 #include "dTree.h"
29 #include "dHeap.h"
30 #include "dHeap.h"
31 #include "dDebug.h"
32 #include "dClassAlloc.h"
33 
34 class dEdge;
35 //class dgObb;
36 class dMatrix;
37 class dBigPlane;
38 class dBigVector;
39 class dPolyhedra;
41 
42 typedef dInt64 dEdgeKey;
43 
44 class dEdge
45 {
46  public:
47  dEdge ();
48  dEdge (dInt32 vertex, dInt32 face, dUnsigned64 userdata = 0);
49  ~dEdge ();
50 
51  dInt32 m_incidentVertex;
52  dInt32 m_incidentFace;
53  dUnsigned64 m_userData;
54  dEdge* m_next;
55  dEdge* m_prev;
56  dEdge* m_twin;
57  dInt32 m_mark;
58 } D_GCC_NEWTON_ALIGN_32 ;
59 
60 class dPolyhedra: public dClassAlloc, public dTree <dEdge, dEdgeKey>
61 {
62  public:
63  class dgPairKey
64  {
65  public:
66  dgPairKey()
67  {
68  }
69 
70  dgPairKey(dInt64 key)
71  :m_key(dUnsigned64(key))
72  {
73  }
74 
75  dgPairKey(dInt32 keyHigh, dInt32 keyLow)
76  :m_keyLow(dUnsigned32 (keyLow))
77  ,m_keyHigh(dUnsigned32 (keyHigh))
78  {
79  }
80 
81  dInt64 GetVal() const
82  {
83  return dInt64(m_key);
84  }
85 
86  dInt32 GetLowKey() const
87  {
88  return dInt32(m_keyLow);
89  }
90 
91  dInt32 GetHighKey() const
92  {
93  return dInt32(m_keyHigh);
94  }
95 
96  bool operator<(const dgPairKey& key) const
97  {
98  return m_key < key.m_key;
99  }
100 
101  bool operator>(const dgPairKey& key) const
102  {
103  return m_key > key.m_key;
104  }
105 
106 
107  private:
108  union
109  {
110  dUnsigned64 m_key;
111  struct
112  {
113  dUnsigned32 m_keyLow;
114  dUnsigned32 m_keyHigh;
115  };
116  };
117  };
118 
119  dPolyhedra ();
120  D_CORE_API dPolyhedra (const dPolyhedra &polyhedra);
121  D_CORE_API virtual ~dPolyhedra();
122 
123  virtual bool ReportProgress(dFloat32 percentProgress) const { return true;}
124 
125  virtual void BeginFace();
126  dEdge* AddFace (dInt32 v0, dInt32 v1, dInt32 v2);
127  dEdge* AddFace (dInt32 count, const dInt32* const index);
128  D_CORE_API dEdge* AddFace (dInt32 count, const dInt32* const index, const dInt64* const userdata);
129  D_CORE_API virtual bool EndFace ();
130  D_CORE_API virtual void DeleteFace(dEdge* const edge);
131 
132  D_CORE_API dInt32 GetFaceCount() const;
133  dInt32 GetEdgeCount() const;
134  dInt32 GetLastVertexIndex() const;
135 
136  dInt32 IncLRU() const;
137  dInt32 GetLRU() const;
138  void SetLRU(dInt32 lru) const;
139 
140  dEdge* FindEdge (dInt32 v0, dInt32 v1) const;
141  dTreeNode* FindEdgeNode (dInt32 v0, dInt32 v1) const;
142 
143  D_CORE_API dEdge* AddHalfEdge (dInt32 v0, dInt32 v1);
144  D_CORE_API void DeleteEdge (dEdge* const edge);
145  void DeleteEdge (dInt32 v0, dInt32 v1);
146 
147  D_CORE_API dEdge* ConnectVertex (dEdge* const e0, dEdge* const e1);
148 
149  D_CORE_API bool FlipEdge (dEdge* const edge);
150  D_CORE_API dEdge* SpliteEdge (dInt32 newIndex, dEdge* const edge);
151  D_CORE_API dBigVector FaceNormal (const dEdge* const face, const dFloat64* const vertex, dInt32 strideInBytes) const;
152 
153  D_CORE_API void SavePLY(const char* const fileName, const dFloat64* const vertex, dInt32 strideInBytes) const;
154 
155  void BeginConectedSurface() const;
156  D_CORE_API bool GetConectedSurface (dPolyhedra &polyhedra) const;
157  void EndConectedSurface() const;
158 
159 // dgObb CalculateSphere (const dFloat64* const vertex, dInt32 strideInBytes, const dMatrix* const basis = nullptr) const;
160  D_CORE_API void ChangeEdgeIncidentVertex (dEdge* const edge, dInt32 newIndex);
161  D_CORE_API void DeleteDegenerateFaces (const dFloat64* const pool, dInt32 dstStrideInBytes, dFloat64 minArea);
162 
163  D_CORE_API bool Optimize (const dFloat64* const pool, dInt32 strideInBytes, dFloat64 tol, dInt32 maxFaceCount = 1<<28);
164  D_CORE_API void Triangulate (const dFloat64* const vertex, dInt32 strideInBytes, dPolyhedra* const leftOversOut);
165  D_CORE_API void ConvexPartition (const dFloat64* const vertex, dInt32 strideInBytes, dPolyhedra* const leftOversOut);
166  D_CORE_API bool IsFaceConvex(dEdge* const face, const dFloat64* const pool, dInt32 strideInBytes) const;
167 
168  protected:
169  D_CORE_API dEdge* CollapseEdge(dEdge* const edge);
170  D_CORE_API bool PolygonizeFace(dEdge* const face, const dFloat64* const pool, dInt32 stride);
171  D_CORE_API bool TriangulateFace(dEdge* const face, const dFloat64* const pool, dInt32 stride);
172 
173  private:
174  void RefineTriangulation (const dFloat64* const vertex, dInt32 stride);
175  void RefineTriangulation (const dFloat64* const vertex, dInt32 stride, const dBigVector& normal, dInt32 perimeterCount, dEdge** const perimeter);
176  void OptimizeTriangulation (const dFloat64* const vertex, dInt32 strideInBytes);
177  void RemoveInteriorEdges (dPolyhedra& polyhedraOut, const dFloat64* const vertex, dInt32 strideInBytes);
178  void MarkAdjacentCoplanarFaces (dPolyhedra& polyhedraOut, dEdge* const face, const dFloat64* const pool, dInt32 strideInBytes);
179  dEdge* FindEarTip (dEdge* const face, const dFloat64* const pool, dInt32 stride, dDownHeap<dEdge*, dFloat64>& heap, const dBigVector &normal) const;
180  dEdge* TriangulateFace (dEdge* const face, const dFloat64* const pool, dInt32 stride, dDownHeap<dEdge*, dFloat64>& heap, dBigVector* const faceNormalOut);
181 
182  void RemoveHalfEdge (dEdge* const edge);
183  dEdge* OptimizeCollapseEdge (dEdge* const edge);
184  bool IsOkToCollapse (const dBigVector* const pool, dEdge* const edge) const;
185  dFloat64 EdgePenalty (const dBigVector* const pool, dEdge* const edge, dFloat64 dist) const;
186  dBigPlane EdgePlane (dInt32 i0, dInt32 i1, dInt32 i2, const dBigVector* const pool) const;
187  void CalculateAllMetrics (dVertexCollapseVertexMetric* const table, const dBigVector* const pool) const;
188  void CalculateVertexMetrics (dVertexCollapseVertexMetric* const table, const dBigVector* const pool, dEdge* const edge) const;
189  dEdge* BestEdgePolygonizeFace(const dBigVector& normal, dEdge* const edge, const dFloat64* const pool, dInt32 stride, const dBigVector& point) const;
190 
191  static dInt32 GetInteriorDiagonals (dPolyhedra& polyhedra, dEdge** const diagonals, dInt32 maxCount);
192  static dBigPlane UnboundedLoopPlane (dInt32 i0, dInt32 i1, dInt32 i2, const dBigVector* const pool);
193  static void RemoveOuterColinearEdges(dPolyhedra& flatFace, const dFloat64* const vertex, dInt32 stride);
194  static void RemoveInteriorColinearEdges(dPolyhedra& flatFace, const dFloat64* const vertex, dInt32 stride);
195  static bool IsEssensialDiagonal (dEdge* const diagonal, const dBigVector& normal, const dFloat64* const pool, dInt32 stride);
196  static bool IsEssensialPointDiagonal (dEdge* const diagonal, const dBigVector& normal, const dFloat64* const pool, dInt32 stride);
197 
198  mutable dInt32 m_baseMark;
199  mutable dInt32 m_edgeMark;
200  mutable dInt32 m_faceSecuence;
201  friend class dPolyhedraDescriptor;
202 };
203 
204 inline dEdge::dEdge ()
205 {
206 }
207 
208 inline dEdge::dEdge (dInt32 vertex, dInt32 face, dUnsigned64 userdata)
209  :m_incidentVertex(vertex)
210  ,m_incidentFace(face)
211  ,m_userData(userdata)
212  ,m_next(nullptr)
213  ,m_prev(nullptr)
214  ,m_twin(nullptr)
215  ,m_mark(0)
216 {
217 }
218 
219 inline dEdge::~dEdge ()
220 {
221 }
222 
223 inline void dPolyhedra::BeginFace ()
224 {
225 }
226 
227 inline dEdge* dPolyhedra::AddFace (dInt32 count, const dInt32* const index)
228 {
229  return AddFace (count, index, nullptr);
230 }
231 
232 inline dEdge* dPolyhedra::AddFace (dInt32 v0, dInt32 v1, dInt32 v2)
233 {
234  dInt32 vertex[3];
235 
236  vertex [0] = v0;
237  vertex [1] = v1;
238  vertex [2] = v2;
239  return AddFace (3, vertex, nullptr);
240 }
241 
242 inline dInt32 dPolyhedra::GetEdgeCount() const
243 {
244 #ifdef _DEBUG
245  dInt32 edgeCount = 0;
246  Iterator iter(*this);
247  for (iter.Begin(); iter; iter ++)
248  {
249  edgeCount ++;
250  }
251  dAssert (edgeCount == GetCount());;
252 #endif
253  return GetCount();
254 }
255 
256 inline dPolyhedra::dPolyhedra()
257  :dClassAlloc()
258  ,dTree <dEdge, dInt64>()
259  ,m_baseMark(0)
260  ,m_edgeMark(0)
261  ,m_faceSecuence(0)
262 {
263 }
264 
265 inline dInt32 dPolyhedra::GetLastVertexIndex() const
266 {
267  dInt32 maxVertexIndex = -1;
268  Iterator iter(*this);
269  for (iter.Begin(); iter; iter ++)
270  {
271  const dEdge* const edge = &(*iter);
272  if (edge->m_incidentVertex > maxVertexIndex)
273  {
274  maxVertexIndex = edge->m_incidentVertex;
275  }
276  }
277  return maxVertexIndex + 1;
278 }
279 
280 inline dInt32 dPolyhedra::IncLRU() const
281 {
282  m_edgeMark ++;
283  dAssert (m_edgeMark < 0x7fffffff);
284  return m_edgeMark;
285 }
286 
287 inline dInt32 dPolyhedra::GetLRU() const
288 {
289  return m_edgeMark;
290 }
291 
292 inline void dPolyhedra::SetLRU(dInt32 lru) const
293 {
294  if (lru > m_edgeMark)
295  {
296  m_edgeMark = lru;
297  }
298 }
299 
300 inline void dPolyhedra::BeginConectedSurface() const
301 {
302  m_baseMark = IncLRU();
303 }
304 
305 inline void dPolyhedra::EndConectedSurface() const
306 {
307 }
308 
309 inline dPolyhedra::dTreeNode* dPolyhedra::FindEdgeNode (dInt32 i0, dInt32 i1) const
310 {
311  dgPairKey key (i0, i1);
312  return Find (key.GetVal());
313 }
314 
315 inline dEdge *dPolyhedra::FindEdge (dInt32 i0, dInt32 i1) const
316 {
317  dTreeNode* const node = FindEdgeNode (i0, i1);
318  return node ? &node->GetInfo() : nullptr;
319 }
320 
321 inline void dPolyhedra::DeleteEdge (dInt32 v0, dInt32 v1)
322 {
323  dgPairKey pairKey (v0, v1);
324  dTreeNode* const node = Find(pairKey.GetVal());
325  dEdge* const edge = node ? &node->GetInfo() : nullptr;
326  if (!edge)
327  {
328  return;
329  }
330  DeleteEdge (edge);
331 }
332 
333 #endif
334 
dDownHeap
Definition: dHeap.h:73
dTree
Definition: dTree.h:80
dEdge
Definition: dPolyhedra.h:45
dClassAlloc
Base class for providing memory allocation for all other engine classes.
Definition: dClassAlloc.h:29
dVertexCollapseVertexMetric
Definition: dPolyhedra.cpp:90
dBigVector
Definition: dVectorArmNeon.h:1521
dPolyhedra::dgPairKey
Definition: dPolyhedra.h:64
dBigPlane
Definition: dPlane.h:50
dMatrix
Definition: dMatrix.h:39
dPolyhedra
Definition: dPolyhedra.h:61