Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
TriStrip_tri_stripper.h
Go to the documentation of this file.
1 // tri_stripper.h: interface for the tri_stripper class.
2 //
4 //
5 // Copyright (C) 2002 Tanguy Fautré.
6 //
7 // This software is provided 'as-is', without any express or implied
8 // warranty. In no event will the authors be held liable for any damages
9 // arising from the use of this software.
10 //
11 // Permission is granted to anyone to use this software for any purpose,
12 // including commercial applications, and to alter it and redistribute it
13 // freely, subject to the following restrictions:
14 //
15 // 1. The origin of this software must not be misrepresented; you must not
16 // claim that you wrote the original software. If you use this software
17 // in a product, an acknowledgment in the product documentation would be
18 // appreciated but is not required.eap_array.h TriStrip_tri_stripper.cpp TriStrip_tri_stripper.h
19 
20 // 2. Altered source versions must be plainly marked as such, and must not be
21 // misrepresented as being the original software.
22 // 3. This notice may not be removed or altered from any source distribution.
23 //
24 // Tanguy Fautré// softdev@pandora.be // ////////////////////////////////////////////////////////////////////// // // Tri Stripper // ************ // // Current version: 1.00 BETA 5 (10/12/2002) // // Comment: Triangle stripper in O(n.log(n)). // // Currently there are no protection against crazy values // given via SetMinStripSize() and SetCacheSize(). // So be careful. (Min. strip size should be equal or greater // than 2, cache size should be about 10 for GeForce 256/2 // and about 16-18 for GeForce 3/4.) // // History: - 1.00 BETA 5 (10/12/2002) - Fixed a bug in Stripify() that could sometimes // cause it to go into an infinite loop. // (thanks to Remy for the bug report) // - 1.00 BETA 4 (18/11/2002) - Removed the dependency on OpenGL: // modified gl_primitives to primitives, // and gl_primitives_vector to primitives_vector; // and added primitive_type. // (thanks to Patrik for noticing this useless dependency) // - 1.00 BETA 3 (18/11/2002) - Fixed a bug in LinkNeightboursTri() that could cause a crash // (thanks to Nicolas for finding it) // - 1.00 BETA 2 (16/11/2002) - Improved portability // - 1.00 BETA 1 (27/10/2002) - First public release // ////////////////////////////////////////////////////////////////////// #ifndef TRISTRIP_TRI_STRIPPER_H #define TRISTRIP_TRI_STRIPPER_H #include <algorithm> #include <deque> #include <list> #include <map> #include <string> #include <vector> // namespace triangle_stripper namespace triangle_stripper { #include "TriStrip_graph_array.h" #include "TriStrip_heap_array.h" typedef unsigned int indice; class triangle { public: triangle(); triangle(const indice A, const indice B, const indice C); void SetStripID(const size_t StripID); indice A() const; indice B() const; indice C() const; size_t StripID() const; private: indice m_A; indice m_B; indice m_C; size_t m_StripID; }; class triangle_edge { public: triangle_edge(const indice A, const indice B, const size_t TriPos); indice A() const; indice B() const; size_t TriPos() const; private: indice m_A; indice m_B; size_t m_TriPos; }; class triangle_degree { public: triangle_degree(); triangle_degree(const size_t TriPos, const size_t Degree); size_t Degree() const; size_t TriPos() const; void SetDegree(const size_t Degree); private: size_t m_TriPos; size_t m_Degree; }; class triangle_strip { public: enum start_order { ABC = 0, BCA = 1, CAB = 2 }; triangle_strip(); triangle_strip(size_t StartTriPos, start_order StartOrder, size_t Size); size_t StartTriPos() const; start_order StartOrder() const; size_t Size() const; private: size_t m_StartTriPos; start_order m_StartOrder; size_t m_Size; }; struct _cmp_tri_interface_lt { bool operator() (const triangle_edge & a, const triangle_edge & b) const; }; struct _cmp_tri_degree_gt { bool operator () (const triangle_degree & a, const triangle_degree & b) const; }; class tri_stripper { public: // New Public types typedef std::vector<indice> indices; enum primitive_type { PT_Triangles = 0x0004, // = GL_TRIANGLES PT_Triangle_Strip = 0x0005 // = GL_TRIANGLE_STRIP }; struct primitives { indices m_Indices; primitive_type m_Type; }; typedef std::vector<primitives> primitives_vector; struct triangles_indices_error { }; // constructor/initializer inline tri_stripper(const indices & TriIndices); // Settings functions inline void SetCacheSize(const size_t CacheSize = 16); // = 0 will disable the cache optimizer inline void SetMinStripSize(const size_t MinStripSize = 2); // Stripper void Strip(primitives_vector * out_pPrimitivesVector); // throw triangles_indices_error(); private: friend struct _cmp_tri_interface_lt; typedef common_structures::graph_array<triangle, char> triangles_graph; typedef common_structures::heap_array<triangle_degree, _cmp_tri_degree_gt> triangles_heap; typedef std::vector<triangle_edge> triangle_edges; typedef std::vector<size_t> triangle_indices; typedef std::deque<indice> indices_cache; void InitCache(); void InitTriGraph(); void InitTriHeap(); void Stripify(); void AddLeftTriangles(); void LinkNeighboursTri(const triangle_edges & TriInterface, const triangle_edge Edge); void MarkTriAsTaken(const size_t i); triangle_edge GetLatestEdge(const triangle & Triangle, const triangle_strip::start_order Order) const; triangle_strip FindBestStrip(); triangle_strip ExtendTriToStrip(const size_t StartTriPos, const triangle_strip::start_order StartOrder); void BuildStrip(const triangle_strip TriStrip); void AddIndice(const indice i); void AddIndiceToCache(const indice i, bool CacheHitCount = false); void AddTriToCache(const triangle & Tri, const triangle_strip::start_order Order); void AddTriToIndices(const triangle & Tri, const triangle_strip::start_order Order); const indices & m_TriIndices; size_t m_MinStripSize; size_t m_CacheSize; primitives_vector m_PrimitivesVector; triangles_graph m_Triangles; triangles_heap m_TriHeap; triangle_indices m_NextCandidates; indices_cache m_IndicesCache; size_t m_StripID; size_t m_CacheHits; }; ////////////////////////////////////////////////////////////////////////// // tri_stripper Inline functions ////////////////////////////////////////////////////////////////////////// inline tri_stripper::tri_stripper(const indices & TriIndices) : m_TriIndices(TriIndices) { SetCacheSize(); SetMinStripSize(); } inline void tri_stripper::SetCacheSize(const size_t CacheSize) { m_CacheSize = CacheSize; } inline void tri_stripper::SetMinStripSize(const size_t MinStripSize) { m_MinStripSize = MinStripSize; } inline triangle::triangle() { } inline triangle::triangle(const indice A, const indice B, const indice C) : m_A(A), m_B(B), m_C(C), m_StripID(0) { } inline void triangle::SetStripID(const size_t StripID) { m_StripID = StripID; } inline indice triangle::A() const { return m_A; } inline indice triangle::B() const { return m_B; } inline indice triangle::C() const { return m_C; } inline size_t triangle::StripID() const { return m_StripID; } inline triangle_edge::triangle_edge(const indice A, const indice B, const size_t TriPos) : m_A(A), m_B(B), m_TriPos(TriPos) { } inline indice triangle_edge::A() const { return m_A; } inline indice triangle_edge::B() const { return m_B; } inline size_t triangle_edge::TriPos() const { return m_TriPos; } inline triangle_degree::triangle_degree() { } inline triangle_degree::triangle_degree(const size_t TriPos, const size_t Degree) : m_TriPos(TriPos), m_Degree(Degree) { } inline size_t triangle_degree::Degree() const { return m_Degree; } inline size_t triangle_degree::TriPos() const { return m_TriPos; } inline void triangle_degree::SetDegree(const size_t Degree) { m_Degree = Degree; } inline triangle_strip::triangle_strip() : m_StartTriPos(0), m_StartOrder(ABC), m_Size(0) { } inline triangle_strip::triangle_strip(const size_t StartTriPos, const start_order StartOrder, const size_t Size) : m_StartTriPos(StartTriPos), m_StartOrder(StartOrder), m_Size(Size) { } inline size_t triangle_strip::StartTriPos() const { return m_StartTriPos; } inline triangle_strip::start_order triangle_strip::StartOrder() const { return m_StartOrder; } inline size_t triangle_strip::Size() const { return m_Size; } inline bool _cmp_tri_interface_lt::operator() (const triangle_edge & a, const triangle_edge & b) const { const indice A1 = a.A(); const indice B1 = a.B(); const indice A2 = b.A(); const indice B2 = b.B(); if ((A1 < A2) || ((A1 == A2) && (B1 < B2))) return true; else return false; } inline bool _cmp_tri_degree_gt::operator () (const triangle_degree & a, const triangle_degree & b) const { // the triangle with a smaller degree has more priority return a.Degree() > b.Degree(); } } // namespace triangle_stripper #endif
25 // softdev@pandora.be
26 //
28 //
29 // Tri Stripper
30 // ************
31 //
32 // Current version: 1.00 BETA 5 (10/12/2002)
33 //
34 // Comment: Triangle stripper in O(n.log(n)).
35 //
36 // Currently there are no protection against crazy values
37 // given via SetMinStripSize() and SetCacheSize().
38 // So be careful. (Min. strip size should be equal or greater
39 // than 2, cache size should be about 10 for GeForce 256/2
40 // and about 16-18 for GeForce 3/4.)
41 //
42 // History: - 1.00 BETA 5 (10/12/2002) - Fixed a bug in Stripify() that could sometimes
43 // cause it to go into an infinite loop.
44 // (thanks to Remy for the bug report)
45 // - 1.00 BETA 4 (18/11/2002) - Removed the dependency on OpenGL:
46 // modified gl_primitives to primitives,
47 // and gl_primitives_vector to primitives_vector;
48 // and added primitive_type.
49 // (thanks to Patrik for noticing this useless dependency)
50 // - 1.00 BETA 3 (18/11/2002) - Fixed a bug in LinkNeightboursTri() that could cause a crash
51 // (thanks to Nicolas for finding it)
52 // - 1.00 BETA 2 (16/11/2002) - Improved portability
53 // - 1.00 BETA 1 (27/10/2002) - First public release
54 //
56 
57 #ifndef TRISTRIP_TRI_STRIPPER_H
58 #define TRISTRIP_TRI_STRIPPER_H
59 
60 #include <algorithm>
61 #include <deque>
62 #include <list>
63 #include <map>
64 #include <string>
65 
66 #include <vector>
67 
68 // namespace triangle_stripper
69 namespace triangle_stripper {
70 
71 
72 
75 
76 typedef unsigned int indice;
77 
78 class triangle
79 {
80 public:
81  triangle();
82  triangle(const indice A, const indice B, const indice C);
83 
84  void SetStripID(const size_t StripID);
85 
86  indice A() const;
87  indice B() const;
88  indice C() const;
89  size_t StripID() const;
90 
91 private:
92  indice m_A;
93  indice m_B;
94  indice m_C;
95  size_t m_StripID;
96 };
97 
98 
100 {
101 public:
102  triangle_edge(const indice A, const indice B, const size_t TriPos);
104  indice A() const;
105  indice B() const;
106  size_t TriPos() const;
107 
108 private:
109  indice m_A;
110  indice m_B;
111  size_t m_TriPos;
112 };
113 
114 
116 {
117 public:
119  triangle_degree(const size_t TriPos, const size_t Degree);
121  size_t Degree() const;
122  size_t TriPos() const;
124  void SetDegree(const size_t Degree);
126 private:
127  size_t m_TriPos;
128  size_t m_Degree;
129 };
133 {
134 public:
135  enum start_order { ABC = 0, BCA = 1, CAB = 2 };
136 
138  triangle_strip(size_t StartTriPos, start_order StartOrder, size_t Size);
140  size_t StartTriPos() const;
141  start_order StartOrder() const;
142  size_t Size() const;
144 private:
145  size_t m_StartTriPos;
146  start_order m_StartOrder;
147  size_t m_Size;
148 };
149 
152 {
153  bool operator() (const triangle_edge & a, const triangle_edge & b) const;
154 };
155 
156 
158 {
159  bool operator () (const triangle_degree & a, const triangle_degree & b) const;
160 };
161 
162 class tri_stripper
163 {
164 public:
165 
166  // New Public types
167  typedef std::vector<indice> indices;
168 
170  PT_Triangles = 0x0004, // = GL_TRIANGLES
171  PT_Triangle_Strip = 0x0005 // = GL_TRIANGLE_STRIP
172  };
173 
174  struct primitives
175  {
176  indices m_Indices;
178  };
179 
180  typedef std::vector<primitives> primitives_vector;
181 
183 
184 
185  // constructor/initializer
186  inline tri_stripper(const indices & TriIndices);
187 
188  // Settings functions
189  inline void SetCacheSize(const size_t CacheSize = 16); // = 0 will disable the cache optimizer
190  inline void SetMinStripSize(const size_t MinStripSize = 2);
191 
192  // Stripper
193  void Strip(primitives_vector * out_pPrimitivesVector); // throw triangles_indices_error();
194 
195 private:
196 
197  friend struct _cmp_tri_interface_lt;
200 
201 
202 
203  typedef common_structures::graph_array<triangle, char> triangles_graph;
205  typedef std::vector<triangle_edge> triangle_edges;
206  typedef std::vector<size_t> triangle_indices;
207  typedef std::deque<indice> indices_cache;
208 
209 
210  void InitCache();
211  void InitTriGraph();
212  void InitTriHeap();
213  void Stripify();
214  void AddLeftTriangles();
215 
216  void LinkNeighboursTri(const triangle_edges & TriInterface, const triangle_edge Edge);
217  void MarkTriAsTaken(const size_t i);
218 
219  triangle_edge GetLatestEdge(const triangle & Triangle, const triangle_strip::start_order Order) const;
220 
221  triangle_strip FindBestStrip();
222  triangle_strip ExtendTriToStrip(const size_t StartTriPos, const triangle_strip::start_order StartOrder);
223  void BuildStrip(const triangle_strip TriStrip);
224  void AddIndice(const indice i);
225  void AddIndiceToCache(const indice i, bool CacheHitCount = false);
226  void AddTriToCache(const triangle & Tri, const triangle_strip::start_order Order);
227  void AddTriToIndices(const triangle & Tri, const triangle_strip::start_order Order);
229  const indices & m_TriIndices;
231  size_t m_MinStripSize;
232  size_t m_CacheSize;
233 
234  primitives_vector m_PrimitivesVector;
235  triangles_graph m_Triangles;
236  triangles_heap m_TriHeap;
237  triangle_indices m_NextCandidates;
238  indices_cache m_IndicesCache;
239  size_t m_StripID;
240  size_t m_CacheHits;
241 };
242 
243 
245 
247 // tri_stripper Inline functions
249 
250 inline tri_stripper::tri_stripper(const indices & TriIndices) : m_TriIndices(TriIndices) {
251  SetCacheSize();
252  SetMinStripSize();
253 }
254 
255 
256 inline void tri_stripper::SetCacheSize(const size_t CacheSize) {
257  m_CacheSize = CacheSize;
258 }
259 
260 
261 inline void tri_stripper::SetMinStripSize(const size_t MinStripSize) {
262  m_MinStripSize = MinStripSize;
263 }
264 
265 
266 inline triangle::triangle() { }
268 
269 inline triangle::triangle(const indice A, const indice B, const indice C) : m_A(A), m_B(B), m_C(C), m_StripID(0) { }
270 
271 
272 inline void triangle::SetStripID(const size_t StripID) {
273  m_StripID = StripID;
274 }
275 
277 inline indice triangle::A() const {
278  return m_A;
279 }
280 
281 
282 inline indice triangle::B() const {
283  return m_B;
284 }
285 
287 inline indice triangle::C() const {
288  return m_C;
289 }
290 
291 
292 inline size_t triangle::StripID() const {
293  return m_StripID;
294 }
296 
297 inline triangle_edge::triangle_edge(const indice A, const indice B, const size_t TriPos) : m_A(A), m_B(B), m_TriPos(TriPos) { }
298 
299 
300 inline indice triangle_edge::A() const {
301  return m_A;
302 }
303 
304 
305 inline indice triangle_edge::B() const {
306  return m_B;
307 }
308 
309 
310 inline size_t triangle_edge::TriPos() const {
311  return m_TriPos;
312 }
314 
316 
317 
318 inline triangle_degree::triangle_degree(const size_t TriPos, const size_t Degree) : m_TriPos(TriPos), m_Degree(Degree) { }
320 
321 inline size_t triangle_degree::Degree() const {
322  return m_Degree;
323 }
324 
326 inline size_t triangle_degree::TriPos() const {
327  return m_TriPos;
328 }
329 
330 
331 inline void triangle_degree::SetDegree(const size_t Degree) {
332  m_Degree = Degree;
333 }
334 
335 
336 inline triangle_strip::triangle_strip() : m_StartTriPos(0), m_StartOrder(ABC), m_Size(0) { }
338 
339 inline triangle_strip::triangle_strip(const size_t StartTriPos, const start_order StartOrder, const size_t Size)
340  : m_StartTriPos(StartTriPos), m_StartOrder(StartOrder), m_Size(Size) { }
341 
342 
343 inline size_t triangle_strip::StartTriPos() const {
344  return m_StartTriPos;
345 }
346 
347 
349  return m_StartOrder;
350 }
352 
353 inline size_t triangle_strip::Size() const {
354  return m_Size;
355 }
356 
357 
358 inline bool _cmp_tri_interface_lt::operator() (const triangle_edge & a, const triangle_edge & b) const {
359  const indice A1 = a.A();
360  const indice B1 = a.B();
361  const indice A2 = b.A();
362  const indice B2 = b.B();
363 
364  if ((A1 < A2) || ((A1 == A2) && (B1 < B2)))
365  return true;
366  else
367  return false;
368 }
369 
370 
371 inline bool _cmp_tri_degree_gt::operator () (const triangle_degree & a, const triangle_degree & b) const {
372  // the triangle with a smaller degree has more priority
373  return a.Degree() > b.Degree();
374 }
375 
376 
377 
378 
379 } // namespace triangle_stripper
380 
381 #endif
GLboolean GLboolean GLboolean GLboolean a
GLboolean GLboolean GLboolean b
png_uint_32 i
Definition: png.h:2640
void SetStripID(size_t StripID)
Definition: types.h:31
tri_stripper(const indices &TriIndices)
bool operator()(const triangle_degree &a, const triangle_degree &b) const
std::vector< index > indices
Definition: public_types.h:22
bool operator()(const triangle_edge &a, const triangle_edge &b) const
std::vector< primitives > primitives_vector
#define A1