source: GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshStripifier.cpp @ 2549

Revision 2549, 28.9 KB checked in by gumbau, 17 years ago (diff)
Line 
1/*      =====================================================================
2 *      (C) 2005 Universitat Jaume I
3 *      =====================================================================
4 *      PROYECT:        GAME TOOLS
5 *      =====================================================================
6 *      CONTENT:        Make triangle strip meshes from triangle list meshes.
7 *
8 *
9 *      @file   GeoMeshStripifier.cpp
10 *      =====================================================================*/
11
12#include "GeoMeshStripifier.h"
13
14using namespace Geometry;
15using   namespace       std;
16
17//-------------------------------------------------------------------------
18//      Private.
19//-------------------------------------------------------------------------
20
21
22///     stripify:       Make triangle strips for a given mesh.
23int CustomStripifier::stripify (Geometry::Mesh  *geoMesh)
24{
25        int                     oddStrip;
26        int                             i;
27        unsigned int    j;
28        int                             num_vert        =       0;
29        int                             num_faces       =       0;
30        int                             num_tris    = 0;
31        int                             totalStripIndices;
32
33        Geometry::SubMesh*      geoSubMesh;
34        vector_int v_indices;
35 
36        //      Process OK.
37        mError = 0;
38
39        StripFaceAdj = NULL;
40
41        //      Progress bar.
42        float   percent;
43        percent =       float(100.0 / (geoMesh->mSubMeshCount * 10.0));
44
45        //      For all submeshes.
46        for(unsigned int k = 0; k < geoMesh->mSubMeshCount; k++)
47        {
48                //      Leaves submesh doesn't stripify.
49                if (mSubMeshLeaves != k)
50                {
51                        //Free structures
52                        v_indices.clear();
53                        StripFaces.clear();
54                        my_vector.clear();
55                        my_vector.push_back(v_indices);
56
57                        if (StripFaceAdj != NULL)
58                                free(StripFaceAdj);
59
60                        StripFaceAdj = NULL;
61
62                        for (int i=0;i<StripEdges.size();i++)
63                                StripEdges[i].clear();
64
65                        StripEdges.clear();
66
67                        if (StripArray != NULL)
68                        {
69                                for (int i=0;i<60;i++)
70                                        StripArray[i].clear();
71
72                        }
73
74                        for (int i=0;i<StripVertices.size();i++)
75                                StripVertices[i].clear();
76
77                        StripVertices.clear();
78
79                        //Let's start striping
80                        num_tiras       =       0;
81
82                        //      Actual submesh.
83                        geoSubMesh      =       &geoMesh->mSubMesh[k];
84
85                        //      Mesh type.
86                        geoSubMesh->mType       =       GEO_TRIANGLE_STRIPS;
87
88                        num_vert        =       int(geoSubMesh->mVertexBuffer->mVertexCount);
89                        num_faces       =       int(geoSubMesh->mIndexCount / 3);
90                        num_tris        =       num_faces;
91
92                        //      Updtate progress bar.
93                        if (mUPB)
94                        {
95                                mUPB(percent*2);
96                        }
97
98                        //      Load the object into memory.
99                        ReadData(geoSubMesh, num_faces, num_vert);
100
101                        //      Updtate progress bar.
102                        if (mUPB)
103                        {
104                                mUPB(percent);
105                        }
106
107                        FindAdjacencies(num_faces,num_vert);
108
109                        //      Updtate progress bar.
110                        if (mUPB)
111                        {
112                                mUPB(percent);
113                        }
114
115                        //      If the mesh is not manifold.
116                        if (mError)
117                        {
118                                return  0;
119                        }
120
121                        StoreAdjacencies(num_faces);
122
123                        //      Updtate progress bar.
124                        if (mUPB)
125                        {
126                                mUPB(percent);
127                        }
128
129                        Stripification();
130
131                        //      Updtate progress bar.
132                        if (mUPB)
133                        {
134                                mUPB(percent);
135                        }
136
137                        //      Updtate progress bar.
138                        if (mUPB)
139                        {
140                                mUPB(percent);
141                        }
142
143                        num_vert        =       num_tiras;
144
145                        totalStripIndices       =       0;
146
147                        geoSubMesh->mStripCount =       num_tiras;
148
149                        //      Memory for the array of strips beginnigs
150                        geoSubMesh->mStrip = (Index**) malloc(sizeof(Index*) * geoSubMesh->mStripCount);
151
152                        // The first one will be different
153                        v_indices       =       my_vector[1];
154
155                        //      Number of vertices of a strip odd or even.
156                        if(v_indices.size() % 2)
157                        {
158                                oddStrip        = true;
159                        }
160                        else
161                        {
162                                oddStrip        =       false;
163                        }
164
165                        //      Obtiene el total de indices de la primera strip.
166                        geoSubMesh->mIndexCount =       v_indices.size();
167
168                        //      Calculate the Index Count.
169                        for (i = 2; i <= num_tiras; i++)
170                        {
171                                v_indices                                                               =               my_vector[i];
172                                geoSubMesh->mIndexCount +=      v_indices.size() + 2;
173
174                                //      Insert a new vertex if the strip es odd.
175                                if(oddStrip)
176                                {
177                                        geoSubMesh->mIndexCount++;
178                                }
179
180                                //      Number of vertices of a strip odd or even.
181                                if(v_indices.size() % 2)
182                                        oddStrip        = true;
183                                else
184                                        oddStrip        =       false;
185                        }
186
187                        //      Delete the actual indices.
188                        delete[]        geoSubMesh->mIndex;
189                        geoSubMesh->mIndex      =       new     Index[geoSubMesh->mIndexCount];
190                        //--------------------------------------------
191
192                        // First time will be different
193                        v_indices =     my_vector[1];
194
195                        //      Copy first strip in the index array
196                        for(j = 0;j < v_indices.size();j++)
197                        {
198                                geoSubMesh->mIndex[totalStripIndices++] =       v_indices[j];
199                        }
200
201                        //Assign beginning of first strip
202                        geoSubMesh->mStrip[0]   =       &geoSubMesh->mIndex[0];
203
204                        //      Updtate progress bar.
205                        if (mUPB)
206                        {
207                                mUPB(percent);
208                        }
209
210                        //      Number of vertices of a strip odd or even.
211                        if(v_indices.size() % 2)
212                        {
213                                oddStrip        = true;
214                        }
215                        else
216                        {
217                                oddStrip        =       false;
218                        }
219
220                        //For all the strips but the first one
221                        for(i   =       2;      i <= num_tiras; i++)
222                        {
223                                //      initial degenerate triangle (copy last twice)
224                                geoSubMesh->mIndex[totalStripIndices++] =       geoSubMesh->
225                                        mIndex[totalStripIndices-1];
226
227                                v_indices                                                               =       my_vector[i];
228
229                                //      initial degenerate triangle (copy first twice)
230                               
231                                geoSubMesh->mIndex[totalStripIndices++] =       v_indices[0];
232
233                                //      Asigna el inicio de la tira de triangulos.
234                                geoSubMesh->mStrip[i-1] =       &geoSubMesh->mIndex[totalStripIndices - 1];
235
236                                //      Degenerate Triangle
237                                geoSubMesh->mIndex[totalStripIndices++] =       v_indices[0];
238
239                                //      Insert a new vertex if the strip es odd.
240                                if(oddStrip)
241                                {
242                                        geoSubMesh->mIndex[totalStripIndices++] =       v_indices[0];
243                                }
244
245                                //      Number of vertices of a strip odd or even.
246                                if(v_indices.size() % 2)
247                                {
248                                        oddStrip        = true;
249                                }
250                                else
251                                {
252                                        oddStrip        =       false;
253                                }
254                               
255                                //      Copy current strip
256                                for(j   =       1;      j < v_indices.size();   j++)
257                                {
258                                        geoSubMesh->mIndex[totalStripIndices++] =       v_indices[j];
259                                }
260                        }
261
262
263                }
264        }//     End For. SubMeshes.
265
266        //      Updtate progress bar.
267        if (mUPB)
268        {
269                mUPB(100.0);
270        }
271
272        return  1;
273}
274
275
276///     Getlower:
277void CustomStripifier::GetLower (int *x, int *y)
278{
279  int temp;
280 
281  if (*y < *x)
282  {
283    temp        =       *x;
284    *x          =       *y;
285    *y          =       temp;
286  }
287}
288
289///     Different:
290//Return the vertex of the first triangle that is not in the second
291int CustomStripifier::Different(int id1,int id2,int id3,int id4,int id5, int id6, int *x, int *y)
292{
293  if ((id1 != id4) && (id1 != id5) && (id1 != id6))
294    {
295      *x = id2;
296      *y = id3;
297      return id1;
298    }
299  if ((id2 != id4) && (id2 != id5) && (id2 != id6))
300    {
301      *x = id1;
302      *y = id3;
303      return id2;
304    }
305  if ((id3 != id4) && (id3 != id5) && (id3 != id6))
306    {
307      *x = id1;
308      *y = id2;
309      return id3;
310    }
311 
312  *x = id5;
313  *y = id6;
314
315  return id4;
316}
317
318///Orient:
319void CustomStripifier::Orient(int vertex1, int vertex2,int vertex3)
320{
321  int original_vertex[3];
322  int vertices,index,i=0;
323  int verts;
324
325        do { 
326                index = 0;
327                verts=StripVertices[vertex1-1][i];
328                i++;
329                for (vertices = 0; vertices < 3;vertices++) {
330                        if (vertex1 == StripFaces[verts].array[vertices]+1 || vertex2 == StripFaces[verts].array[vertices]+1 ||
331                                vertex3 == StripFaces[verts].array[vertices]+1 )
332                                        original_vertex[index++] = StripFaces[verts].array[vertices]+1;     
333
334                        if (index == 3)
335                        break;
336                }
337        if (index == 3)
338                break;
339        }
340        while (i< (int) StripVertices[vertex1-1].size());
341
342        i=0;
343
344        if (index == 3)
345                return;
346 
347        do {
348                verts=StripVertices[vertex2-1][i];
349                i++;
350                index = 0;
351                for (vertices = 0; vertices < 3;vertices++) {
352                if (vertex1 == StripFaces[verts] .array[vertices]+1 || vertex2 == StripFaces[verts] .array[vertices]+1 ||
353                        vertex3 == StripFaces[verts] .array[vertices]+1 )
354                                original_vertex[index++] = StripFaces[verts] .array[vertices]+1;   
355                if (index == 3)
356                        break;
357                }
358        }
359        while (i< (int) StripVertices[vertex2-1].size());
360
361        if (index == 3)
362                return;
363
364    do {   
365          verts=StripVertices[vertex3-1][i];
366      i++;
367      index = 0;
368      for (vertices = 0; vertices < 3;vertices++) {
369                if (vertex1 == StripFaces[verts] .array[vertices]+1 || vertex2 == StripFaces[verts] .array[vertices]+1 ||
370                        vertex3 == StripFaces[verts] .array[vertices]+1 )
371                        original_vertex[index++] = StripFaces[verts] .array[vertices]+1;     
372
373        if (index == 3)
374          break;
375      }
376    }
377        while (i< (int) StripVertices[vertex3-1].size());
378 
379  if ( ( original_vertex[0] == vertex3 && original_vertex[1] == vertex2 && original_vertex[2] == vertex1   ) ||
380       ( original_vertex[0] == vertex2 && original_vertex[1] == vertex1 && original_vertex[2] == vertex3   ) ||
381       ( original_vertex[0] == vertex1 && original_vertex[1] == vertex3 && original_vertex[2] == vertex2   ))
382                        my_vector[num_tiras].push_back(vertex2-1);
383
384}
385
386///     AddTri:
387void CustomStripifier::AddTri(int id1, int id2, int id3, int flag, int where)
388{
389  /*   We will save everything into a list, rather than output at once,
390       as was done in the old routine. This way for future modifications
391       we can change the strips later on if we want to  */
392 
393  if (flag == -10)
394  {
395          vector_int nada;
396          my_vector.push_back(nada);
397
398          num_tiras++;
399      Finished();
400  }
401  else
402  {
403      StoreStrip(id1, where);
404      StoreStrip(id2, where);
405      StoreStrip(id3, where);
406     
407          lastTri[0]=id1;
408          lastTri[1]=id2;
409          lastTri[2]=id3;
410  }
411}
412
413///     GoBack:
414void CustomStripifier::GoBack(int face_id, int *ties,int tie)
415{
416  int NumAdj,next_face,x,y,z,f,i;   
417  int correct=0;
418
419  if (Strips.size() > 3)
420  {
421        x = Strips[0];
422        y = Strips[1];
423        z = Strips[2];
424  }
425 
426  for (i=0; i<3 ; i++)
427  {
428                correct=0;
429     
430                if ( (i !=2) && (( (StripFaces[face_id].array[i] == x) && (StripFaces[face_id].array[i+1] == y)) ||
431                        (StripFaces[face_id].array[i] == y) && (StripFaces[face_id].array[i+1] == x)))
432                                correct=1;
433
434                else if ( (i == 2) &&
435                        ( ((StripFaces[face_id].array[0] == x) && (StripFaces[face_id].array[2]== y)) ||
436                                (StripFaces[face_id].array[0] == y) && (StripFaces[face_id].array[2] == x)))
437                                correct=1;
438
439                if (correct)
440                {
441                        next_face = Find_Face(face_id,x,y,&NumAdj);
442
443                        if (next_face == -1)
444                                break;
445
446                        for (f=0;;f++)
447                        {
448                                if (StripArray[NumAdj][f] == next_face)
449                                {
450                                        lastTri[0]=z;
451                                        lastTri[1]=y;
452                                        lastTri[2]=x;
453                                        StoreTri(StripArray[NumAdj][f],NumAdj,NumAdj,ties,tie,0);
454                                        return;
455                                }
456                        }
457                }
458  }
459}
460
461///     StoreTri:
462void CustomStripifier::StoreTri(int face_id,int NumAdj,int original_adj, int *ties, int tie, int where)
463{
464  static int begin = true;
465  int old_face,next_face_id,next_NumAdj,e1,e2,e3,other1,other2,other3;
466
467  e1=lastTri[0];
468  e2=lastTri[1];
469  e3=lastTri[2];
470 
471  if (NumAdj == 0)
472  {
473          next_face_id = Different(StripFaces[face_id].array[0],StripFaces[face_id].array[1],
474                                   StripFaces[face_id].array[2],e1,e2,e3,&other1,&other2);
475
476          if ((e2 ==0) && (e3 == 0))
477          {
478              e2 = other1;
479              e3 = other2;
480          }
481         
482          AddTri(e2,e3,next_face_id,true, where);
483
484          if (StripFaceAdj[face_id].NumAdj == 0)
485            StripFaceAdj[face_id].finish = true;
486
487          StripArray[NumAdj].erase(find(StripArray[NumAdj].begin(), StripArray[NumAdj].end(), face_id));
488
489          begin = true;
490  }
491  else
492  {
493      next_face_id = UpdateAdjacencies(face_id,&next_NumAdj, &e1,&e2,ties);
494          old_face = next_face_id;
495         
496          if (last == 1)
497                  old_face=ties_array[0];
498          else
499                  old_face=Prediction();
500         
501          if (next_face_id == -1)
502          {
503              StoreTri(face_id,0,NumAdj,ties,tie, where);
504              return;
505          }
506                 
507          if (old_face != next_face_id)
508          {
509            next_face_id = old_face;
510            e3 = GetEdge(&e1,&e2,StripFaces[face_id].array,next_face_id);
511         }
512         
513          // Find the other vertex
514          if ((StripFaces[face_id].array[0]==e1)||(StripFaces[face_id].array[0]==e2))
515          {
516                if ((StripFaces[face_id].array[1]==e1)||(StripFaces[face_id].array[1]==e2))
517                        e3=StripFaces[face_id].array[2];
518                else
519                        e3=StripFaces[face_id].array[1];
520          }
521          else
522          {
523                e3=StripFaces[face_id].array[0];
524          }
525         
526          other1=lastTri[0];
527          other2=lastTri[1];
528          other3=lastTri[2];
529         
530          if ((other1 != 0) && (other2 != 0))
531          {
532                if ((e1 != other2) && (e1 != other3))
533                {
534                        e3 = e1;
535                }
536            else
537                {
538                        if ((e2 != other2) && (e2 != other3))
539                        {
540                                e3 = e2;
541                        }
542                        else
543                        {
544                                StoreTri(face_id,0,NumAdj,ties,tie, where);
545                                return;
546                        }
547                }
548             
549            if ((other2 != e1) && (other2 != e2))
550                {
551                  other1 = other2;
552                  other2 = other3;
553                }
554            else
555                {
556                        if ((other3 != e1) && (other3 != e2))
557                                other1 = other3;
558                        else
559                        {
560                                AddTri(other1,other2,e3,begin, where);
561                                if (StripFaceAdj[face_id].NumAdj == NumAdj)
562                                        StripFaceAdj[face_id].finish = true;
563
564                                StripArray[NumAdj].erase(find(StripArray[NumAdj].begin(), StripArray[NumAdj].end(), face_id));
565
566                                begin = false;
567                                return;
568                        }
569             }   
570          }
571          else
572          {
573              other1 = e3;
574              e3 = e2;
575              other2 = e1;
576          }
577
578          AddTri(other1,other2,e3,begin, where);
579
580          if (StripFaceAdj[face_id].NumAdj == NumAdj)
581                        StripFaceAdj[face_id].finish = true;
582
583          StripArray[NumAdj].erase(find(StripArray[NumAdj].begin(), StripArray[NumAdj].end(), face_id));
584
585          begin = false;
586         
587          if (StripFaceAdj[next_face_id].finish)
588                exit(0);
589
590          StoreTri(next_face_id,next_NumAdj,next_NumAdj, ties,tie, where);
591        }
592}
593
594///     StoreAdjacencies:
595void CustomStripifier::StoreAdjacencies(int num_faces)
596{
597  int i,adjacency;
598 
599  for (i=0;i<num_faces;i++)
600  {
601        adjacency=0;
602                 
603        adjacency += NumAdj(StripFaces[i].array[0],StripFaces[i].array[1]);
604        adjacency += NumAdj(StripFaces[i].array[1],StripFaces[i].array[2]);
605        adjacency += NumAdj(StripFaces[i].array[0],StripFaces[i].array[2]);
606             
607    StoreAdjacency(adjacency,i);
608  }
609}
610
611///     GetNumAdjacencies:
612int CustomStripifier::GetNumAdjacencies(int id1, int id2, int curr_id)
613{
614  int size,y,count=0;
615  int temp2;
616  int there= false;
617 
618        GetLower(&id1,&id2);
619
620        if (StripEdges[id1].empty())
621                return 0;
622
623        while (StripEdges[id1][count].array[0] != id2)
624        {
625                count++;
626                                   
627                if (count>=StripEdges[id1].size())
628                        return 0;
629        }
630
631        if (StripEdges[id1][count].array[2] == -1)
632                return 0;
633
634        if (curr_id != StripEdges[id1][count].array[1])
635        {
636                temp2 = StripEdges[id1][count].array[1];
637
638                if (StripFaceAdj[StripEdges[id1][count].array[1]].finish)
639                        return 0;
640                       
641                size = StripFaceAdj[StripEdges[id1][count].array[1]].NumAdj;
642        }
643        else
644        {
645                temp2 = StripEdges[id1][count].array[2];
646
647                if (StripFaceAdj[StripEdges[id1][count].array[2]].finish)
648                        return 0;
649                       
650                size = StripFaceAdj[StripEdges[id1][count].array[2]].NumAdj;
651        }
652   
653        if (temp2<StripFaces.size())
654        {
655                for (y = 0; y< 3; y++)
656                {
657                        if (y != 2)
658                        {
659                        if(((id1 == StripFaces[temp2].array[y]) && (id2 == StripFaces[temp2].array[y+1])) ||
660                                ((id2 == StripFaces[temp2].array[y]) && (id1 == StripFaces[temp2].array[y+1])))
661                                        there = true;
662                        }
663                        else
664                        {
665                        if(((id1 == StripFaces[temp2].array[0]) && (id2 == StripFaces[temp2].array[2])) ||
666                                ((id2 == StripFaces[temp2].array[0]) && (id1 == StripFaces[temp2].array[2])))
667                                        there = true;
668                        }
669                }
670        }
671   
672        return there;
673}
674
675///     MinimumAd:
676int CustomStripifier::MinimumAd(int id)
677{
678  int t,x=60;
679
680  if (StripFaceAdj[id].finish)
681          return 60;
682 
683  if ( id< StripFaces.size() )
684  {
685            t = GetNumAdjacencies(StripFaces[id].array[0],StripFaces[id].array[1],id);
686                if (t < x)
687                        x = t;
688
689                t = GetNumAdjacencies(StripFaces[id].array[1],StripFaces[id].array[2],id);
690                if (t < x)
691                        x = t;
692
693            t = GetNumAdjacencies(StripFaces[id].array[0],StripFaces[id].array[2],id);
694                if (t < x)
695                        x = t;
696  }
697
698  return x;
699}
700
701///     Find_Face:
702int CustomStripifier::Find_Face(int current_face, int id1, int id2, int *NumAdj)
703{
704  int y,count=0;   
705  int next_face;
706  int there = false;
707 
708        GetLower(&id1,&id2);
709
710        if (StripEdges[id1].empty())
711                return -1;
712 
713        while (StripEdges[id1][count].array[0] != id2)
714    {
715                count++;
716     
717            if (count>=StripEdges[id1].size())
718                        return -1;
719    }
720
721
722        if (StripEdges[id1][count].array[2] == -1)
723                return -1;
724
725        if (StripEdges[id1][count].array[2] == current_face)
726                next_face =  StripEdges[id1][count].array[1];
727        else
728                next_face = StripEdges[id1][count].array[2];
729       
730   
731        if (StripFaceAdj[next_face].finish)
732          return -1;
733 
734        *NumAdj = StripFaceAdj[next_face].NumAdj;
735 
736        if( ((id1 == StripFaces[next_face].array[0]) && (id2 == StripFaces[next_face].array[1]))
737        || ((id2 == StripFaces[next_face].array[0]) && (id1 == StripFaces[next_face].array[1])))
738                there = true;
739
740        if( ((id1 == StripFaces[next_face].array[1]) && (id2 == StripFaces[next_face].array[2]))
741        || ((id2 == StripFaces[next_face].array[1]) && (id1 == StripFaces[next_face].array[2])))
742                there = true;
743
744        if(((id1 == StripFaces[next_face].array[0]) && (id2 ==StripFaces[next_face].array[2])) ||
745        ((id2 == StripFaces[next_face].array[0]) && (id1 ==StripFaces[next_face].array[2])))
746                there = true;
747 
748  if (!there)
749    return -1;
750  else
751    return next_face;
752}
753
754///     Look_Up:
755int CustomStripifier::Look_Up(int id1,int id2,int face_id)
756{
757  int x,count = 0;
758
759  GetLower(&id1,&id2);
760 
761  if (StripEdges[id1].empty())
762    return 0;
763 
764  while (StripEdges[id1][count].array[0] != id2)
765    {
766      count++;
767 
768          if (count>=StripEdges[id1].size())
769                return 0;
770    }
771
772  if ((StripEdges[id1][count].array[2] == face_id) || (StripEdges[id1][count].array[1] == face_id))
773  {
774      // The edge
775          if (((StripFaces[face_id].array[0]==id1)||(StripFaces[face_id].array[1]==id1)||(StripFaces[face_id].array[2]==id1))&&
776                 ((StripFaces[face_id].array[0]==id2)||(StripFaces[face_id].array[1]==id2)||(StripFaces[face_id].array[2]==id2)))
777                return 1;
778  }
779
780  return 0;
781}
782
783///     StoreStrip:
784void CustomStripifier::StoreStrip(int id, int where)
785{
786
787    if (where == 1)
788        {
789                Strips.push_back(id);
790        }
791    else
792        {
793                if (Strips.empty())
794                        Strips.push_back(id);
795                else
796                        Strips.insert(Strips.begin(),id);
797        }
798 
799}
800
801///     NumAdj:
802int CustomStripifier::NumAdj(int id1, int id2)
803{
804  int count=0;
805
806  GetLower(&id1,&id2);
807 
808  while (StripEdges[id1][count].array[0] != id2)
809    count++;
810
811  if (StripEdges[id1][count].array[2] == -1)
812    return 0;
813
814  return 1;
815}
816
817///     StoreAdjacency:
818void CustomStripifier::StoreAdjacency(int NumAdj,int face_id)
819{
820    StripFaceAdj[face_id].NumAdj = NumAdj;
821    StripFaceAdj[face_id].finish = false;
822
823        if (StripArray[NumAdj].empty())
824                StripArray[NumAdj].push_back(face_id);
825        else
826                StripArray[NumAdj].insert(StripArray[NumAdj].begin(),face_id);
827
828}
829
830///     Find_Adjacencies:
831void CustomStripifier::FindAdjacencies(int num_faces, int num_verts)
832{
833  int   x;
834  vector_vector3 aux;
835
836
837        for (x=0; x < num_verts; x++)
838                StripEdges.push_back(aux);
839
840        for (x=0;x<num_faces;x++)
841        {
842                if (x<StripFaces.size())
843                {
844                        //v1,v2,face,index
845                        AddAdjEdge(StripFaces[x].array[0],StripFaces[x].array[1],x);
846                        AddAdjEdge(StripFaces[x].array[1],StripFaces[x].array[2],x);
847                        AddAdjEdge(StripFaces[x].array[0],StripFaces[x].array[2],x);
848                }
849        }
850}
851
852///     Prediction:
853int CustomStripifier::Prediction()
854{
855  int id[60],t,x,f=0,min = 60;
856 
857        for (x = 0; x < last; x++)
858    {
859                t = MinimumAd(ties_array[x]);
860
861            if (t == min)
862                        id[f++] = ties_array[x];
863     
864                if (t < min)
865                {
866                        f = 0;
867                        min = t;
868                        id[f++] = ties_array[x];
869                }
870    }
871 
872        if ( f == 1)
873                return id[0];
874 
875        if (min == 0)
876                return id[0];
877
878        x = rand();
879
880        while (x >= f)
881                x = x/20;
882
883  return (id[x]);
884
885}
886
887///     AddNewFace:
888void CustomStripifier::AddNewFace(int ids[3], int face_id)
889{
890 
891  for (int i = 0; i < 3; i++)
892  {
893                StripFaces[face_id-1].array[i] = ids[i];
894
895                if (StripVertices[ids[i]].empty())
896                        StripVertices[ids[i]].push_back(face_id-1);
897                else
898                        StripVertices[ids[i]].insert(StripVertices[ids[i]].begin(),face_id-1);
899  }
900}
901
902///     AddAdjEdge:
903void CustomStripifier::AddAdjEdge(int v1,int v2,int fnum )
904{
905  int   flag    =       true;
906  int   t,count=0;
907  int   v3              =       -1;
908  vector3 aux;
909 
910        GetLower (&v1, &v2);
911
912        if (StripEdges[v1].empty())
913        {
914                flag    =       false;
915        }
916
917        while (flag)
918        {
919                if (v2 == StripEdges[v1][count].array[0])
920                {
921                        if (StripEdges[v1][count].array[2] == -1)
922                        {
923                                StripEdges[v1][count].array[2] = fnum;
924                        }
925                        else
926                        {
927                                v3      =       StripEdges[v1][count].array[2];
928
929                                mError  =       1;
930                        }
931
932                        flag = false;
933                }
934                else
935                {
936                        count++;
937
938                        if (count>=StripEdges[v1].size())
939                        {
940                                flag    =       false;
941                        }
942                }
943  }
944
945  if (count>=StripEdges[v1].size())
946  {
947        aux.array[0]    =       v2;
948        aux.array[1]    =       fnum;
949        aux.array[2]    =       v3;
950
951        StripEdges[v1].push_back(aux);
952  }
953}
954
955///     GetEdge:
956int CustomStripifier::GetEdge(int *edge1,int *edge2,int *index,int face_id)
957{
958  int x;
959  int reversed = -1;
960  int set = false;
961 
962  for (x=0; x< 3; x++)
963  {
964    if (x == 2)
965        {
966            if ((*(index) == 0) && (*(index+2)==0))
967                {
968              if (set)
969                        return 1;
970
971              reversed = 1;
972            }
973            else if ((*(index) == 0) && (*(index+2)==0))
974            {
975              if (set)
976                    return 0;
977              reversed = 0;
978            }
979         
980            if (Look_Up(*(index),*(index+2),face_id))
981            {
982             
983                  set = true;
984                  *edge1 = *(index);
985                  *edge2 = *(index+2);
986               
987              if ((reversed != -1)) 
988                    return reversed;
989            }
990        }               
991    else
992        {
993                if ((*(index+x) == 0) && (*(index+x+1)==0))
994            {
995              if (set)
996                        return 0;
997              reversed = 0;
998            }
999                else if ((*(index+x) == 0) && (*(index+x+1)==0))
1000            {
1001              if (set)
1002                        return 1;
1003              reversed = 1;
1004            }
1005         
1006                if (Look_Up(*(index+x),*(index+x+1),face_id))
1007            {
1008                  set = true;
1009                  *edge1 = *(index+x);
1010                  *edge2 = *(index+x + 1);
1011
1012              if ((reversed != -1))
1013                        return reversed;
1014            }
1015        }
1016  }                     
1017
1018        if ((x == 3) && (reversed != -1))
1019      exit(0);
1020
1021  return reversed;
1022}
1023
1024///     Update_FaceEx:
1025void CustomStripifier::UpdateFaces(int *next_NumAdj,int *min_face, int face_id, int *e1, int *e2,int temp1, int temp2,int *ties)
1026{
1027  int i;
1028  int there = false;
1029 
1030               
1031  if (face_id<StripFaces.size())
1032  {
1033    for (i = 0; i< 3; i++)
1034        {
1035                if (i != 2)
1036            {
1037              if( ((temp1 == StripFaces[face_id].array[i]) &&
1038                   (temp2 ==StripFaces[face_id].array[i+1])) ||
1039                   ((temp2 == StripFaces[face_id].array[i]) &&
1040                   (temp1 ==StripFaces[face_id].array[i+1])))
1041                                there = true;
1042            }
1043                else
1044            {
1045              if( ((temp1 == StripFaces[face_id].array[0]) &&
1046                   (temp2 ==StripFaces[face_id].array[2])) ||
1047                  ((temp2 == StripFaces[face_id].array[0]) &&
1048                   (temp1 ==StripFaces[face_id].array[2])))
1049                                        there = true;
1050            }
1051        }
1052     
1053    if (!there)
1054                return;
1055     
1056    if (StripFaceAdj[face_id].finish)
1057                return;
1058
1059        i = StripFaceAdj[face_id].NumAdj;
1060
1061    if (i==0)
1062                return;
1063
1064    StoreAdjacency(i-1,face_id);
1065
1066        StripArray[i].erase(find(StripArray[i].begin(), StripArray[i].end(), face_id));
1067
1068    if (*next_NumAdj == (i-1))
1069        {
1070          ties_array[last++] = face_id;
1071        }
1072
1073    if (*next_NumAdj > (i-1))
1074        {
1075          *next_NumAdj = i-1;
1076          *min_face = face_id;
1077          *e1 = temp1;
1078          *e2 = temp2;
1079          last=0;
1080          ties_array[last++] = face_id;
1081        }
1082  }
1083}
1084
1085///     DeleteAdj:
1086//Looking for another adajacent face
1087void CustomStripifier::DeleteAdj(int id1, int id2, int *next_NumAdj, int *min_face,
1088                                                                        int current_face, int *e1, int *e2, int *ties)
1089{
1090  int count=0;
1091  int next_face;
1092 
1093  GetLower(&id1,&id2);
1094 
1095  if (StripEdges[id1].empty())
1096    return;
1097
1098  while (StripEdges[id1][count].array[0] != id2)
1099  {
1100      count++;
1101
1102          if (count>=StripEdges[id1].size())
1103                return;
1104  }
1105
1106  if (StripEdges[id1][count].array[2] == -1) //No more adjacencies
1107  {
1108    return;
1109  }
1110  else
1111  {
1112    if (StripEdges[id1][count].array[2] == current_face)
1113          next_face = StripEdges[id1][count].array[1];
1114    else
1115          next_face = StripEdges[id1][count].array[2];
1116  }
1117
1118  UpdateFaces(next_NumAdj, min_face, next_face,e1,e2,id1,id2,ties);
1119}
1120
1121///     UpdateAdjacencies:
1122int CustomStripifier::UpdateAdjacencies(int face_id, int *next_NumAdj, int *e1, int *e2,  int *ties)
1123{
1124  int min_face = -1;
1125 
1126  *next_NumAdj = 60;
1127
1128  if ( face_id >= StripFaces.size() )
1129      exit(0);
1130
1131  DeleteAdj(StripFaces[face_id].array[0],StripFaces[face_id].array[1],
1132                        next_NumAdj,&min_face,face_id,e1,e2,ties);
1133  DeleteAdj(StripFaces[face_id].array[1],StripFaces[face_id].array[2],
1134                                next_NumAdj,&min_face,face_id,e1,e2,ties);
1135  DeleteAdj(StripFaces[face_id].array[0],StripFaces[face_id].array[2],
1136                                next_NumAdj,&min_face,face_id,e1,e2,ties);
1137
1138  return (min_face);
1139}
1140
1141///     Stripification:
1142void CustomStripifier::Stripification()
1143{
1144  int   max,NumAdj      =       0;
1145  int                                   whole_flag      =       true;
1146  int                                           dummy                           = 0;
1147  int                                           cont                            =       0;
1148  int face,ties=0;
1149 
1150  lastTri[0]=0;
1151  lastTri[1]=0;
1152  lastTri[2]=0;
1153 
1154  while (whole_flag)
1155  {
1156        NumAdj = -1;
1157
1158    while (NumAdj < 59)
1159        {
1160                NumAdj++;
1161       
1162                max = StripArray[NumAdj].size();
1163
1164                if (max > 0)
1165                {
1166                        face=StripArray[NumAdj][0];
1167
1168                        StoreTri(face,NumAdj,NumAdj,&ties,3,1);
1169
1170                        if (NumAdj >= 2)
1171                                        GoBack(face,&ties,3);
1172
1173                        break; 
1174                }
1175        }
1176
1177
1178        if ((NumAdj == 59) && (max == 0))
1179        {
1180                        whole_flag = false;
1181        }
1182    else
1183        {
1184                        AddTri(-1,-2,-3,-10,1);
1185                        lastTri[0]=0;
1186                        lastTri[1]=0;
1187                        lastTri[2]=0;
1188                        cont++;
1189        }
1190  }
1191}
1192
1193
1194///     Finished:
1195int CustomStripifier::Finished()
1196{
1197  int num,x,vertex1,vertex2;
1198  int id[2],other1,other2,index = 0,a,b,c;
1199  vector_int::iterator iter;
1200 
1201  num = Strips.size();
1202
1203  if (num==0)
1204        return 0;
1205
1206  if (num<4)
1207  {
1208                Orient(Strips[2]+1,Strips[1]+1,Strips[0]+1);
1209         
1210                my_vector[num_tiras].push_back(Strips[2]);
1211                my_vector[num_tiras].push_back(Strips[1]);
1212                my_vector[num_tiras].push_back(Strips[0]);
1213   
1214            Strips.clear();
1215
1216            return 1;
1217  }
1218 
1219  if (num<6)
1220  {
1221    exit(0);
1222  }
1223 
1224  vertex1 = Different(Strips[0],Strips[1],Strips[2], Strips[3],Strips[4],Strips[5], &other1,&other2);
1225  vertex2 = Different(Strips[3],Strips[4],Strips[5], Strips[0],Strips[1],Strips[2], &other1,&other2);
1226 
1227 if (Strips.size()>6)
1228    other1 = Different(Strips[8],Strips[3],Strips[4], Strips[6],Strips[7],Strips[8],&other1,&a);
1229 
1230  id[index] = vertex1; index = !index;
1231  id[index] = other1; index = !index;
1232  id[index] = other2; index = !index;
1233 
1234  a = Strips[3];
1235  b = Strips[4];
1236  c = Strips[5];
1237 
1238  Orient(vertex1+1,other1+1,other2+1);
1239   
1240  my_vector[num_tiras].push_back(vertex1);
1241  my_vector[num_tiras].push_back(other1);
1242  my_vector[num_tiras].push_back(other2);
1243
1244  for (x = 6; x < num ; x = x+3)
1245  {
1246    //    Error checking
1247        if (((id[0] != a) && (id[0] != b) && (id[0] != c)) ||
1248                ((id[1] != a) && (id[1] != b) && (id[1] != c)) ||
1249                ((vertex2 != a) && (vertex2 != b) && (vertex2 != c)))
1250    {
1251                vector_int nada;
1252                my_vector.push_back(nada);
1253
1254                num_tiras++;
1255
1256        vertex1 = Different(a,b,c,Strips[x],Strips[x+1],Strips[x+2],&other1,&other2);
1257        vertex2 = Different(Strips[x],Strips[x+1],Strips[x+2], a,b,c,&other1,&other2);
1258         
1259        id[index] = vertex1; index = !index;
1260        id[index] = other1; index = !index;
1261        id[index] = other2; index = !index;
1262        }
1263     
1264     
1265    if ((id[0] == id[1]) || (id[0] == vertex2))
1266        continue;
1267     
1268    if ((id[index] == Strips[x]) || (id[index] == Strips[x+1]) || (id[index] == Strips[x+2]))
1269    {
1270
1271                my_vector[num_tiras].push_back(id[index]);
1272
1273
1274        index = !index;
1275        }
1276     
1277        my_vector[num_tiras].push_back(vertex2);
1278
1279    id[index] = vertex2; index = !index;
1280     
1281        vertex2 =       Different(Strips[x],Strips[x+1],Strips[x+2], a,b,c,&other1,&other2);
1282        a               =       Strips[x];
1283        b               =       Strips[x+1];
1284        c               =       Strips[x+2];
1285  }
1286
1287  my_vector[num_tiras].push_back(vertex2);
1288
1289  Strips.clear();
1290
1291  return (num/3);       
1292}
1293
1294
1295///     ReadData: Loads the object in memory.
1296void CustomStripifier::ReadData(Geometry::SubMesh *geoSubMesh,int num_faces, int num_vert)
1297{
1298  int i,face_id =       0;
1299  vector3 aux;
1300  vector_int aux2;
1301
1302  //Allocate space for faces and vertices
1303  for (i=0; i<num_faces; i++)
1304                StripFaces.push_back(aux);
1305   
1306  for (i=0; i < num_vert; i++) 
1307                StripVertices.push_back(aux2);
1308
1309  for(unsigned int j = 0; j < geoSubMesh->mIndexCount; j = j + 3)
1310  {
1311                face_id++;
1312
1313                ids[0]=geoSubMesh->mIndex[j+0];
1314                ids[1]=geoSubMesh->mIndex[j+1];
1315                ids[2]=geoSubMesh->mIndex[j+2];
1316
1317                AddNewFace(ids,face_id);
1318  }
1319
1320  num_faces     = face_id;
1321
1322  if (StripFaceAdj != NULL)
1323  {
1324    free(StripFaceAdj);
1325  }
1326 
1327  StripFaceAdj = (adj*) malloc (sizeof(adj) * num_faces);
1328}
1329
1330
1331//-------------------------------------------------------------------------
1332//      Constructors.
1333//-------------------------------------------------------------------------
1334
1335MeshStripifier::MeshStripifier()
1336{
1337}
1338
1339MeshStripifier::MeshStripifier( const   Geometry::Mesh  *geoMesh)
1340{
1341}
1342
1343CustomStripifier::CustomStripifier()
1344{
1345}
1346CustomStripifier::CustomStripifier(     const   Geometry::Mesh  *geoMesh)
1347{
1348        MeshGlobal      =       new Geometry::Mesh();
1349        *MeshGlobal     =       *geoMesh;
1350
1351        //      Initialize the leaves submesh index.
1352        mSubMeshLeaves  =       -1;
1353
1354        //      Sets the actual progress bar function.
1355        mUPB    =       NULL;
1356}
1357
1358//-------------------------------------------------------------------------
1359//      Destroyers.
1360//-------------------------------------------------------------------------
1361CustomStripifier::~CustomStripifier()
1362{       
1363        printf("Voy a borrar\n");
1364        delete  MeshGlobal;
1365        printf("Borro\n");
1366}
1367
1368MeshStripifier::~MeshStripifier()
1369{
1370}
1371
1372//-------------------------------------------------------------------------
1373//      Public.
1374//-------------------------------------------------------------------------
1375
1376//-------------------------------------------------------------------------
1377//      Stripify.
1378//-------------------------------------------------------------------------
1379int CustomStripifier::Stripify()
1380{
1381        //      Init variables
1382        last                            =       0;
1383
1384        //      Make Triangle Strips.
1385        return  stripify(MeshGlobal);
1386}
1387
1388//-------------------------------------------------------------------------
1389//      GetMesh: Return de current Mesh.
1390//-------------------------------------------------------------------------
1391Mesh*   CustomStripifier::GetMesh()
1392{
1393        Mesh            *mesh_stripified;
1394
1395        mesh_stripified                 =       new Mesh();
1396        *mesh_stripified                =       *MeshGlobal;
1397
1398        return  mesh_stripified;
1399}
1400
1401//-------------------------------------------------------------------------
1402//      Set the progress bar function.
1403//-------------------------------------------------------------------------
1404void    CustomStripifier::SetProgressFunc(TIPOFUNC upb)
1405{
1406        //      Sets the actual progress bar function.
1407        mUPB    =       upb;
1408}
1409
1410//-------------------------------------------------------------------------
1411// Sets what is the submesh that stores the leaves.
1412//-------------------------------------------------------------------------
1413void CustomStripifier::SetSubMeshLeaves(size_t  submesh)
1414{
1415        mSubMeshLeaves  =       submesh;
1416}
Note: See TracBrowser for help on using the repository browser.