44 if (m_TriIndices.size() % 3 != 0)
48 m_PrimitivesVector.clear();
49 out_pPrimitivesVector->clear();
70 std::swap(m_PrimitivesVector, (* out_pPrimitivesVector));
76 void tri_stripper::InitTriGraph()
80 m_Triangles.setsize(m_TriIndices.size() / 3);
83 for (i = 0; i < m_Triangles.
size(); ++
i)
84 m_Triangles[i] =
triangle(m_TriIndices[i * 3 + 0], m_TriIndices[i * 3 + 1], m_TriIndices[i * 3 + 2]);
87 triangle_edges TriInterface;
88 TriInterface.reserve(m_Triangles.
size() * 3);
90 for (i = 0; i < m_Triangles.
size(); ++
i) {
91 TriInterface.push_back(
triangle_edge(m_Triangles[i]->A(), m_Triangles[i]->B(), i));
92 TriInterface.push_back(
triangle_edge(m_Triangles[i]->B(), m_Triangles[i]->C(), i));
93 TriInterface.push_back(
triangle_edge(m_Triangles[i]->C(), m_Triangles[i]->A(), i));
100 for (i = 0; i < m_Triangles.
size(); ++
i) {
102 const triangle_edge EdgeBA(m_Triangles[i]->B(), m_Triangles[i]->A(), i);
103 const triangle_edge EdgeCB(m_Triangles[i]->C(), m_Triangles[i]->B(), i);
104 const triangle_edge EdgeAC(m_Triangles[i]->A(), m_Triangles[i]->C(), i);
106 LinkNeighboursTri(TriInterface, EdgeBA);
107 LinkNeighboursTri(TriInterface, EdgeCB);
108 LinkNeighboursTri(TriInterface, EdgeAC);
114 void tri_stripper::LinkNeighboursTri(
const triangle_edges & TriInterface,
const triangle_edge Edge)
116 typedef triangle_edges::const_iterator edge_const_it;
119 edge_const_it It = std::lower_bound(TriInterface.begin(), TriInterface.end(), Edge,
_cmp_tri_interface_lt());
124 for (; (It != TriInterface.end()) && ((It->A() == Edge.
A()) && (It->B() == Edge.
B())); ++It)
125 m_Triangles.insert(Edge.TriPos(), It->TriPos());
132 void tri_stripper::InitTriHeap()
139 for (
size_t i = 0;
i < m_Triangles.
size(); ++
i)
144 while ((! m_TriHeap.
empty()) && (m_TriHeap.
top().Degree() == 0))
150 void tri_stripper::InitCache()
152 m_IndicesCache.clear();
155 m_IndicesCache.resize(m_CacheSize, static_cast<indice>(-1));
160 void tri_stripper::Stripify()
166 m_NextCandidates.clear();
169 while (! m_TriHeap.
empty()) {
172 const size_t HeapTop = m_TriHeap.
top().TriPos();
173 m_NextCandidates.push_back(HeapTop);
176 while (! m_NextCandidates.empty()) {
184 if (TriStrip.
Size() >= m_MinStripSize)
185 BuildStrip(TriStrip);
190 if (! m_TriHeap.
removed(HeapTop))
191 m_TriHeap.
erase(HeapTop);
195 while ((! m_TriHeap.
empty()) && (m_TriHeap.
top().Degree() == 0))
205 size_t BestStripDegree = 0;
206 size_t BestStripCacheHits = 0;
209 indices_cache CacheBackup = m_IndicesCache;
211 while (! m_NextCandidates.empty()) {
214 if ((m_Triangles[m_NextCandidates.back()].marked()) || (m_TriHeap[m_NextCandidates.back()].Degree() == 0)) {
215 m_NextCandidates.pop_back();
224 const size_t CandidateTri = m_NextCandidates.back();
225 m_NextCandidates.pop_back();
228 for (
size_t i = 0;
i < 3; ++
i) {
237 m_IndicesCache = CacheBackup;
241 if (TempStrip.
Size() >= m_MinStripSize) {
244 if (m_CacheSize == 0) {
247 if (TempStrip.
Size() > BestStrip.
Size())
248 BestStrip = TempStrip;
255 if (m_CacheHits > BestStripCacheHits) {
256 BestStrip = TempStrip;
257 BestStripDegree = m_TriHeap[TempStrip.
StartTriPos()].Degree();
258 BestStripCacheHits = m_CacheHits;
260 }
else if (m_CacheHits == BestStripCacheHits) {
263 if ((BestStrip.
Size() != 0) && (m_TriHeap[TempStrip.
StartTriPos()].Degree() < BestStripDegree)) {
264 BestStrip = TempStrip;
265 BestStripDegree = m_TriHeap[TempStrip.
StartTriPos()].Degree();
268 }
else if (TempStrip.
Size() > BestStrip.
Size()) {
269 BestStrip = TempStrip;
270 BestStripDegree = m_TriHeap[TempStrip.
StartTriPos()].Degree();
291 bool ClockWise =
false;
298 m_Triangles[StartTriPos]->SetStripID(m_StripID);
301 AddTriToCache((* m_Triangles[StartTriPos]), Order);
305 for (tri_node_iter TriNodeIt = (m_Triangles.
begin() + StartTriPos);
306 (TriNodeIt != m_Triangles.
end()) && ((m_CacheSize <= 0) || ((Size + 2) < m_CacheSize));
310 const triangle_edge Edge = GetLatestEdge(** TriNodeIt, Order);
313 const_tri_link_iter LinkIt;
314 for (LinkIt = TriNodeIt->out_begin(); LinkIt != TriNodeIt->out_end(); ++LinkIt) {
317 const triangle & Tri = (** (LinkIt->terminal()));
320 if ((Tri.
StripID() != m_StripID) && (! (LinkIt->terminal()->marked()))) {
324 if ((Edge.
B() == Tri.
A()) && (Edge.
A() == Tri.
B())) {
326 AddIndiceToCache(Tri.
C(),
true);
330 else if ((Edge.
B() == Tri.
B()) && (Edge.
A() == Tri.
C())) {
332 AddIndiceToCache(Tri.
A(),
true);
336 else if ((Edge.
B() == Tri.
C()) && (Edge.
A() == Tri.
A())) {
338 AddIndiceToCache(Tri.
B(),
true);
345 if (LinkIt == TriNodeIt->out_end()) {
346 TriNodeIt = m_Triangles.
end();
349 TriNodeIt = LinkIt->terminal();
352 (* TriNodeIt)->SetStripID(m_StripID);
353 ClockWise = ! ClockWise;
386 bool ClockWise =
false;
394 AddTriToIndices((* m_Triangles[StartTriPos]), Order);
397 MarkTriAsTaken(StartTriPos);
401 tri_node_iter TriNodeIt = (m_Triangles.
begin() + StartTriPos);
403 for (
size_t Size = 1; Size < TriStrip.
Size(); ++Size) {
406 const triangle_edge Edge = GetLatestEdge(** TriNodeIt, Order);
409 const_tri_link_iter LinkIt;
410 for (LinkIt = TriNodeIt->out_begin(); LinkIt != TriNodeIt->out_end(); ++LinkIt) {
413 const triangle & Tri = (** (LinkIt->terminal()));
416 if (! (LinkIt->terminal()->marked())) {
420 if ((Edge.
B() == Tri.
A()) && (Edge.
A() == Tri.
B())) {
426 else if ((Edge.
B() == Tri.
B()) && (Edge.
A() == Tri.
C())) {
432 else if ((Edge.
B() == Tri.
C()) && (Edge.
A() == Tri.
A())) {
442 if (LinkIt == TriNodeIt->out_end())
throw "tri_stripper::BuildStrip(,) error, next triangle not found";
446 TriNodeIt = LinkIt->terminal();
447 MarkTriAsTaken(TriNodeIt - m_Triangles.
begin());
450 ClockWise = ! ClockWise;
456 void tri_stripper::MarkTriAsTaken(
const size_t i)
462 m_Triangles[
i].mark();
469 for (tri_link_iter LinkIt = m_Triangles[i].out_begin(); LinkIt != m_Triangles[
i].out_end(); ++LinkIt) {
471 const size_t j = LinkIt->terminal() - m_Triangles.
begin();
473 if ((! m_Triangles[j].marked()) && (! m_TriHeap.
removed(j))) {
476 m_TriHeap.
update(j, NewDegree);
479 if ((m_CacheSize > 0) && (NewDegree.
Degree() > 0))
480 m_NextCandidates.push_back(j);
487 void tri_stripper::AddIndiceToCache(
const indice i,
bool CacheHitCount)
490 if (m_CacheSize > 0) {
494 if (std::find(m_IndicesCache.begin(), m_IndicesCache.end(),
i) != m_IndicesCache.end())
499 m_IndicesCache.pop_back();
500 m_IndicesCache.push_front(i);
506 void tri_stripper::AddIndice(
const indice i)
509 m_PrimitivesVector.back().m_Indices.push_back(i);
523 AddIndiceToCache(Tri.
A(),
true);
524 AddIndiceToCache(Tri.
B(),
true);
525 AddIndiceToCache(Tri.
C(),
true);
528 AddIndiceToCache(Tri.
B(),
true);
529 AddIndiceToCache(Tri.
C(),
true);
530 AddIndiceToCache(Tri.
A(),
true);
533 AddIndiceToCache(Tri.
C(),
true);
534 AddIndiceToCache(Tri.
A(),
true);
535 AddIndiceToCache(Tri.
B(),
true);
566 void tri_stripper::AddLeftTriangles()
572 m_PrimitivesVector.push_back(Primitives);
573 indices & Indices = m_PrimitivesVector.back().m_Indices;
575 for (
size_t i = 0; i < m_Triangles.
size(); ++
i)
576 if (! m_Triangles[i].marked()) {
577 Indices.push_back(m_Triangles[i]->A());
578 Indices.push_back(m_Triangles[i]->B());
579 Indices.push_back(m_Triangles[i]->C());
583 if (Indices.size() == 0)
584 m_PrimitivesVector.pop_back();
void Strip(primitive_vector *out_pPrimitivesVector)
void reserve(size_t Size)
void update(size_t i, const T &Elem)
size_t push(const T &Elem)
std::list< arc >::const_iterator const_out_arc_iterator
start_order StartOrder() const
const T & peek(size_t i) const
friend struct _cmp_tri_interface_lt
std::vector< node >::iterator node_iterator
std::vector< indice > indices
std::list< arc >::iterator out_arc_iterator
bool removed(size_t i) const
void SetDegree(const size_t Degree)
std::vector< primitives > primitives_vector
size_t StartTriPos() const