Changeset 2549 for GTP/trunk/Lib/Geom/shared
- Timestamp:
- 09/04/07 13:06:39 (17 years ago)
- Location:
- GTP/trunk/Lib/Geom/shared/GTGeometry
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMesh.h
r1070 r2549 6 6 #include <iostream> 7 7 #include <fstream> 8 #include <algorithm> 8 9 9 10 #include "GeoBase.h" -
GTP/trunk/Lib/Geom/shared/GTGeometry/include/GeoMeshStripifier.h
r2341 r2549 15 15 #include "GeoMesh.h" 16 16 17 typedef int BOOL; 18 typedef void * PVOID; 19 17 #define MAX_ADJ 60 20 18 21 19 namespace Geometry 22 20 { 23 24 #define TRIANGLE 3 25 #define MAGNITUDE 1000000 26 #define MAX_TIE 60 27 28 #define FALSE 0 29 #define TRUE 1 30 #define LISTHEAD 0 31 #define LISTTAIL 1 21 typedef struct 22 { 23 int array[3]; 24 } 25 vector3; 32 26 33 27 typedef struct 34 28 { 35 void *Next;36 void *Previous;37 38 myNode, * PNODE;29 int finish; 30 int NumAdj; 31 } 32 adj; 39 33 40 typedef struct List 41 { 42 /* link to the next Listinfo Structure */ 43 myNode ListNode; 44 45 /* user definable data */ 46 } 47 ListInfo, *PLISTINFO; 48 49 typedef struct LHead 50 { 51 PLISTINFO LHeaders[2]; 52 int NumList; 53 } 54 ListHead, *PLISTHEAD; 55 56 #define PEEKFROMHEAD( lh, ind ) ( PeekList( (lh), LISTHEAD, (ind) ) ) 57 #define PEEKFROMTAIL( lh, ind ) ( PeekList( (lh), LISTTAIL, (ind) ) ) 58 #define EMPTYLIST( lh ) ( ( (lh)->LHeaders[LISTHEAD] == NULL ) ) 59 #define NumOnList(lh) ( ((lh)->NumList) ) 60 #define GetNextNode(pli) ( ((pli)->ListNode.Next) ) 61 #define GetPrevNode(pli) ( ((pli)->ListNode.Previous) ) 62 63 //----- 64 65 /** polverts.h 66 */ 67 typedef struct adjacencies 68 { 69 myNode ListNode; 70 int face_id; 71 }ADJACENCIES,*P_ADJACENCIES; 72 73 typedef struct FVerts 74 { 75 myNode ListNode; 76 int *pPolygon; 77 int nPolSize; 78 int nId; 79 } F_VERTS, *PF_VERTS; 80 81 /*Every time we need to use this, cast it ( ListInfo*)*/ 82 typedef struct FEdges 83 { 84 myNode ListNode; 85 int edge[3]; 86 }F_EDGES,*PF_EDGES; 87 88 typedef struct FFaces 89 { 90 myNode ListNode; 91 int *pPolygon; 92 int *pNorms; 93 int seen; 94 int seen2; 95 int seen3; 96 int nPolSize; 97 int nOrgSize; 98 F_EDGES **VertandId; 99 int *marked; 100 int *walked; 101 }F_FACES,*PF_FACES; 34 typedef std::vector<int> vector_int; 35 typedef std::vector<vector3> vector_vector3; 102 36 103 typedef struct FVertices104 {105 myNode ListNode;106 PF_FACES face;107 }F_VERTICES, *PF_VERTICES;108 109 typedef struct Strips110 {111 myNode ListNode;112 int face_id;113 }Strips,*P_STRIPS;114 115 116 struct vert_added117 {118 int num;119 int *normal;120 };121 122 typedef struct face_adjacencies123 {124 P_ADJACENCIES pfNode;125 int bucket;126 ListHead *head;127 }128 FACE_ADJACENCIES, *P_FACE_ADJACENCIES;129 130 /** global.h131 */132 typedef std::vector<int> mi_vector_tipo;133 //std::vector<mi_vector_tipo> mi_vector;134 enum swap_type {ON,OFF};135 136 #define VRDATA double137 #define MAX1 60138 139 #define GEO_PI 3.1415926573140 #define ATOI(C) (C -'0')141 #define EVEN(x) (((x) & 1) == 0)142 #define MAX_BAND 10000143 144 struct vert_struct145 {146 VRDATA x, y, z; /* point coordinates */147 };148 149 37 /// Stripifier interface class. 150 38 /** This module implements methods that extract triangle strips from triangle meshes. … … 201 89 private: 202 90 203 /* Globals */ 204 int mError; // 0 OK. 205 // 1 Error: The mesh is not Manifold. 91 // Globals 92 int mError; 206 93 int num_faces; 207 ListHead **PolFaces; 208 ListHead **PolEdges; 209 ListHead *array[60]; 210 P_FACE_ADJACENCIES face_array; /* Pointers from face_id to face */ 211 ListHead **Vertices; /* Pointers from vertex_id to face */ 212 ListHead *strips[1]; 213 int orient; 94 95 std::vector<vector3> StripFaces; 96 std::vector<vector_vector3> StripEdges; 97 98 vector_int StripArray[MAX_ADJ]; 99 100 adj* StripFaceAdj; 101 102 std::vector<vector_int> StripVertices; 103 104 vector_int Strips; 105 214 106 int num_tiras; 215 int ids[MAX1]; 216 int norms[MAX1]; 217 int *vert_norms; 218 int *vert_texture; 219 int out1;//= -1; // static. 220 int out2;//= -1; // static. 221 int ties_array[60]; // static. 222 int last;//= 0; // static. 223 int out1Ex;// = -1; // static. 224 int out2Ex;// = -1; // static. 225 int *vn; 226 int *vt; 227 int norm; // static. 228 int text; // static. 229 BOOL resetting;// = FALSE; // static. 230 int added_quad;// = 0; // static. 231 BOOL reversed;// = FALSE; // static. 232 int patch;// = 0; // static. 107 int ids[3]; 108 int lastTri[3]; 109 int ties_array[60]; 110 int last; 233 111 234 /** global.h 235 */ 236 std::vector<mi_vector_tipo> mi_vector; 112 std::vector<vector_int> my_vector; 237 113 238 /** auxiliar.h239 */240 114 Geometry::Mesh *MeshGlobal; 241 // Structures for the object.242 vert_struct *vertices;243 vert_struct *nvertices;244 vert_struct *pvertices;245 vert_struct *pnvertices;246 115 247 /* General utility routines */ 248 /* %%s QueRoutines */ 249 BOOL InitList ( PLISTHEAD ); 116 int stripify( Geometry::Mesh *geoMesh); 250 117 251 /***************************************************************** 252 InitList : Initialize a new list structure for use with the List 253 routines 118 void GetLower(int *x, int *y); 119 int Different(int id1,int id2,int id3,int id4,int id5, int id6, int *x, int *y); 120 void Orient(int vertex1,int vertex2,int vertex3); 121 void StoreAdjacencies(int num_faces); 122 void ReadData(Geometry::SubMesh *geoSubMesh,int num_faces, int num_vert); 123 void Stripification(); 124 void AddTri(int id1, int id2, int id3, int flag, int where); 125 void GoBack(int face_id, int *ties,int tie); 126 void StoreTri(int face_id,int NumAdj, int original_adj, int *ties, int tie, int where); 254 127 255 INPUTS : LHead : a pointer to a ListHead structure. 256 OUTPUT : a boolean value TRUE if no errors occured FALSE 257 otherwise 258 ******************************************************************/ 128 int GetNumAdjacencies(int id1, int id2, int curr_id); 129 int MinimumAd(int id); 130 int Find_Face(int current_face, int id1,int id2, int *NumAdj); 131 int Look_Up(int id1,int id2,int face_id); 132 void StoreStrip(int id, int where); 133 int NumAdj(int id1, int id2); 134 void FindAdjacencies(int num_faces, int num_verts); 135 void StoreAdjacency(int NumAdj,int face_id); 136 int Prediction(); 137 void AddNewFace(int ids[3],int face_id); 138 void AddAdjEdge(int v1,int v2, int fnum); 139 int GetEdge( int *edge1,int *edge2,int *index,int face_id); 140 void DeleteAdj(int id1, int id2, int *next_NumAdj,int *min_face, 141 int current_face,int *e1,int *e2,int *ties); 142 int UpdateAdjacencies(int face_id,int *next_NumAdj, int *e1, int *e2,int *ties); 143 void UpdateFaces(int *next_NumAdj,int *min_face, int face_id, int *e1,int *e2,int temp1, int temp2,int *ties); 144 int Finished(); 259 145 260 146 261 PLISTINFO PeekList( PLISTHEAD, int, int );262 263 /*****************************************************************264 PeekList : This funciton peeks down a list for the N'th element265 from the HEAD or TAIL of the list266 267 INPUTS : LHead : a pointer to a List head structure.268 from : can either search from the HEAD or TAIL269 of the list270 where : how many nodes from the begining should the271 List routines look.272 OUTPUT : a pointer to a ListInfo structure identified by273 from/where or NULL if an error occurred.274 ******************************************************************/275 276 277 PLISTINFO RemoveList( PLISTHEAD LHead, PLISTINFO LInfo );278 279 280 /*****************************************************************281 RemoveList: Remove a ListInfo structure from a List.282 283 INPUTS : LHead : a pointer to a ListHead structure.284 LInfo : a pointer to the ListInfo structure to remove285 from the list.286 OUTPUT : a pointer to the ListInfo structure that was removed or287 NULL if an error occurred.288 ******************************************************************/289 290 BOOL InsertNode( PLISTHEAD LHead, int nPos, PLISTINFO LInfo );291 292 /*****************************************************************293 InsertNode: add a node to a list after a given node294 295 INPUTS : LHead : a pointer to a ListHead structure.296 nPos : the position to insert the node into297 LInfo : a pointer to the new node to add to the list.298 OUTPUT: a boolean value TRUE if all goes well false otherwise299 *****************************************************************/300 301 BOOL AddHead ( PLISTHEAD, PLISTINFO );302 303 /*****************************************************************304 AddHead : add a ListInfo structure to the HEAD of a list.305 306 INPUTS : LHead : a pointer to a ListHead structure of the list307 to add to.308 LInfo : a pointer to the ListInfo structure to add to309 the list.310 OUTPUT : A boolean value TRUE if no errors occurred FALSE311 otherwise.312 ******************************************************************/313 314 315 BOOL AddTail ( PLISTHEAD, PLISTINFO );316 317 /*****************************************************************318 AddTail : Add a ListInfo structure to the TAIL of a list.319 320 INPUTS : LHead : a pointer to a ListHead structure of the List321 to add to.322 LInfo : a pointer to the ListInfo structure to add to323 the List.324 OUTPUT : a boolean value TRUE if no errors occurred FALSE325 otherwise.326 ******************************************************************/327 328 329 PLISTINFO RemTail ( PLISTHEAD );330 331 /*****************************************************************332 RemTail : Remove a ListInfo structure from the TAIL of a List.333 334 INPUTS : LHead : a pointer to a ListHead structure of the List335 to remove from.336 OUTPUT : a pointer to the ListInfo structure that was removed337 or NULL if an error occurred.338 ******************************************************************/339 340 341 PLISTINFO RemHead ( PLISTHEAD );342 343 /*****************************************************************344 RemHead : Remove a ListInfo structure from the Head of a List.345 346 INPUTS : LHead : a pointer to a ListHead structure of the List347 to remove from.348 OUTPUT : a pointer to the ListInfo structure that was removed or349 NULL if an error occurred.350 ******************************************************************/351 352 PLISTINFO SearchList(353 PLISTHEAD lpListHead,354 PVOID lpSKey,355 int ( * CompareCallBack) ( PVOID, PVOID ) );356 357 /*****************************************************************358 SearchList:359 Try to find a specific node in the queue whose key matches with360 searching key. Return the pointer to that node if found, return NULL361 otherwise362 363 Input:364 lpHashTbl => a far pointer to the hash table365 lpKey => a far poniter to searching key366 CompareCallBack => comparision function367 368 Output: a far pointer to the node to be found369 370 ******************************************************************/371 372 /** init.h373 */374 BOOL InitVertexTable(int nSize);375 BOOL InitFaceTable(int nSize);376 BOOL InitEdgeTable(int nSize);377 void BuildFaceTable(int nSize);378 void BuildVertexTable(int nSize);379 void BuildEdgeTable(int nSize);380 void init_vert_norms(int num_vert);381 void init_vert_texture(int num_vert);382 void InitStripTable();383 void Init_Table_SGI(int numfaces);384 void Start_Vertex_Struct(int numverts);385 void Start_Face_Struct(int numfaces);386 void Start_Edge_Struct(int numverts);387 388 /** util.h389 */390 void switch_lower(int *x, int *y);391 BOOL member(int x , int id1, int id2, int id3);392 BOOL Exist(int face_id, int id1, int id2);393 int Different( int id1,int id2,int id3,int id4,int id5,394 int id6, int *x, int *y);395 int Return_Other(int *index,int e1,int e2);396 int Get_Other_Vertex(int id1,int id2,int id3,int *index);397 PLISTINFO Done(int face_id, int *bucket);398 void First_Edge(int *id1,int *id2, int *id3);399 void Last_Edge(int *id1, int *id2, int *id3, BOOL save);400 401 void preserve_strip_orientation_with_normal(402 int vertex1,403 int normal1,404 int vertex2,405 int normal2,406 int vertex3,407 int normal3);408 409 void preserve_strip_orientation_with_texture(410 int vertex1,411 int texture1,412 int vertex2,413 int texture2,414 int vertex3,415 int texture3);416 417 void preserve_strip_orientation_with_texture_and_normal(418 int vertex1,419 int texture1,420 int normal1,421 int vertex2,422 int texture2,423 int normal2,424 int vertex3,425 int texture3,426 int normal3);427 428 void preserve_strip_orientation(429 int vertex1,430 int vertex2,431 int vertex3);432 433 void find_triangle_orientation( int vertex1,434 int vertex2,435 int vertex3,436 int *original_vertex);437 438 /** local.h439 */440 void Find_StripsEx(int *ties, int tie, int triangulate, int swaps, int *next_id);441 void SGI_Strip(int num_faces,int ties,int triangulate);442 443 /** outputex.h444 */445 void Output_TriEx(int id1, int id2, int id3, int flag,int where);446 void Extend_BackwardsEx(int face_id, int *ties,447 int tie, int triangulate,448 int swaps,int *next_id);449 void Polygon_OutputEx(P_ADJACENCIES temp,int face_id,int bucket,450 ListHead *pListHead,451 int *ties, int tie,int triangulate, int swaps,452 int *next_id, int where);453 454 /** sgi_triang.h455 */456 int Adjacent(int id2,int id1, int *list, int size);457 void Build_SGI_Table(int num_faces);458 void Non_Blind_Triangulate( int size,int *index,459 int next_face_id,460 int face_id,int where,461 int color1,int color2,int color3);462 void Blind_Triangulate(int size, int *index, BOOL begin, int where);463 void Rearrange_Index(int *index, int size); // static.464 void Delete_From_List(int id,int *list, int *size); // static.465 void Triangulate_Quad(int out_edge1,int out_edge2,int in_edge1,466 int in_edge2,int size,int *index,467 int reversed,int where); // static.468 void Triangulate_Polygon( int out_edge1,int out_edge2,469 int in_edge1, int in_edge2,470 int size, int *index,471 int reversed,472 int face_id, int where,473 int color1, int color2,474 int color3); // static.475 476 void Triangulate( int out_edge1,int out_edge2,int in_edge1,477 int in_edge2,int size,int *index,478 int reversed,int face_id, int where,479 int color1, int color2,int color3); // static.480 481 /** struct.h482 */483 int Get_Edge( int *edge1,int *edge2,484 int *index,int face_id,485 int size, int id1, int id2);486 int Update_Adjacencies( int face_id,int *next_bucket,487 int *e1,int *e2,int *ties);488 void Update_Face( int *next_bucket, int *min_face,489 int face_id, int *e1,490 int *e2, int temp1,491 int temp2, int *ties); // static.492 void Delete_Adj(int id1, int id2,int *next_bucket,493 int *min_face,int current_face,int *e1,494 int *e2,int *ties); // static.495 /** common.h496 */497 int Old_Adj(int face_id);498 int Number_Adj(int id1, int id2, int curr_id);499 int Min_Adj(int id);500 void Check_In_Polygon(int face_id, int *min, int size);501 void New_Face (int face_id, int v1, int v2, int v3);502 void New_Size_Face(int face_id);503 void Check_In_Quad(int face_id,int *min);504 int Get_Output_Edge(int face_id, int size, int *index,int id2,int id3);505 void Get_Input_Edge(int *index,int id1,506 int id2,int id3,507 int *new1,int *new2,508 int size,int face_id);509 int Find_Face(int current_face, int id1,510 int id2, int *bucket);511 BOOL Look_Up(int id1,int id2,int face_id);512 void Add_Id_Strips(int id, int where);513 int Num_Adj(int id1, int id2);514 void Add_Sgi_Adj(int bucket,int face_id);515 void Find_Adjacencies(int num_faces);516 void Edge_Least(int *index,int *new1,517 int *new2,int face_id,int size); // static.518 519 /** ties.h520 */521 void Clear_Ties();522 void Add_Ties(int id);523 int Get_Next_Face(int t, int face_id, int triangulate);524 int Alternate_Tie(); // static.525 int Random_Tie(); // static.526 int Look_Ahead(int id); // static.527 int Random_Look(int id[],int count); // static.528 int Look_Ahead_Tie(); // static.529 int Sequential_Tri(int *index); // static.530 int Sequential_Quad(int *index, int triangulate); // static.531 void Whole_Output(int in1, int *index, int size,532 int *out1,int *out2); // static.533 int Sequential_Poly(int size,int *index,int triangulate); // static.534 int Sequential_Tie(int face_id,int triangulate); // static.535 536 /** add.h537 */538 BOOL norm_array(int id,int vertex,539 double normal_difference,540 struct vert_struct *n,int num_vert);541 void add_texture(int id,BOOL vertex);542 int add_vert_id(int id, int index_count);543 void add_norm_id(int id, int index_count);544 void AddNewFace(int ids[MAX1],int vert_count,545 int face_id,int norms[MAX1]);546 void CopyFace(int ids[MAX1],int vert_count,547 int face_id,int norms[MAX1]);548 void Add_AdjEdge( int v1,int v2,549 int fnum,int index1);550 BOOL new_vertex(double difference,int id1,551 int id2,struct vert_struct *n); // static.552 BOOL Check_VN(int vertex,int normal, struct vert_added *added); // static.553 554 /** options.h555 */556 enum file_options {ASCII,BINARY};557 enum tie_options {FIRST, RANDOM, ALTERNA, LOOK, SEQUENTIAL};558 enum triangulation_options {PARTIAL,WHOLE};559 560 void print_usage(void);561 float get_options(int argc, char **argv,562 int *f, int *t,563 int *tr, int *group,564 int *orientation);565 int power_10(int power); // static.566 float power_negative(int power); // static.567 float convert_array(int num[],int stack_size); // static.568 569 /** sgi_triangex.h570 */571 int AdjacentEx(int id2,int id1, int *list, int size);572 void Delete_From_ListEx(int id,int *list, int size);573 void Triangulate_PolygonEx( int out_edge1,int out_edge2,int in_edge1,574 int in_edge2,int size,int *index,575 int reversed,int face_id,576 int where);577 void Non_Blind_TriangulateEx( int size,int *index,578 int next_face_id,579 int face_id,int where);580 void Rearrange_IndexEx(int *index, int size);581 void Blind_TriangulateEx( int size, int *index,582 BOOL begin, int where);583 void Triangulate_QuadEx(int out_edge1,int out_edge2,int in_edge1,584 int in_edge2, int size, int *index,585 int reversed, int where); // static.586 void TriangulateEx( int out_edge1,int out_edge2,587 int in_edge1, int in_edge2,588 int size, int *index,589 int reversed,590 int face_id, int where); // static.591 592 /** structex.h593 */594 int Get_EdgeEx( int *edge1,int *edge2,int *index,int face_id,595 int size, int id1, int id2);596 void Delete_AdjEx(int id1, int id2,597 int *next_bucket,int *min_face,598 int current_face,int *e1,599 int *e2,int *ties);600 int Change_FaceEx(int face_id,int in1,int in2,601 ListHead *pListHead, BOOL no_check);602 int Update_AdjacenciesEx( int face_id,int *next_bucket,603 int *e1, int *e2,604 int *ties);605 int Min_Face_AdjEx(int face_id,int *next_bucket,int *ties);606 607 void Update_FaceEx( int *next_bucket,int *min_face,608 int face_id, int *e1,609 int *e2,int temp1,610 int temp2,int *ties); // static.611 612 void Find_Adj_TallyEx(int id1, int id2,613 int *next_bucket, int *min_face,614 int current_face, int *ties); // static.615 616 /** partial.h617 */618 void Partial_Triangulate(int size, int *index,619 int next_face_id,620 int face_id, int *next_id,621 ListHead *pListHead,622 P_ADJACENCIES temp, int where);623 624 625 void Inside_Polygon(int size, int *index,626 int face_id, ListHead *pListHead,627 int where);628 629 void P_Triangulate_Quad(int out_edge1,int out_edge2,630 int in_edge1, int in_edge2,631 int size, int *index,632 int reversed, int face_id,633 ListHead *pListHead,634 P_ADJACENCIES temp,635 int where); // static.636 void P_Triangulate_Polygon( int out_edge1,int out_edge2,637 int in_edge1, int in_edge2,638 int size, int *index,639 int reversed,640 int face_id, int *next_id,641 ListHead *pListHead,642 P_ADJACENCIES temp2,643 int where); // static.644 void P_Triangulate( int out_edge1,int out_edge2,int in_edge1,645 int in_edge2, int size, int *index,646 int reversed, int face_id,647 int *next_id, ListHead *pListHead,648 P_ADJACENCIES temp,int where); // static.649 void Input_Edge(int face_id, int *index,650 int size, int in_edge1,651 int in_edge2, ListHead *pListHead,652 int where); // static.653 654 /** output.h655 */656 int Finished(int *swap, int startnewstrip);657 void Output_Tri(int id1, int id2, int id3,BOOL end);658 int Extend_Face(int face_id,int e1,int e2,int *swaps,659 int color1,int color2,int color3,int *vert_norm,660 int normals,int *vert_texture,int texture);661 int Polygon_Output( P_ADJACENCIES temp, int face_id,662 int bucket, ListHead *pListHead,663 BOOL first, int *swaps,664 int color1, int color2,665 int color3,666 BOOL global, BOOL end); // static.667 /** free.h668 */669 void Free_Strips();670 void End_Face_Struct(int numfaces);671 void End_Edge_Struct(int numverts);672 void ParseAndFreeList( ListHead *pListHead ); // static.673 void FreeFaceTable(int nSize); // static.674 void FreeEdgeTable(int nSize); // static.675 676 /** newpolve.h677 */678 void Find_Bands(int numfaces, int *swaps, int *bands,679 int *cost, int *tri, int norms, int *vert_norms,680 int texture, int *vert_texture);681 void Save_Walks(int numfaces);682 void Save_Rest(int *numfaces);683 int Calculate_Walks(int lastvert,int y, PF_FACES temp2); // static.684 BOOL Check_Right( int last_seen,PF_FACES temp2,685 int y,int face_id); // static.686 int Update_and_Test(PF_FACES temp2,int y,687 BOOL first,int distance,688 int lastvert, int val); // static.689 int Test_Adj( PF_FACES temp2,int x,690 int north,int distance,691 int lastvert, int value); // static.692 int Find_Max( PF_FACES temp2, int lastvert,693 int north, int left,694 int *lastminup, int *lastminleft); // static.695 void Mark_Face( PF_FACES temp2, int color1,696 int color2, int color3,697 BOOL end,698 int *edge1, int *edge2,699 int *face_id, int norms,700 int texture); // static.701 void Assign_Walk( int lastvert, PF_FACES temp2,702 int front_walk, int y,703 int back_walk); // static.704 void Fast_Reset(int x); // static.705 void Reset_Max( PF_FACES temp2,int face_id,706 int north,int last_north,707 int orientation,int last_left,708 int color1,709 int color2,int color3,710 BOOL start); // static.711 int Peel_Max( PF_FACES temp2,int face_id,712 int north,int last_north,713 int orientation,int last_left,714 int color1,715 int color2,int color3,716 BOOL start, int *swaps_added,717 int norms, int texture); // static.718 719 /** auxiliar.h720 */721 // FILE *OpenOutputFile(char *fname);722 void AllocateStruct(int num_faces,723 int num_vert,724 int num_nvert,725 int num_texture);726 void miReadFile(char *fname, char *file_open, Geometry::SubMesh *geoSubMesh);727 int stripify( char *fname,728 Geometry::Mesh *geoMesh);729 147 730 148 public: -
GTP/trunk/Lib/Geom/shared/GTGeometry/src/GeoMeshStripifier.cpp
r2341 r2549 19 19 //------------------------------------------------------------------------- 20 20 21 //------------------------------------------------------------------------- 22 // InitList. 23 //------------------------------------------------------------------------- 24 BOOL CustomStripifier::InitList(PLISTHEAD LHead) 25 { 26 if (LHead == NULL) 27 { 28 return FALSE; 29 } 30 31 LHead->LHeaders[LISTHEAD] = LHead->LHeaders[LISTTAIL] = NULL; 32 LHead->NumList = 0; 33 34 return TRUE; 35 } 36 37 //------------------------------------------------------------------------- 38 // AddHead. 39 //------------------------------------------------------------------------- 40 BOOL CustomStripifier::AddHead(PLISTHEAD LHead, PLISTINFO LInfo) 41 { 42 if (LHead == NULL || LInfo == NULL) 43 { 44 return(FALSE); 45 } 46 47 if (EMPTYLIST(LHead)) 48 { 49 LHead->LHeaders[LISTTAIL] = LInfo; 50 } 51 else 52 { 53 LHead->LHeaders[LISTHEAD]->ListNode.Previous = (void *) LInfo; 54 } 55 56 LInfo->ListNode.Next = (void *) LHead->LHeaders[LISTHEAD]; 57 LHead->LHeaders[LISTHEAD] = LInfo; 58 LInfo->ListNode.Previous = NULL; 59 LHead->NumList++; 60 61 return(TRUE); 62 } 63 64 /// AddTail 65 BOOL CustomStripifier::AddTail(PLISTHEAD LHead, PLISTINFO LInfo) 66 { 67 if (LHead == NULL || LInfo == NULL) 68 { 69 return FALSE; 70 } 71 72 if (EMPTYLIST(LHead)) 73 { 74 LHead->LHeaders[LISTHEAD] = LInfo; 75 } 76 else 77 { 78 LHead->LHeaders[LISTTAIL]->ListNode.Next = (void *) LInfo; 79 } 80 81 LInfo->ListNode.Previous = (void *) LHead->LHeaders[LISTTAIL]; 82 LHead->LHeaders[LISTTAIL] = LInfo; 83 LInfo->ListNode.Next = NULL; 84 LHead->NumList++; 85 86 return TRUE; 87 } 88 89 /// InsertNode 90 BOOL CustomStripifier::InsertNode( PLISTHEAD LHead, int nPos, PLISTINFO LInfo ) 91 { 92 PLISTINFO add_node; 93 94 if ( LHead == NULL || LInfo == NULL || nPos > NumOnList( LHead ) ) 95 { 96 return FALSE; 97 } 98 99 if ( nPos == 0 ) 100 { 101 AddHead( LHead, LInfo ); 102 } 103 else if ( nPos == NumOnList( LHead ) ) 104 { 105 AddTail( LHead, LInfo ); 106 } 107 else 108 { 109 if ( (add_node = PeekList( LHead, LISTHEAD, nPos - 1 )) == NULL ) 21 22 /// stripify: Make triangle strips for a given mesh. 23 int 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) 110 50 { 111 return FALSE; 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 112 263 } 113 114 ((PLISTINFO)add_node->ListNode.Next)->ListNode.Previous = LInfo; 115 116 LInfo->ListNode.Next = add_node->ListNode.Next; 117 LInfo->ListNode.Previous = add_node; 118 add_node->ListNode.Next = LInfo; 119 LHead->NumList++; 120 } 121 122 return TRUE; 123 } 124 125 /// RemHead: 126 PLISTINFO CustomStripifier::RemHead(PLISTHEAD LHead) 127 { 128 PLISTINFO t, t1; 129 130 if ( LHead == NULL || EMPTYLIST(LHead) ) 131 { 132 return NULL; 133 } 134 135 t = LHead->LHeaders[LISTHEAD]; 136 LHead->LHeaders[LISTHEAD] = (PLISTINFO) t->ListNode.Next; 137 138 if (LHead->LHeaders[LISTHEAD] != NULL) 139 { 140 t1 = (PLISTINFO) t->ListNode.Next; 141 t1->ListNode.Previous = NULL; 142 } 143 else 144 { 145 LHead->LHeaders[LISTTAIL] = NULL; 146 } 147 148 LHead->NumList--; 149 150 return t; 151 } 152 153 /// RemTail: 154 PLISTINFO CustomStripifier::RemTail(PLISTHEAD LHead) 155 { 156 PLISTINFO t, t1; 157 158 if ( LHead == NULL || EMPTYLIST(LHead) ) 159 { 160 return NULL; 161 } 162 163 t = LHead->LHeaders[LISTTAIL]; 164 LHead->LHeaders[LISTTAIL] = (PLISTINFO) t->ListNode.Previous; 165 166 if (LHead->LHeaders[LISTTAIL] != NULL) 167 { 168 t1 = (PLISTINFO) t->ListNode.Previous; 169 t1->ListNode.Next = NULL; 170 } 171 else 172 { 173 LHead->LHeaders[LISTHEAD] = NULL; 174 } 175 176 LHead->NumList--; 177 178 return t; 179 } 180 181 /// PeekList: 182 PLISTINFO CustomStripifier::PeekList(PLISTHEAD LHead, int wch, int index ) 183 { 184 PLISTINFO t; 185 186 if (LHead == NULL) 187 { 188 return NULL; 189 } 190 191 if ( (t = LHead->LHeaders[wch]) == NULL ) 192 { 193 return NULL; 194 } 195 196 for (; t != NULL && index > 0; index-- ) 197 { 198 t = (wch == LISTHEAD) ? (PLISTINFO) t->ListNode.Next 199 : (PLISTINFO) t->ListNode.Previous; 200 } 201 202 return t; 203 } 204 205 /// RemoveList: 206 PLISTINFO CustomStripifier::RemoveList(PLISTHEAD LHead, PLISTINFO LInfo ) 207 { 208 PLISTINFO t; 209 PLISTINFO t1; 210 211 t = LInfo; 212 213 if (LHead == NULL) 214 { 215 return NULL; 216 } 217 218 if (LHead->LHeaders[LISTHEAD] == t) 219 { 220 t = (PLISTINFO) RemHead(LHead); 221 } 222 else if (LHead->LHeaders[LISTTAIL] == t) 223 { 224 t = (PLISTINFO) RemTail(LHead); 225 } 226 else 227 { 228 t1 = (PLISTINFO) t->ListNode.Previous; 229 t1->ListNode.Next = t->ListNode.Next; 230 t1 = (PLISTINFO) t->ListNode.Next; 231 t1->ListNode.Previous = t->ListNode.Previous; 232 LHead->NumList--; 233 } 234 235 return t; 236 } 237 238 /// SearchList: 239 /// Try to find a specific node in the queue whose key matches with 240 /// searching key. Return the pointer to that node if found, return NULL 241 /// otherwise 242 /// @param lpHashTbl => a far pointer to the hash table. 243 /// @param lpKey => a far poniter to searching key. 244 /// @param CompareCallBack => comparision function. 245 /// @return a far pointer to the node to be found. 246 PLISTINFO CustomStripifier::SearchList( 247 PLISTHEAD listHead, 248 PVOID lpSKey, 249 int (* CompareCallBack) ( PVOID, PVOID ) ) 250 { 251 PLISTINFO list_info; 252 253 list_info = PeekList( listHead, LISTHEAD, 0); 254 255 while ( list_info != NULL ) 256 { 257 if ( CompareCallBack( list_info, lpSKey ) ) 258 { 259 break; 260 } 261 262 list_info = (PLISTINFO) GetNextNode( list_info ); 263 } 264 265 return list_info; 266 } 267 268 /// init_vert_norms: 269 void CustomStripifier::init_vert_norms(int num_vert) 270 { 271 /* Initialize vertex/normal array to have all zeros to 272 start with. 273 */ 274 register int x; 275 276 for (x = 0; x < num_vert; x++) 277 { 278 *(vert_norms + x) = 0; 279 } 280 } 281 282 /// init_vert_texture: 283 void CustomStripifier::init_vert_texture(int num_vert) 284 { 285 /* Initialize vertex/normal array to have all zeros to 286 start with. 287 */ 288 register int x; 289 290 for (x = 0; x < num_vert; x++) 291 { 292 *(vert_texture + x) = 0; 293 } 294 } 295 296 /// InitVertexTable: 297 BOOL CustomStripifier::InitVertexTable( int size ) 298 { 299 register int index; 300 301 /* Initialize the face table */ 302 Vertices = (ListHead**) malloc(sizeof(ListHead*) * size ); 303 304 if (Vertices) 305 { 306 for (index = 0; index < size; index++) 307 { 308 Vertices[index] = NULL; 309 } 310 311 return TRUE; 312 313 } 314 315 return FALSE; 316 } 317 318 /// InitFaceTable: 319 BOOL CustomStripifier::InitFaceTable( int size ) 320 { 321 register int index; 322 323 /* Initialize the face table */ 324 PolFaces = (ListHead**) malloc(sizeof(ListHead*) * size); 325 326 if (PolFaces) 327 { 328 for (index = 0; index < size; index++) 329 { 330 PolFaces[index] = NULL; 331 } 332 333 return TRUE; 334 } 335 336 return FALSE; 337 } 338 339 /// InitEdgeTable: 340 BOOL CustomStripifier::InitEdgeTable( int size ) 341 { 342 register int index; 343 344 /* Initialize the edge table */ 345 PolEdges = (ListHead**) malloc(sizeof(ListHead*) * size ); 346 347 if (PolEdges) 348 { 349 for (index=0; index < size; index++) 350 { 351 PolEdges[index] = NULL; 352 } 353 354 return TRUE; 355 } 356 357 return FALSE; 358 } 359 360 /// InitStripTable: 361 void CustomStripifier::InitStripTable( ) 362 { 363 364 PLISTHEAD list_head; 365 366 /* Initialize the strip table */ 367 list_head = (PLISTHEAD) malloc(sizeof(ListHead)); 368 369 if (list_head) 370 { 371 InitList(list_head); 372 373 strips[0] = list_head; 374 } 375 else 376 { 377 printf("Out of memory !\n"); 378 379 exit(0); 380 } 381 382 } 383 384 /// Init_Table_SGI: 385 void CustomStripifier::Init_Table_SGI(int numFaces) 386 { 387 PLISTHEAD list_head; 388 int max_adj = 60; 389 register int x; 390 391 /* This routine will initialize the table that will 392 have the faces sorted by the number of adjacent polygons 393 to it. 394 */ 395 396 for (x=0; x< max_adj; x++) 397 { 398 /* We are allowing the max number of sides of a polygon 399 to be max_adj. 400 */ 401 list_head = (PLISTHEAD) malloc(sizeof(ListHead)); 402 403 if (list_head) 404 { 405 InitList(list_head); 406 407 array[x] = list_head; 408 } 409 else 410 { 411 printf("Out of memory !\n"); 412 exit(0); 413 } 414 } 415 416 if (face_array != NULL) /* It seems this function is called more than */ 417 { 418 free(face_array); /* once so we'll free up the old stuff */ 419 } 420 421 face_array = (P_FACE_ADJACENCIES) malloc (sizeof(FACE_ADJACENCIES) * numFaces); 422 423 if (face_array == NULL) 424 { 425 printf("Out of memory !!\n"); 426 exit(0); 427 } 428 429 } 430 431 /// BuildVertexTable: 432 void CustomStripifier::BuildVertexTable(int size) 433 { 434 register int index; 435 PLISTHEAD list_head; 436 437 for (index = 0; index < size; index++) 438 { 439 list_head = (PLISTHEAD) malloc(sizeof(ListHead)); 440 441 if (list_head) 442 { 443 InitList(list_head); 444 445 Vertices[index] = list_head; 446 } 447 else 448 { 449 return; 450 } 451 452 } 453 } 454 455 /// BuildFaceTable: 456 void CustomStripifier::BuildFaceTable( int size ) 457 { 458 register int index; 459 PLISTHEAD list_head; 460 461 for (index = 0; index < size; index++) 462 { 463 list_head = (PLISTHEAD) malloc(sizeof(ListHead)); 464 465 if (list_head) 466 { 467 InitList(list_head); 468 469 PolFaces[index] = list_head; 470 } 471 else 472 { 473 return; 474 } 475 } 476 } 477 478 /// BuildEdgeTable: 479 void CustomStripifier::BuildEdgeTable( int size ) 480 { 481 register int index; 482 PLISTHEAD list_head; 483 484 for (index = 0; index < size; index++) 485 { 486 list_head = (PLISTHEAD) malloc(sizeof(ListHead)); 487 488 if (list_head) 489 { 490 InitList(list_head); 491 492 PolEdges[index] = list_head; 493 } 494 else 495 { 496 return; 497 } 498 } 499 } 500 501 /// Start_Vertex_Struct: 502 void CustomStripifier::Start_Vertex_Struct(int numVerts) 503 { 504 if (InitVertexTable(numVerts)) 505 { 506 BuildVertexTable(numVerts); 507 } 508 } 509 510 /// Start_Face_Struct: 511 void CustomStripifier::Start_Face_Struct(int numFaces) 512 { 513 if (InitFaceTable(numFaces)) 514 { 515 BuildFaceTable(numFaces); 516 } 517 } 518 519 /// Start_Edge_Struct: 520 void CustomStripifier::Start_Edge_Struct(int numVerts) 521 { 522 if (InitEdgeTable(numVerts)) 523 { 524 BuildEdgeTable(numVerts); 525 } 526 } 527 528 /// switch_lower: 529 void CustomStripifier::switch_lower (int *x, int *y) 530 { 531 register int temp; 532 533 /* Put lower value in x */ 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: 277 void CustomStripifier::GetLower (int *x, int *y) 278 { 279 int temp; 280 534 281 if (*y < *x) 535 282 { … … 540 287 } 541 288 542 /// member:543 BOOL CustomStripifier::member(int x , int id1, int id2, int id3)544 {545 /* Is x in the triangle specified by id1,id2,id3 */546 if ((x != id1) && (x != id2) && (x != id3))547 {548 return FALSE;549 }550 551 return TRUE;552 }553 554 /// Exist:555 BOOL CustomStripifier::Exist(int faceId, int id1, int id2)556 {557 /* Does the edge specified by id1 and id2 exist in this558 face currently? Maybe we deleted in partial triangulation559 */560 ListHead *list_head;561 PF_FACES temp;562 register int x,size;563 BOOL a = FALSE;564 BOOL b = FALSE;565 566 list_head = PolFaces[faceId];567 568 temp = (PF_FACES) PeekList(list_head, LISTHEAD, 0);569 size = temp->nPolSize;570 571 for (x=0; x<size; x++)572 {573 if (*(temp->pPolygon+x) == id1)574 {575 a = TRUE;576 }577 578 if (*(temp->pPolygon+x) == id2)579 {580 b = TRUE;581 }582 583 if (a && b)584 {585 return TRUE;586 }587 }588 589 return FALSE;590 }591 592 289 /// Different: 290 //Return the vertex of the first triangle that is not in the second 593 291 int CustomStripifier::Different(int id1,int id2,int id3,int id4,int id5, int id6, int *x, int *y) 594 292 { 595 /* Find the vertex in the first 3 numbers that does not exist in596 the last three numbers597 */598 293 if ((id1 != id4) && (id1 != id5) && (id1 != id6)) 599 294 { … … 615 310 } 616 311 617 /* Because there are degeneracies in the data, this might occur */618 312 *x = id5; 619 313 *y = id6; 314 620 315 return id4; 621 316 } 622 317 623 /// Return_Other: 624 int CustomStripifier::Return_Other(int *index,int e1,int e2) 625 { 626 /* We have a triangle and want to know the third vertex of it */ 627 register int x; 628 629 for (x=0;x<3;x++) 630 { 631 if ((*(index+x) != e1) && (*(index+x) != e2)) 632 return *(index+x); 633 } 634 /* If there is a degenerate triangle return arbitrary */ 635 return e1; 636 } 637 638 /// Get_Other_Vertex: 639 int CustomStripifier::Get_Other_Vertex(int id1,int id2,int id3,int *index) 640 { 641 /* We have a list index of 4 numbers and we wish to 642 return the number that is not id1,id2 or id3 643 */ 644 register int x; 645 646 for (x=0; x<4; x++) 647 { 648 if ((*(index+x) != id1) && (*(index+x) != id2) && 649 (*(index+x) != id3)) 650 return *(index+x); 651 } 652 /* If there is some sort of degeneracy this might occur, 653 return arbitrary 654 */ 655 // if (x==4) 656 return id1; 657 } 658 659 /// Done: 660 PLISTINFO CustomStripifier::Done(int face_id, int *bucket) 661 { 662 /* Check to see whether the polygon with face_id was used 663 already, return NULL if it was, otherwise return a pointer to the face. 664 */ 665 666 PLISTINFO lpListInfo; 667 668 lpListInfo = (PLISTINFO) face_array[face_id].pfNode; 669 if (lpListInfo != NULL) { 670 *bucket = face_array[face_id].bucket; 671 return lpListInfo; 672 } 673 else 674 return lpListInfo; 675 } 676 677 /// First_Edge: 678 void CustomStripifier::First_Edge(int *id1,int *id2, int *id3) 679 { 680 /* Get the first triangle in the strip we just found, we will use this to 681 try to extend backwards in the strip 682 */ 683 684 ListHead *pListHead; 685 register int num; 686 P_STRIPS temp1,temp2,temp3; 687 688 pListHead = strips[0]; 689 num = NumOnList(pListHead); 690 691 /* Did not have a strip */ 692 if (num < 3) 693 return; 694 695 temp1 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 0); 696 temp2 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 1); 697 temp3 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 2); 698 *id1 = temp1->face_id; 699 *id2 = temp2->face_id; 700 *id3 = temp3->face_id; 701 702 } 703 704 /// Last_Edge: 705 void CustomStripifier::Last_Edge(int *id1, int *id2, int *id3, BOOL save) 706 { 707 /* We need the last edge that we had */ 708 static int v1, v2, v3; 709 710 if (save) 711 { 712 v1 = *id1; 713 v2 = *id2; 714 v3 = *id3; 715 } 716 else 717 { 718 *id1 = v1; 719 *id2 = v2; 720 *id3 = v3; 721 } 722 } 723 724 /// find_triangle_orientation: 725 void CustomStripifier::find_triangle_orientation(int vertex1,int vertex2,int vertex3, 726 int *original_vertex) 727 { 728 int vertices,index; 729 PF_VERTICES verts; 730 731 /* Search through face to match orignal vertices */ 732 733 /* Start with vertex1's Vertices struct */ 734 verts = (PF_VERTICES) PeekList(Vertices[vertex1-1],LISTHEAD,0); 735 do { 736 index = 0; 737 for (vertices = 0; vertices < verts->face->nOrgSize;vertices++) { 738 if (vertex1 == verts->face->pPolygon[vertices]+1 || 739 vertex2 == verts->face->pPolygon[vertices]+1 || 740 vertex3 == verts->face->pPolygon[vertices]+1 ) 741 original_vertex[index++] = verts->face->pPolygon[vertices]+1; 742 if (index == 3) 743 break; 744 } 745 if (index == 3) 746 break; 747 } while ((verts = (PF_VERTICES) GetNextNode(verts)) != NULL); 748 749 if (index != 3) { 750 /* Search vertex2's Vertices struct */ 751 verts = (PF_VERTICES) PeekList(Vertices[vertex2-1],LISTHEAD,0); 752 do { 318 ///Orient: 319 void 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++; 753 367 index = 0; 754 for (vertices = 0; vertices < verts->face->nOrgSize;vertices++) {755 if (vertex1 == verts->face->pPolygon[vertices]+1 || 756 vertex2 == verts->face->pPolygon[vertices]+1 ||757 vertex3 == verts->face->pPolygon[vertices]+1 )758 original_vertex[index++] = verts->face->pPolygon[vertices]+1; 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 759 373 if (index == 3) 760 374 break; 761 375 } 762 if (index == 3) 763 break; 764 } while ((verts = (PF_VERTICES) GetNextNode(verts)) != NULL); 765 } 766 767 if (index != 3) { 768 /* Search vertex3's Vertices struct */ 769 verts = (PF_VERTICES) PeekList(Vertices[vertex3-1],LISTHEAD,0); 770 do { 771 index = 0; 772 for (vertices = 0; vertices < verts->face->nOrgSize;vertices++) { 773 if (vertex1 == verts->face->pPolygon[vertices]+1 || 774 vertex2 == verts->face->pPolygon[vertices]+1 || 775 vertex3 == verts->face->pPolygon[vertices]+1 ) 776 original_vertex[index++] = verts->face->pPolygon[vertices]+1; 777 if (index == 3) 778 break; 779 } 780 if (index == 3) 781 break; 782 } while ((verts = (PF_VERTICES) GetNextNode(verts)) != NULL); 783 } 784 785 /* if (index !=3 ) 786 printf("Warning: Didn't find a triangle for %d %d %d\n", 787 vertex1,vertex2,vertex3); 788 */ 789 } 790 791 /// preserve_strip_orientation_with_normal: 792 void CustomStripifier::preserve_strip_orientation_with_normal(int vertex1, int normal1, int vertex2, int normal2, int vertex3, int normal3) 793 { 794 int original_vertex[3]; 795 796 find_triangle_orientation(vertex1,vertex2,vertex3, original_vertex); 797 798 /* if ( ( original_vertex[0] == vertex3 && original_vertex[1] == vertex2 && original_vertex[2] == vertex1) || 376 } 377 while (i< (int) StripVertices[vertex3-1].size()); 378 379 if ( ( original_vertex[0] == vertex3 && original_vertex[1] == vertex2 && original_vertex[2] == vertex1 ) || 799 380 ( original_vertex[0] == vertex2 && original_vertex[1] == vertex1 && original_vertex[2] == vertex3 ) || 800 ( original_vertex[0] == vertex1 && original_vertex[1] == vertex3 && original_vertex[2] == vertex2 )) { 801 // New Triangle is in an opposite orientation. Add vertex2 to correct it 802 fprintf(output," %d//%d",vertex2,normal2); 803 }*/ 804 805 } 806 807 /// preserve_strip_orientation_with_texture: 808 void CustomStripifier::preserve_strip_orientation_with_texture( 809 int vertex1, int texture1, 810 int vertex2, int texture2, 811 int vertex3, int texture3) 812 { 813 int original_vertex[3]; 814 815 find_triangle_orientation(vertex1,vertex2,vertex3, 816 original_vertex); 817 818 /* if ( ( original_vertex[0] == vertex3 && 819 original_vertex[1] == vertex2 && 820 original_vertex[2] == vertex1 ) || 821 ( original_vertex[0] == vertex2 && 822 original_vertex[1] == vertex1 && 823 original_vertex[2] == vertex3 ) || 824 ( original_vertex[0] == vertex1 && 825 original_vertex[1] == vertex3 && 826 original_vertex[2] == vertex2 ) ) { 827 // New Triangle is in an opposite orientation 828 // Add vertex2 to correct it 829 fprintf(output," %d/%d",vertex2,texture2); 830 }*/ 831 } 832 833 /// preserve_strip_orientation_with_texture_and_normal: 834 void CustomStripifier::preserve_strip_orientation_with_texture_and_normal( 835 int vertex1, int texture1, int normal1, 836 int vertex2, int texture2, int normal2, 837 int vertex3, int texture3, int normal3) 838 { 839 int original_vertex[3]; 840 841 find_triangle_orientation(vertex1,vertex2,vertex3, 842 original_vertex); 843 844 /* if ( ( original_vertex[0] == vertex3 && 845 original_vertex[1] == vertex2 && 846 original_vertex[2] == vertex1 ) || 847 ( original_vertex[0] == vertex2 && 848 original_vertex[1] == vertex1 && 849 original_vertex[2] == vertex3 ) || 850 ( original_vertex[0] == vertex1 && 851 original_vertex[1] == vertex3 && 852 original_vertex[2] == vertex2 ) ) { 853 // New Triangle is in an opposite orientation 854 // Add vertex2 to correct it 855 fprintf(output," %d/%d/%d",vertex2,texture2,normal2); 856 }*/ 857 } 858 859 /// preserve_strip_orientation: 860 void CustomStripifier::preserve_strip_orientation(int vertex1, int vertex2,int vertex3) 861 { 862 int original_vertex[3]; 863 864 find_triangle_orientation(vertex1,vertex2,vertex3, 865 original_vertex); 866 867 if ( ( original_vertex[0] == vertex3 && 868 original_vertex[1] == vertex2 && 869 original_vertex[2] == vertex1 ) || 870 ( original_vertex[0] == vertex2 && 871 original_vertex[1] == vertex1 && 872 original_vertex[2] == vertex3 ) || 873 ( original_vertex[0] == vertex1 && 874 original_vertex[1] == vertex3 && 875 original_vertex[2] == vertex2 )) { 876 // New Triangle is in an opposite orientation 877 // Add vertex2 to correct it 878 // fprintf(output," %d",vertex2); 879 mi_vector[num_tiras].push_back(vertex2-1); 880 } 881 } 882 883 /// Output_TriEx: 884 void CustomStripifier::Output_TriEx(int id1, int id2, int id3, int flag, int where) 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: 387 void CustomStripifier::AddTri(int id1, int id2, int id3, int flag, int where) 885 388 { 886 389 /* We will save everything into a list, rather than output at once, 887 390 as was done in the old routine. This way for future modifications 888 we can change the strips later on if we want to. 889 */ 890 891 int swap,temp1,temp2,temp3; 892 static int total=0; 893 static int tri=0; 894 static int strips = 0; 895 static int cost = 0; 896 897 if (flag == -20) 898 { 899 cost = cost + where+total+tri+strips+strips; 900 printf("We will need to send %d vertices to the renderer\n",cost); 901 total = 0; 902 tri = 0; 903 strips = 0; 904 return ; 905 } 906 391 we can change the strips later on if we want to */ 907 392 908 393 if (flag == -10) 909 /* We are finished, now is time to output the triangle list 910 */ 911 { 912 // fprintf(output,"\nt"); 913 mi_vector_tipo nada; 914 mi_vector.push_back(nada); 394 { 395 vector_int nada; 396 my_vector.push_back(nada); 397 915 398 num_tiras++; 916 tri = tri + Finished(&swap,1); 917 total = total + swap; 918 strips++; 919 /*printf("There are %d swaps %d tri %d strips\n",total,tri,strips);*/ 399 Finished(); 920 400 } 921 401 else 922 402 { 923 Last_Edge(&temp1,&temp2,&temp3,0); 924 Add_Id_Strips(id1,where); 925 Add_Id_Strips(id2,where); 926 Add_Id_Strips(id3,where); 927 Last_Edge(&id1,&id2,&id3,1); 928 } 929 } 930 931 /// Extend_BackwardsEx: 932 void CustomStripifier::Extend_BackwardsEx(int face_id, int *ties, 933 int tie, int triangulate, 934 int swaps,int *next_id) 935 { 936 /* We just made a strip, now we are going to see if we can extend 937 backwards from the starting face, which had 2 or more adjacencies 938 to start with. 939 */ 940 941 int bucket,next_face,num,x,y,z,c,max,f; 942 ListHead *pListFace; 943 PF_FACES face; 944 P_ADJACENCIES temp; 945 946 /* Get the first triangle that we have saved the the strip data 947 structure, so we can see if there are any polygons adjacent 948 to this edge or a neighboring one 949 */ 950 First_Edge(&x,&y,&z); 951 952 pListFace = PolFaces[face_id]; 953 face = (PF_FACES) PeekList(pListFace,LISTHEAD,0); 954 955 num = face->nPolSize; 956 957 /* Go through the edges to see if there is an adjacency 958 with a vertex in common to the first triangle that was 959 outputted in the strip. (maybe edge was deleted....) 960 */ 961 for (c=0; c<num ; c++) 962 { 403 StoreStrip(id1, where); 404 StoreStrip(id2, where); 405 StoreStrip(id3, where); 963 406 964 if ( (c != (num-1)) && 965 (( (*(face->pPolygon+c) == x) && (*(face->pPolygon+c+1) == y)) || 966 (*(face->pPolygon+c) == y) && (*(face->pPolygon+c+1) == x))) 967 { 968 /* Input edge is still there see if there is an adjacency */ 969 next_face = Find_Face(face_id, x, y, &bucket); 970 if (next_face == -1) 971 /* Could not find a face adjacent to the edge */ 972 break; 973 pListFace = array[bucket]; 974 max = NumOnList(pListFace); 975 for (f=0;;f++) 976 { 977 temp = (P_ADJACENCIES) PeekList(pListFace,LISTHEAD,f); 978 if (temp->face_id == next_face) 407 lastTri[0]=id1; 408 lastTri[1]=id2; 409 lastTri[2]=id3; 410 } 411 } 412 413 /// GoBack: 414 void 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) 979 440 { 980 Last_Edge(&z,&y,&x,1); 981 Polygon_OutputEx(temp,temp->face_id,bucket,pListFace, 982 ties,tie,triangulate, 983 swaps,next_id,0); 984 return; 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: 462 void 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 } 985 547 } 986 548 987 if (temp == NULL) 988 { 989 printf("Error in the new buckets%d %d %d\n",bucket,max,0); 990 exit(0); 991 } 992 } 993 994 } 995 else if ( (c == (num -1)) && 996 ( ((*(face->pPolygon) == x) && (*(face->pPolygon+num-1) == y)) || 997 (*(face->pPolygon) == y) && (*(face->pPolygon+num-1) == x))) 998 { 999 next_face = Find_Face(face_id,x,y,&bucket); 1000 if (next_face == -1) 1001 /* Could not find a face adjacent to the edge */ 1002 break; 1003 pListFace = array[bucket]; 1004 max = NumOnList(pListFace); 1005 for (f=0;;f++) 1006 { 1007 temp = (P_ADJACENCIES) PeekList(pListFace,LISTHEAD,f); 1008 if (temp->face_id == next_face) 1009 { 1010 Last_Edge(&z,&y,&x,1); 1011 Polygon_OutputEx(temp,temp->face_id,bucket,pListFace, 1012 ties,tie,triangulate, 1013 swaps,next_id,0); 1014 return; 1015 } 1016 1017 if (temp == NULL) 1018 { 1019 printf("Error in the new buckets%d %d %d\n",bucket,max,0); 1020 exit(0); 1021 } 1022 } 1023 } 1024 } 1025 } 1026 1027 /// Polygon_OutputEx: 1028 void CustomStripifier::Polygon_OutputEx(P_ADJACENCIES temp,int face_id,int bucket, 1029 ListHead *pListHead, 1030 int *ties, int tie, 1031 int triangulate, int swaps, 1032 int *next_id, int where) 1033 { 1034 ListHead *pListFace; 1035 PF_FACES face; 1036 static BOOL begin = TRUE; 1037 int old_face,next_face_id,next_bucket,e1,e2,e3,other1,other2,other3; 1038 P_ADJACENCIES lpListInfo; 1039 1040 /* We have a polygon to output, the id is face id, and the number 1041 of adjacent polygons to it is bucket. 1042 */ 1043 1044 Last_Edge(&e1,&e2,&e3,0); 1045 1046 /* Get the polygon with id face_id */ 1047 pListFace = PolFaces[face_id]; 1048 face = (PF_FACES) PeekList(pListFace,LISTHEAD,0); 1049 1050 if (face->nPolSize == 3) 1051 { 1052 /* It is already a triangle */ 1053 if (bucket == 0) 1054 { 1055 /* It is not adjacent to anything so we do not have to 1056 worry about the order of the sides or updating adjacencies 1057 */ 1058 1059 Last_Edge(&e1,&e2,&e3,0); 1060 next_face_id = Different(*(face->pPolygon),*(face->pPolygon+1), 1061 *(face->pPolygon+2), 1062 e1,e2,e3,&other1,&other2); 1063 /* No input edge, at the start */ 1064 if ((e2 ==0) && (e3 == 0)) 1065 { 1066 e2 = other1; 1067 e3 = other2; 1068 } 1069 1070 Output_TriEx(e2,e3,next_face_id,begin,where); 1071 if (face_array[temp->face_id].head == pListHead) 1072 face_array[temp->face_id].pfNode = NULL; 1073 RemoveList(pListHead,(PLISTINFO) temp); 1074 /* We will be at the beginning of the next strip. */ 1075 begin = TRUE; 1076 } 1077 /* It is a triangle with adjacencies. This means that we 1078 have to: 1079 1. Update the adjacencies in the list, because we are 1080 using this polygon and it will be deleted. 1081 2. Get the next polygon. 1082 */ 1083 else 1084 { 1085 /* Return the face_id of the next polygon we will be using, 1086 while updating the adjacency list by decrementing the 1087 adjacencies of everything adjacent to the current triangle. 1088 */ 1089 1090 next_face_id = Update_AdjacenciesEx(face_id,&next_bucket, &e1,&e2,ties); 1091 old_face = next_face_id; 1092 1093 /* Break the tie, if there was one */ 1094 if (tie != FIRST) 1095 old_face = Get_Next_Face(tie,face_id,triangulate); 1096 1097 if (next_face_id == -1) 1098 { 1099 Polygon_OutputEx(temp,face_id,0,pListHead,ties,tie, 1100 triangulate,swaps,next_id,where); 1101 return; 1102 } 1103 1104 1105 /* We are using a different face */ 1106 if ((tie != FIRST) && (old_face != next_face_id) && (swaps == ON)) 1107 { 1108 next_face_id = old_face; 1109 /* Get the new output edge, since e1 and e2 are for the 1110 original next face that we got. 1111 */ 1112 e3 = Get_EdgeEx(&e1,&e2,face->pPolygon,next_face_id, 1113 face->nPolSize,0,0); 1114 } 1115 1116 /* Find the other vertex to transmit in the triangle */ 1117 e3 = Return_Other(face->pPolygon,e1,e2); 1118 Last_Edge(&other1,&other2,&other3,0); 1119 1120 if ((other1 != 0) && (other2 != 0)) 1121 { 1122 /* See which vertex in the output edge is not in the input edge */ 1123 if ((e1 != other2) && (e1 != other3)) 1124 e3 = e1; 1125 else if ((e2 != other2) && (e2 != other3)) 1126 e3 = e2; 1127 /* can happen with > 2 polys on an edge but won't 1128 form a good strip so stop the strip here 1129 */ 1130 else 1131 { 1132 Polygon_OutputEx(temp,face_id,0,pListHead, 1133 ties,tie,triangulate,swaps,next_id,where); 1134 return; 1135 } 1136 1137 /* See which vertex of the input edge is not in the output edge */ 1138 if ((other2 != e1) && (other2 != e2)) 549 if ((other2 != e1) && (other2 != e2)) 1139 550 { 1140 551 other1 = other2; 1141 552 other2 = other3; 1142 553 } 1143 else if ((other3 != e1) && (other3 != e2)) 1144 other1 = other3; 1145 else 554 else 1146 555 { 1147 /* Degenerate triangle just return*/ 1148 Output_TriEx(other1,other2,e3,begin,where); 1149 if (face_array[temp->face_id].head == pListHead) 1150 face_array[temp->face_id].pfNode = NULL; 1151 RemoveList(pListHead,(PLISTINFO) temp); 1152 begin = FALSE; 1153 return; 1154 } 1155 1156 } 1157 1158 /* There was not an input edge, we are the first triangle in a strip */ 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 } 1159 571 else 1160 { 1161 /* Find the correct order to transmit the triangle, what is 1162 the output edge that we want ? 1163 */ 572 { 1164 573 other1 = e3; 1165 574 e3 = e2; 1166 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: 595 void 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: 612 int 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: 676 int 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: 702 int 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: 755 int 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: 784 void 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: 802 int 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: 818 void 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: 831 void 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: 853 int 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: 888 void 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: 903 void 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: 956 int 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; 1167 972 } 1168 1169 /* At this point the adjacencies have been updated and we 1170 have the next polygon id 1171 */ 1172 Output_TriEx(other1,other2,e3,begin,where); 1173 if (face_array[temp->face_id].head == pListHead) 1174 face_array[temp->face_id].pfNode = NULL; 1175 RemoveList(pListHead,(PLISTINFO) temp); 1176 begin = FALSE; 1177 1178 if (Done(next_face_id,&next_bucket) == NULL) 1179 return; 1180 1181 pListHead = array[next_bucket]; 1182 lpListInfo = face_array[next_face_id].pfNode; 1183 if (lpListInfo == NULL) 1184 { 1185 printf("There is an error finding the next polygon3 %d\n", 1186 next_face_id); 1187 exit(0); 1188 } 1189 Polygon_OutputEx(lpListInfo,next_face_id,next_bucket, 1190 pListHead, ties,tie, 1191 triangulate,swaps,next_id,where); 1192 1193 } 1194 } 1195 1196 else 1197 { 1198 /* It is not a triangle, we have to triangulate it . 1199 Since it is not adjacent to anything we can triangulate it 1200 blindly 1201 */ 1202 if (bucket == 0) 1203 { 1204 /* Check to see if there is not an input edge */ 1205 Last_Edge(&other1,&other2,&other3,0); 1206 if ((other1 == 0) && (other2 ==0)) 1207 Blind_TriangulateEx(face->nPolSize,face->pPolygon, 1208 TRUE,where); 1209 else 1210 Blind_TriangulateEx(face->nPolSize,face->pPolygon, 1211 FALSE,where); 1212 1213 if (face_array[temp->face_id].head == pListHead) 1214 face_array[temp->face_id].pfNode = NULL; 1215 RemoveList(pListHead,(PLISTINFO) temp); 1216 /* We will be at the beginning of the next strip. */ 1217 begin = TRUE; 1218 } 1219 1220 /* If we have specified PARTIAL triangulation then 1221 we will go to special routines that will break the 1222 polygon and update the data structure. Else everything 1223 below will simply triangulate the whole polygon 1224 */ 1225 else if (triangulate == PARTIAL) 1226 { 1227 1228 /* Return the face_id of the next polygon we will be using, 1229 */ 1230 next_face_id = Min_Face_AdjEx(face_id,&next_bucket,ties); 1231 1232 1233 /* Don't do it partially, because we can go inside and get 1234 less adjacencies, for a quad we can do the whole thing. 1235 */ 1236 if ((face_id == next_face_id) && (face->nPolSize == 4) && (swaps == ON)) 1237 { 1238 next_face_id = Update_AdjacenciesEx(face_id, &next_bucket, 1239 &e1,&e2,ties); 1240 if (next_face_id == -1) 1241 { 1242 /* There is no sequential face to go to, end the strip */ 1243 Polygon_OutputEx(temp,face_id,0,pListHead, 1244 ties,tie,triangulate,swaps,next_id,where); 1245 return; 1246 } 1247 1248 /* Break the tie, if there was one */ 1249 if (tie != FIRST) 1250 next_face_id = Get_Next_Face(tie,face_id,triangulate); 1251 Non_Blind_TriangulateEx(face->nPolSize,face->pPolygon, 1252 next_face_id,face_id,where); 1253 1254 if (face_array[temp->face_id].head == pListHead) 1255 face_array[temp->face_id].pfNode = NULL; 1256 RemoveList(pListHead,(PLISTINFO) temp); 1257 } 1258 1259 /* Was not a quad but we still do not want to do it partially for 1260 now, since we want to only do one triangle at a time 1261 */ 1262 else if ((face_id == next_face_id) && (swaps == ON)) 1263 Inside_Polygon(face->nPolSize,face->pPolygon, 1264 face_id,pListHead,where); 1265 1266 else 1267 { 1268 if ((tie != FIRST) && (swaps == ON)) 1269 next_face_id = Get_Next_Face(tie,face_id,triangulate); 1270 Partial_Triangulate(face->nPolSize,face->pPolygon, 1271 next_face_id,face_id,next_id, 1272 pListHead,temp,where); 1273 /* Check the next bucket again ,maybe it changed 1274 We calculated one less, but that might not be the case 1275 */ 1276 } 1277 1278 if (Done(next_face_id,&next_bucket) == NULL) 1279 { 1280 /* Check to see if there is not an input edge */ 1281 Last_Edge(&other1,&other2,&other3,0); 1282 if ((other1 == 0) && (other2 ==0)) 1283 Blind_TriangulateEx(face->nPolSize,face->pPolygon, 1284 TRUE,where); 1285 else 1286 Blind_TriangulateEx(face->nPolSize,face->pPolygon, 1287 FALSE,where); 1288 1289 if (Done(face_id,&bucket) != NULL) 1290 { 1291 pListHead = array[bucket]; 1292 lpListInfo = face_array[face_id].pfNode; 1293 if (face_array[temp->face_id].head == pListHead) 1294 face_array[lpListInfo->face_id].pfNode = NULL; 1295 RemoveList(pListHead,(PLISTINFO)lpListInfo); 1296 } 1297 begin = TRUE; 1298 return; 1299 } 1300 1301 begin = FALSE; 1302 pListHead = array[next_bucket]; 1303 lpListInfo = face_array[next_face_id].pfNode; 1304 if (lpListInfo == NULL) 1305 { 1306 printf("There is an error finding the next polygon1 %d %d\n", 1307 next_face_id,next_bucket); 1308 exit(0); 1309 } 1310 Polygon_OutputEx(lpListInfo,next_face_id,next_bucket, 1311 pListHead, ties,tie, 1312 triangulate,swaps,next_id,where); 1313 } 1314 1315 1316 else 1317 { 1318 /* WHOLE triangulation */ 1319 /* It is not a triangle and has adjacencies. 1320 This means that we have to: 1321 1. TriangulateEx this polygon, not blindly because 1322 we have an edge that we want to come out on, that 1323 is the edge that is adjacent to a polygon with the 1324 least number of adjacencies. Also we must come in 1325 on the last seen edge. 1326 2. Update the adjacencies in the list, because we are 1327 using this polygon . 1328 3. Get the next polygon. 1329 */ 1330 /* Return the face_id of the next polygon we will be using, 1331 while updating the adjacency list by decrementing the 1332 adjacencies of everything adjacent to the current polygon. 1333 */ 1334 1335 next_face_id = Update_AdjacenciesEx(face_id,&next_bucket, &e1,&e2,ties); 1336 1337 if (Done(next_face_id,&next_bucket) == NULL) 1338 { 1339 Polygon_OutputEx(temp,face_id,0,pListHead,ties,tie, 1340 triangulate,swaps,next_id,where); 1341 /* Because maybe there was more than 2 polygons on the edge */ 1342 return; 1343 } 1344 1345 /* Break the tie, if there was one */ 1346 else if (tie != FIRST) 1347 next_face_id = Get_Next_Face(tie,face_id,triangulate); 1348 1349 Non_Blind_TriangulateEx(face->nPolSize,face->pPolygon, 1350 next_face_id,face_id,where); 1351 1352 if (face_array[temp->face_id].head == pListHead) 1353 face_array[temp->face_id].pfNode = NULL; 1354 RemoveList(pListHead,(PLISTINFO) temp); 1355 begin = FALSE; 1356 pListHead = array[next_bucket]; 1357 lpListInfo = face_array[next_face_id].pfNode; 1358 1359 if (lpListInfo == NULL) 1360 { 1361 printf("There is an error finding the next polygon2 %d %d\n", 1362 next_face_id,next_bucket); 1363 exit(0); 1364 } 1365 Polygon_OutputEx(lpListInfo,next_face_id,next_bucket, 1366 pListHead, ties,tie, 1367 triangulate,swaps,next_id,where); 1368 } 1369 1370 } 1371 Last_Edge(&e1,&e2,&e3,0); 1372 } 1373 1374 /// Adjacent: 1375 int CustomStripifier::Adjacent(int id2,int id1, int *list, int size) 1376 { 1377 /* Return the vertex that is adjacent to id1, 1378 but is not id2, in the list of integers. 1379 */ 1380 1381 register int x=0; 1382 1383 while (x < size) 1384 { 1385 if (*(list+x) == id1) 1386 { 1387 if ((x != (size -1)) && (x != 0)) 1388 { 1389 if ( *(list+x+1) != id2) 1390 return *(list+x+1); 1391 else 1392 return *(list+x-1); 1393 } 1394 else if (x == (size -1)) 1395 { 1396 if (*(list) != id2) 1397 return *(list); 1398 else 1399 return *(list+x-1); 1400 } 1401 else 1402 { 1403 if (*(list+size-1) != id2) 1404 return *(list+size-1); 1405 else 1406 return *(list+x+1); 1407 } 1408 } 1409 x++; 1410 } 1411 /* if there are degeneracies */ 1412 return id1; 1413 } 1414 1415 /// Rearrange_Index: 1416 void CustomStripifier::Rearrange_Index(int *index, int size) 1417 { 1418 /* If we are in the middle of a strip we must find the 1419 edge to start on, which is the last edge that we had 1420 transmitted. 1421 */ 1422 int x,f,y,e1,e2,e3; 1423 register int increment = 1; 1424 int *temp; 1425 1426 /* Find where the input edge is in the input list */ 1427 Last_Edge(&e1,&e2,&e3,0); 1428 for (y = 0; y < size; y++) 1429 { 1430 if (*(index+y) == e2) 1431 { 1432 if ((y != (size - 1)) && (*(index+y+1) == e3)) 1433 break; 1434 else if ((y == (size - 1)) && (*(index) == e3)) 1435 break; 1436 else if ((y != 0) && (*(index+y-1) == e3)) 1437 { 1438 increment = -1; 1439 break; 1440 } 1441 else if ((y==0) && (*(index+size-1) == e3)) 1442 { 1443 increment = -1; 1444 break; 1445 } 1446 } 1447 if (*(index+y) == e3) 1448 { 1449 if ((y != (size - 1)) && (*(index+y+1) == e2)) 1450 break; 1451 else if ((y == (size - 1)) && (*(index) == e2)) 1452 break; 1453 else if ((y != 0) && (*(index+y-1) == e2)) 1454 { 1455 increment = -1; 1456 break; 1457 } 1458 else if ((y==0) && (*(index+size-1) == e2)) 1459 { 1460 increment = -1; 1461 break; 1462 } 1463 } 1464 /* Edge is not here, we are at the beginning */ 1465 if ((y == (size-1)) && (increment != -1)) 1466 return; 1467 } 1468 1469 /* Now put the list into a new list, starting with the 1470 input edge. Increment tells us whether we have to go 1471 forward or backward. 1472 */ 1473 /* Was in good position already */ 1474 if ((y == 0) && (increment == 1)) 1475 return; 1476 1477 temp = (int *) malloc(sizeof(int) * size); 1478 memcpy(temp,index,sizeof(int)*size); 1479 1480 if (increment == 1) 1481 { 1482 x=0; 1483 for (f = y ; f< size; f++) 1484 { 1485 *(index+x) = *(temp+f); 1486 x++; 1487 } 1488 /* Finish the rest of the list */ 1489 for(f = 0; f < y ; f++) 1490 { 1491 *(index+x) = *(temp+f); 1492 x++; 1493 } 1494 } 1495 else 1496 { 1497 x=0; 1498 for (f = y ; f >= 0; f--) 1499 { 1500 *(index+x) = *(temp+f); 1501 x++; 1502 } 1503 /* Finish the rest of the list */ 1504 for(f = (size - 1); f > y ; f--) 1505 { 1506 *(index+x) = *(temp+f); 1507 x++; 1508 } 1509 } 1510 } 1511 1512 /// Delete_From_List: 1513 void CustomStripifier::Delete_From_List(int id,int *list, int *size) 1514 { 1515 /* Delete the occurence of id in the list. 1516 (list has size size) 1517 */ 1518 1519 int *temp; 1520 register int x,y=0; 1521 1522 temp = (int *) malloc(sizeof(int) * (*size)); 1523 for (x=0; x<(*size); x++) 1524 { 1525 if (*(list+x) != id) 1526 { 1527 *(temp+y) = *(list+x); 1528 y++; 1529 } 1530 } 1531 *(temp+y) = -1; 1532 *size = *size - (*size - y - 1); 1533 memcpy(list,temp,sizeof(int)*(*size)); 1534 } 1535 1536 /// Build_SGI_Table: 1537 void CustomStripifier::Build_SGI_Table(int num_faces) 1538 { 1539 /* Build a table that has the polygons sorted by the 1540 number of adjacent polygons. 1541 */ 1542 int x,y,size,tally=0; 1543 ListHead *pListHead; 1544 PF_FACES temp = NULL; 1545 1546 /* For each face....*/ 1547 for (x=0;x < num_faces;x++) 1548 { 1549 pListHead = PolFaces[x]; 1550 temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 ); 1551 /* Check each edge of the face and tally the number of adjacent 1552 polygons to this face. 1553 */ 1554 if ( temp != NULL ) 1555 { 1556 /* Size of the polygon */ 1557 size = temp->nPolSize; 1558 if (size != 1) 1559 { 1560 for (y = 0; y< size; y++) 1561 { 1562 if (y != (size-1)) 1563 tally += Num_Adj(*(temp->pPolygon+y),*(temp->pPolygon+y+1)); 1564 else 1565 tally+= Num_Adj(*(temp->pPolygon),*(temp->pPolygon+(size-1))); 1566 } 1567 1568 /* Tally is the number of polygons that is adjacent to 1569 the current polygon. 1570 */ 1571 /* Now put the face in the proper bucket depending on tally. */ 1572 Add_Sgi_Adj(tally,x); 1573 temp = NULL; 1574 tally=0; 1575 } 1576 } 1577 } 1578 } 1579 1580 /// Triangulate_Quad: 1581 void CustomStripifier::Triangulate_Quad(int out_edge1,int out_edge2,int in_edge1, 1582 int in_edge2,int size,int *index, 1583 int reversed,int where) 1584 { 1585 int vertex4,vertex5; 1586 1587 /* This routine will nonblindly triangulate a quad, meaning 1588 that there is a definite input and a definite output 1589 edge that we must adhere to. Reversed will tell the orientation 1590 of the input edge. (Reversed is -1 is we do not have an input 1591 edge, in other words we are at the beginning of a strip.) 1592 Out_edge* is the output edge, and in_edge* is the input edge. 1593 Index are the edges of the polygon 1594 and size is the size of the polygon. Begin is whether we are 1595 at the start of a new strip. 1596 */ 1597 1598 /* If we do not have an input edge, then we can make our input 1599 edge whatever we like, therefore it will be easier to come 1600 out on the output edge. 1601 */ 1602 if (reversed == -1) 1603 { 1604 vertex4 = Adjacent(out_edge1,out_edge2,index,size); 1605 vertex5 = Get_Other_Vertex(vertex4,out_edge1,out_edge2,index); 1606 Output_Tri(vertex5,vertex4,out_edge1,where); 1607 Output_Tri(vertex4,out_edge1,out_edge2,where); 1608 return; 1609 } 1610 1611 /* These are the 5 cases that we can have for the output edge */ 1612 1613 /* Are they consecutive so that we form a triangle to 1614 peel off, but cannot use the whole quad? 1615 */ 1616 1617 if (in_edge2 == out_edge1) 1618 { 1619 /* Output the triangle that comes out the correct 1620 edge last. First output the triangle that comes out 1621 the wrong edge. 1622 */ 1623 vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge2,index); 1624 Output_Tri(in_edge1,in_edge2,vertex4,where); 1625 Output_Tri(vertex4,in_edge2,out_edge2,where); 1626 return; 1627 } 1628 /* The next case is where it is impossible to come out the 1629 edge that we want. So we will have to start a new strip to 1630 come out on that edge. We will output the one triangle 1631 that we can, and then start the new strip with the triangle 1632 that comes out on the edge that we want to come out on. 1633 */ 1634 else if (in_edge1 == out_edge1) 1635 { 1636 /* We want to output the first triangle (whose output 1637 edge is not the one that we want. 1638 We have to find the vertex that we need, which is 1639 the other vertex which we do not have. 1640 */ 1641 vertex4 = Get_Other_Vertex(in_edge2,in_edge1,out_edge2,index); 1642 Output_Tri(in_edge2,in_edge1,vertex4,where); 1643 Output_Tri(vertex4,in_edge1,out_edge2,where); 1644 return; 1645 } 1646 1647 /* Consecutive cases again, but with the output edge reversed */ 1648 else if (in_edge1 == out_edge2) 1649 { 1650 vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge1,index); 1651 Output_Tri(in_edge2,in_edge1,vertex4,where); 1652 Output_Tri(vertex4,in_edge1,out_edge1,where); 1653 return; 1654 } 1655 else if (in_edge2 == out_edge2) 1656 { 1657 vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge1,index); 1658 Output_Tri(in_edge1,in_edge2,vertex4,where); 1659 Output_Tri(vertex4,in_edge2,out_edge1,where); 1660 return; 1661 } 1662 1663 /* The final case is where we want to come out the opposite 1664 edge. 1665 */ 1666 else 1667 { 1668 if( ((!reversed) && 1669 (out_edge1 == (Adjacent(in_edge1,in_edge2,index,size)))) || 1670 ((reversed) && 1671 (out_edge2 == (Adjacent(in_edge2,in_edge1,index,size))))) 1672 { 1673 /* We need to know the orientation of the input 1674 edge, so we know which way to put the diagonal. 1675 And also the output edge, so that we triangulate 1676 correctly. 1677 */ 1678 Output_Tri(in_edge1,in_edge2,out_edge2,where); 1679 Output_Tri(in_edge2,out_edge2,out_edge1,where); 1680 } 1681 else 1682 { 1683 /* Input and output orientation was reversed, so diagonal will 1684 be reversed from above. 1685 */ 1686 Output_Tri(in_edge1,in_edge2,out_edge1,where); 1687 Output_Tri(in_edge2,out_edge1,out_edge2,where); 1688 } 1689 return; 1690 } 1691 } 1692 1693 /// Triangulate_Polygon: 1694 void CustomStripifier::Triangulate_Polygon( int out_edge1,int out_edge2, 1695 int in_edge1, int in_edge2, 1696 int size, int *index, 1697 int reversed, 1698 int face_id, int where, 1699 int color1, int color2, 1700 int color3) 1701 { 1702 /* We have a polygon that we need to nonblindly triangulate. 1703 We will recursively try to triangulate it, until we are left 1704 with a polygon of size 4, which can use the quad routine 1705 from above. We will be taking off a triangle at a time 1706 and outputting it. We will have 3 cases similar to the 1707 cases for the quad above. The inputs to this routine 1708 are the same as for the quad routine. 1709 */ 1710 1711 int vertex4; 1712 int *temp; 1713 1714 1715 /* Since we are calling this recursively, we have to check whether 1716 we are down to the case of the quad. 1717 */ 1718 1719 if (size == 4) 1720 { 1721 Triangulate_Quad(out_edge1,out_edge2,in_edge1,in_edge2,size, 1722 index,reversed,where); 1723 return; 1724 } 1725 1726 1727 1728 /* We do not have a specified input edge, and therefore we 1729 can make it anything we like, as long as we still come out 1730 the output edge that we want. 1731 */ 1732 if (reversed == -1) 1733 { 1734 /* Get the vertex for the last triangle, which is 1735 the one coming out the output edge, before we do 1736 any deletions to the list. We will be doing this 1737 bottom up. 1738 */ 1739 vertex4 = Adjacent(out_edge1,out_edge2,index,size); 1740 temp = (int *) malloc(sizeof(int) * size); 1741 memcpy(temp,index,sizeof(int)*size); 1742 Delete_From_List(out_edge2,index,&size); 1743 Triangulate_Polygon(out_edge1,vertex4,in_edge2, 1744 vertex4,size-1,index,reversed,face_id, 1745 where,color1,color2,color3); 1746 memcpy(index,temp,sizeof(int)*size); 1747 /* Lastly do the triangle that comes out the output 1748 edge. 1749 */ 1750 Output_Tri(vertex4,out_edge1,out_edge2,where); 1751 return; 1752 } 1753 1754 /* These are the 5 cases that we can have for the output edge */ 1755 1756 /* Are they consecutive so that we form a triangle to 1757 peel off that comes out the correct output edge, 1758 but we cannot use the whole polygon? 1759 */ 1760 if (in_edge2 == out_edge1) 1761 { 1762 /* Output the triangle that comes out the correct 1763 edge last. First recursively do the rest of the 1764 polygon. 1765 */ 1766 /* Do the rest of the polygon without the triangle. 1767 We will be doing a fan triangulation. 1768 */ 1769 /* Get the vertex adjacent to in_edge1, but is not 1770 in_edge2. 1771 */ 1772 vertex4 = Adjacent(in_edge2,in_edge1,index,size); 1773 Output_Tri(in_edge1,in_edge2,vertex4,where); 1774 /* Create a new edgelist without the triangle that 1775 was just outputted. 1776 */ 1777 temp = (int *) malloc(sizeof(int) * size); 1778 memcpy(temp,index,sizeof(int)*size); 1779 Delete_From_List(in_edge1,index,&size); 1780 Triangulate_Polygon(out_edge1,out_edge2,in_edge2, 1781 vertex4,size-1,index,!reversed,face_id, 1782 where,color1,color2,color3); 1783 memcpy(index,temp,sizeof(int)*size); 1784 return; 1785 } 1786 1787 /* Next case is where it is again consecutive, but the triangle 1788 formed by the consecutive edges do not come out of the 1789 correct output edge. For this case, we can not do much to 1790 keep it sequential. Try and do the fan. 1791 */ 1792 else if (in_edge1 == out_edge1) 1793 { 1794 /* Get vertex adjacent to in_edge2, but is not in_edge1 */ 1795 vertex4 = Adjacent(in_edge1,in_edge2,index,size); 1796 Output_Tri(in_edge1,in_edge2,vertex4,where); 1797 /* Since that triangle goes out of the polygon (the 1798 output edge of it), we can make our new input edge 1799 anything we like, so we will try to make it good for 1800 the strip. (This will be like starting a new strip, 1801 all so that we can go out the correct output edge.) 1802 */ 1803 temp = (int *) malloc(sizeof(int) * size); 1804 memcpy(temp,index,sizeof(int)*size); 1805 Delete_From_List(in_edge2,index,&size); 1806 Triangulate_Polygon(out_edge1,out_edge2,in_edge1, 1807 vertex4,size-1,index,reversed,face_id, 1808 where,color1,color2,color3); 1809 memcpy(index,temp,sizeof(int)*size); 1810 return; 1811 } 1812 /* Consecutive cases again, but with the output edge reversed */ 1813 else if (in_edge1 == out_edge2) 1814 { 1815 /* Get vertex adjacent to in_edge2, but is not in_edge1 */ 1816 vertex4 = Adjacent(in_edge1,in_edge2,index,size); 1817 Output_Tri(in_edge2,in_edge1,vertex4,where); 1818 temp = (int *) malloc(sizeof(int) * size); 1819 memcpy(temp,index,sizeof(int)*size); 1820 Delete_From_List(in_edge2,index,&size); 1821 Triangulate_Polygon(out_edge1,out_edge2,in_edge1, 1822 vertex4,size-1,index,reversed,face_id, 1823 where,color1,color2,color3); 1824 memcpy(index,temp,sizeof(int)*size); 1825 return; 1826 } 1827 else if (in_edge2 == out_edge2) 1828 { 1829 /* Get vertex adjacent to in_edge2, but is not in_edge1 */ 1830 vertex4 = Adjacent(in_edge2,in_edge1,index,size); 1831 Output_Tri(in_edge1,in_edge2,vertex4,where); 1832 temp = (int *) malloc(sizeof(int) * size); 1833 memcpy(temp,index,sizeof(int)*size); 1834 Delete_From_List(in_edge1,index,&size); 1835 Triangulate_Polygon(out_edge1,out_edge2,vertex4, 1836 in_edge2,size-1,index,reversed,face_id, 1837 where,color1,color2,color3); 1838 memcpy(index,temp,sizeof(int)*size); 1839 return; 1840 } 1841 1842 /* Else the edge is not consecutive, and it is sufficiently 1843 far away, for us not to make a conclusion at this time. 1844 So we can take off a triangle and recursively call this 1845 function. 1846 */ 1847 else 1848 { 1849 vertex4 = Adjacent(in_edge2,in_edge1,index,size); 1850 Output_Tri(in_edge1,in_edge2,vertex4,where); 1851 temp = (int *) malloc(sizeof(int) * size); 1852 memcpy(temp,index,sizeof(int)*size); 1853 Delete_From_List(in_edge1,index,&size); 1854 Triangulate_Polygon(out_edge1,out_edge2,in_edge2, 1855 vertex4,size-1,index,!reversed,face_id, 1856 where,color1,color2,color3); 1857 memcpy(index,temp,sizeof(int)*size); 1858 return; 1859 } 1860 } 1861 1862 /// Triangulate: 1863 void CustomStripifier::Triangulate(int out_edge1,int out_edge2,int in_edge1, 1864 int in_edge2,int size,int *index, 1865 int reversed,int face_id, int where, 1866 int color1, int color2,int color3) 1867 { 1868 /* We have the info we need to triangulate a polygon */ 1869 1870 if (size == 4) 1871 Triangulate_Quad(out_edge1,out_edge2,in_edge1,in_edge2,size, 1872 index,reversed,where); 1873 else 1874 Triangulate_Polygon(out_edge1,out_edge2,in_edge1,in_edge2,size, 1875 index,reversed,face_id,where,color1,color2,color3); 1876 } 1877 1878 /// Non_Blind_Triangulate: 1879 void CustomStripifier::Non_Blind_Triangulate(int size,int *index, 1880 int next_face_id,int face_id,int where,int color1,int color2,int color3) 1881 { 1882 int id1,id2,id3; 1883 int nedge1,nedge2; 1884 int reversed; 1885 /* We have a polygon that has to be triangulated and we cannot 1886 do it blindly, ie we will try to come out on the edge that 1887 has the least number of adjacencies 1888 */ 1889 1890 Last_Edge(&id1,&id2,&id3,0); 1891 /* Find the edge that is adjacent to the new face , 1892 also return whether the orientation is reversed in the 1893 face of the input edge, which is id2 and id3. 1894 */ 1895 if (next_face_id == -1) 1896 { 1897 printf("The face is -1 and the size is %d\n",size); 1898 exit(0); 1899 } 1900 1901 reversed = Get_Edge(&nedge1,&nedge2,index,next_face_id,size,id2,id3); 1902 /* Do the triangulation */ 1903 1904 /* If reversed is -1, the input edge is not in the polygon, 1905 therefore we can have the input edge to be anything we like, 1906 since we are at the beginning of a strip 1907 */ 1908 Triangulate(nedge1,nedge2,id2,id3,size,index,reversed, 1909 face_id, where,color1,color2,color3); 1910 } 1911 1912 /// Blind_Triangulate: 1913 void CustomStripifier::Blind_Triangulate(int size, int *index, BOOL begin, int where) 1914 { 1915 /* save sides in temp array, we need it so we know 1916 about swaps. 1917 */ 1918 int mode, decreasing,increasing,e1,e2,e3; 1919 1920 /* Rearrange the index list so that the input edge is first 1921 */ 1922 if (!begin) 1923 Rearrange_Index(index,size); 1924 1925 /* We are given a polygon of more than 3 sides 1926 and want to triangulate it. We will output the 1927 triangles to the output file. 1928 */ 1929 1930 /* Find where the input edge is in the input list */ 1931 Last_Edge(&e1,&e2,&e3,0); 1932 if (( (!begin) && (*(index) == e2) ) || (begin)) 1933 { 1934 Output_Tri(*(index+0),*(index+1),*(index+size-1),where); 1935 /* If we have a quad, (chances are yes), then we know that 1936 we can just add one diagonal and be done. (divide the 1937 quad into 2 triangles. 1938 */ 1939 if (size == 4) 1940 { 1941 Output_Tri(*(index+1),*(index+size-1),*(index+2),where); 1942 return; 1943 } 1944 increasing = 1; 1945 mode = 1; 1946 1947 } 1948 else if (!begin) 1949 { 1950 Output_Tri(*(index+1),*(index+0),*(index+size-1),where); 1951 if (size == 4) 1952 { 1953 Output_Tri(*(index+0),*(index+size-1),*(index+2),where); 1954 return; 1955 } 1956 Output_Tri(*(index+0),*(index+size-1),*(index+2),where); 1957 increasing = 2; 1958 mode = 0; 1959 } 1960 if (size != 4) 1961 { 1962 /* We do not have a quad, we have something bigger. */ 1963 decreasing = size - 1; 1964 do 1965 { 1966 /* Will be alternating diagonals, so we will be increasing 1967 and decreasing around the polygon. 1968 */ 1969 if (mode) 1970 { 1971 Output_Tri(*(index+increasing),*(index+decreasing), 1972 *(index+increasing+1),where); 1973 increasing++; 1974 } 1975 else 1976 { 1977 Output_Tri(*(index+decreasing),*(index+increasing), 1978 *(index+decreasing-1),where); 1979 decreasing--; 1980 } 1981 mode = !mode; 1982 } while ((decreasing - increasing) >= 2); 1983 1984 } 1985 } 1986 1987 /// Get_Edge: 1988 int CustomStripifier::Get_Edge(int *edge1,int *edge2,int *index,int face_id, 1989 int size, int id1, int id2) 1990 { 1991 /* Put the edge that is adjacent to face_id into edge1 1992 and edge2. For each edge see if it is adjacent to 1993 face_id. Id1 and id2 is the input edge, so see if 1994 the orientation is reversed, and save it in reversed. 1995 */ 1996 register int x; 1997 int reversed = -1; 1998 BOOL set = FALSE; 1999 2000 for (x=0; x< size; x++) 2001 { 2002 if (x == (size-1)) 2003 { 2004 if ((*(index) == id1) && (*(index+size-1)==id2)) 973 else if ((*(index) == 0) && (*(index+2)==0)) 2005 974 { 2006 975 if (set) 2007 return 1; 2008 reversed = 1; 2009 } 2010 else if ((*(index) == id2) && (*(index+size-1)==id1)) 2011 { 2012 if (set) 2013 return 0; 976 return 0; 2014 977 reversed = 0; 2015 978 } 2016 979 2017 if (Look_Up(*(index),*(index+size-1),face_id))980 if (Look_Up(*(index),*(index+2),face_id)) 2018 981 { 2019 if ( (out1 != -1) && 2020 ( (out1 == *(index)) || 2021 (out1 == *(index+size-1)) ) && 2022 ( (out2 == *(index)) || 2023 (out2 == *(index+size-1)) )) 2024 { 2025 set = TRUE; 982 983 set = true; 2026 984 *edge1 = *(index); 2027 *edge2 = *(index+size-1); 2028 } 2029 else if (out1 == -1) 2030 { 2031 set = TRUE; 2032 *edge1 = *(index); 2033 *edge2 = *(index+size-1); 2034 } 2035 if ((reversed != -1) && (set)) 2036 return reversed; 985 *edge2 = *(index+2); 986 987 if ((reversed != -1)) 988 return reversed; 2037 989 } 2038 990 } 2039 2040 { 2041 if ((*(index+x) == id1) && (*(index+x+1)==id2))991 else 992 { 993 if ((*(index+x) == 0) && (*(index+x+1)==0)) 2042 994 { 2043 995 if (set) 2044 return 0;996 return 0; 2045 997 reversed = 0; 2046 998 } 2047 else if ((*(index+x) == id2) && (*(index+x+1)==id1))999 else if ((*(index+x) == 0) && (*(index+x+1)==0)) 2048 1000 { 2049 1001 if (set) 2050 return 1;1002 return 1; 2051 1003 reversed = 1; 2052 1004 } 2053 1005 2054 1006 if (Look_Up(*(index+x),*(index+x+1),face_id)) 2055 1007 { 2056 if ( (out1 != -1) && 2057 ( (out1 == *(index+x)) || 2058 (out1 == *(index+x+1)) ) && 2059 ((out2 == *(index+x)) || 2060 (out2 == *(index+x+1)))) 2061 { 2062 set = TRUE; 2063 *edge1 = *(index+x); 2064 *edge2 = *(index+x+1); 2065 } 2066 else if (out1 == -1) 2067 { 2068 set = TRUE; 1008 set = true; 2069 1009 *edge1 = *(index+x); 2070 1010 *edge2 = *(index+x + 1); 2071 } 2072 if ((reversed != -1) && (set))2073 return reversed;1011 1012 if ((reversed != -1)) 1013 return reversed; 2074 1014 } 2075 1015 } 2076 } 2077 if ((x == size) && (reversed != -1)) 2078 { 2079 /* Could not find the output edge */ 2080 printf("Error in the Lookup %d %d %d %d %d %d %d %d\n", 2081 face_id,id1,id2,reversed,*edge1,*edge2,out1,out2); 1016 } 1017 1018 if ((x == 3) && (reversed != -1)) 2082 1019 exit(0); 2083 } 1020 2084 1021 return reversed; 2085 1022 } 2086 1023 2087 /// Udate_Face: 2088 void CustomStripifier::Update_Face(int *next_bucket, int *min_face, int face_id, int *e1, 2089 int *e2,int temp1,int temp2,int *ties) 2090 { 2091 /* We have a face id that needs to be decremented. 2092 We have to determine where it is in the structure, 2093 so that we can decrement it. 2094 */ 2095 /* The number of adjacencies may have changed, so to locate 2096 it may be a little tricky. However we know that the number 2097 of adjacencies is less than or equal to the original number 2098 of adjacencies, 2099 */ 2100 int y,size; 2101 ListHead *pListHead; 2102 PF_FACES temp = NULL; 2103 PLISTINFO lpListInfo; 2104 static int each_poly = 0; 2105 BOOL there = FALSE; 2106 2107 pListHead = PolFaces[face_id]; 2108 temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 ); 2109 /* Check each edge of the face and tally the number of adjacent 2110 polygons to this face. 2111 */ 2112 if ( temp != NULL ) 2113 { 2114 /* Size of the polygon */ 2115 size = temp->nPolSize; 2116 /* We did it already */ 2117 if (size == 1) 2118 return; 2119 for (y = 0; y< size; y++) 2120 { 2121 /* If we are doing partial triangulation, we must check 2122 to see whether the edge is still there in the polygon, 2123 since we might have done a portion of the polygon 2124 and saved the rest for later. 2125 */ 2126 if (y != (size-1)) 1024 /// Update_FaceEx: 1025 void 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) 2127 1036 { 2128 if( ((temp1 == *(temp->pPolygon+y)) && 2129 (temp2 ==*(temp->pPolygon+y+1))) || 2130 ((temp2 == *(temp->pPolygon+y)) && 2131 (temp1 ==*(temp->pPolygon+y+1)))) 2132 /* edge is still there we are ok */ 2133 there = TRUE; 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; 2134 1042 } 2135 1043 else 2136 1044 { 2137 if( ((temp1 == *(temp->pPolygon)) && 2138 (temp2 == *(temp->pPolygon+size-1))) || 2139 ((temp2 == *(temp->pPolygon)) && 2140 (temp1 ==*(temp->pPolygon+size-1)))) 2141 /* edge is still there we are ok */ 2142 there = TRUE; 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; 2143 1050 } 2144 1051 } 2145 1052 2146 if (!there) 2147 /* Original edge was already used, we cannot use this polygon */ 2148 return; 2149 2150 /* We have a starting point to start our search to locate 2151 this polygon. 2152 */ 2153 2154 /* Check to see if this polygon was done */ 2155 lpListInfo = Done(face_id,&y); 2156 2157 if (lpListInfo == NULL) 2158 return; 2159 2160 /* Was not done, but there is an error in the adjacency calculations */ 2161 if (y == 0) 2162 { 2163 printf("There is an error in finding the adjacencies\n"); 2164 exit(0); 2165 } 2166 2167 /* Now put the face in the proper bucket depending on tally. */ 2168 /* First add it to the new bucket, then remove it from the old */ 2169 Add_Sgi_Adj(y-1,face_id); 2170 RemoveList(array[y],lpListInfo); 2171 2172 /* Save it if it was the smallest seen so far since then 2173 it will be the next face 2174 Here we will have different options depending on 2175 what we want for resolving ties: 2176 1) First one we see we will use 2177 2) Random resolving 2178 3) Look ahead 2179 4) Alternating direction 2180 */ 2181 /* At a new strip */ 2182 if (*next_bucket == 60) 2183 *ties = *ties + each_poly; 2184 /* Have a tie */ 2185 if (*next_bucket == (y-1)) 2186 { 2187 Add_Ties(face_id); 2188 each_poly++; 2189 } 2190 /* At a new minimum */ 2191 if (*next_bucket > (y-1)) 2192 { 2193 *next_bucket = y-1; 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; 2194 1076 *min_face = face_id; 2195 1077 *e1 = temp1; 2196 1078 *e2 = temp2; 2197 each_poly = 0; 2198 Clear_Ties(); 2199 Add_Ties(face_id); 2200 } 2201 } 2202 } 2203 2204 /// Delete_Adj: 2205 void CustomStripifier::Delete_Adj(int id1, int id2,int *next_bucket,int *min_face, 2206 int current_face,int *e1,int *e2,int *ties) 2207 { 2208 /* Find the face that is adjacent to the edge and is not the 2209 current face. Delete one adjacency from it. Save the min 2210 adjacency seen so far. 2211 */ 2212 register int count=0; 2213 PF_EDGES temp = NULL; 2214 ListHead *pListHead; 1079 last=0; 1080 ties_array[last++] = face_id; 1081 } 1082 } 1083 } 1084 1085 /// DeleteAdj: 1086 //Looking for another adajacent face 1087 void 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; 2215 1091 int next_face; 2216 1092 2217 /* Always want smaller id first */ 2218 switch_lower(&id1,&id2); 2219 2220 pListHead = PolEdges[id1]; 2221 temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count); 2222 if (temp == NULL) 2223 /* It could be a new edge that we created. So we can 2224 exit, since there is not a face adjacent to it. 2225 */ 1093 GetLower(&id1,&id2); 1094 1095 if (StripEdges[id1].empty()) 2226 1096 return; 2227 while (temp->edge[0] != id2) 2228 { 1097 1098 while (StripEdges[id1][count].array[0] != id2) 1099 { 2229 1100 count++; 2230 temp = ( PF_EDGES )GetNextNode(temp); 2231 2232 if (temp == NULL) 2233 /* Was a new edge that was created and therefore 2234 does not have anything adjacent to it 2235 */ 2236 return; 2237 } 2238 /* Was not adjacent to anything else except itself */ 2239 if (temp->edge[2] == -1) 1101 1102 if (count>=StripEdges[id1].size()) 1103 return; 1104 } 1105 1106 if (StripEdges[id1][count].array[2] == -1) //No more adjacencies 1107 { 2240 1108 return; 2241 2242 /* Was adjacent to something */ 1109 } 2243 1110 else 2244 { 2245 if (temp->edge[2] == current_face) 2246 next_face = temp->edge[1]; 2247 else 2248 next_face = temp->edge[2]; 2249 } 2250 /* We have the other face adjacent to this edge, it is 2251 next_face. Now we need to decrement this faces' adjacencies. 2252 */ 2253 Update_Face(next_bucket, min_face, next_face,e1,e2,id1,id2,ties); 2254 } 2255 2256 /// Update_Adjacencies: 2257 int CustomStripifier::Update_Adjacencies(int face_id, int *next_bucket, int *e1, int *e2, 2258 int *ties) 2259 { 2260 /* Give the face with id face_id, we want to decrement 2261 all the faces that are adjacent to it, since we will 2262 be deleting face_id from the data structure. 2263 We will return the face that has the least number 2264 of adjacencies. 2265 */ 2266 PF_FACES temp = NULL; 2267 ListHead *pListHead; 2268 int size,y,min_face = -1; 2269 2270 *next_bucket = 60; 2271 pListHead = PolFaces[face_id]; 2272 temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 ); 2273 2274 if ( temp == NULL ) 2275 { 2276 printf("The face was already deleted, there is an error\n"); 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: 1122 int 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() ) 2277 1129 exit(0); 2278 } 2279 2280 /* Size of the polygon */ 2281 size = temp->nPolSize; 2282 for (y = 0; y< size; y++) 2283 { 2284 if (y != (size-1)) 2285 Delete_Adj(*(temp->pPolygon+y),*(temp->pPolygon+y+1), 2286 next_bucket,&min_face,face_id,e1,e2,ties); 2287 else 2288 Delete_Adj(*(temp->pPolygon),*(temp->pPolygon+(size-1)), 2289 next_bucket,&min_face,face_id,e1,e2,ties); 2290 } 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 2291 1138 return (min_face); 2292 1139 } 2293 1140 2294 /// Old_Adj: 2295 int CustomStripifier::Old_Adj(int face_id) 2296 { 2297 /* Find the bucket that the face_id is currently in, 2298 because maybe we will be deleting it. 2299 */ 2300 PF_FACES temp = NULL; 2301 ListHead *pListHead; 2302 int y; 2303 2304 pListHead = PolFaces[face_id]; 2305 temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 ); 2306 if ( temp == NULL ) 2307 { 2308 printf("The face was already deleted, there is an error\n"); 2309 exit(0); 2310 } 2311 2312 if (Done(face_id,&y) == NULL) 2313 { 2314 printf("There is an error in finding the face\n"); 2315 exit(0); 2316 } 2317 return y; 2318 } 2319 2320 /// Number_Adj: 2321 int CustomStripifier::Number_Adj(int id1, int id2, int curr_id) 2322 { 2323 /* Given edge whose endpoints are specified by id1 and id2, 2324 determine how many polygons share this edge and return that 2325 number minus one (since we do not want to include the polygon 2326 that the caller has already). 2327 */ 2328 2329 int size,y,count=0; 2330 PF_EDGES temp = NULL; 2331 PF_FACES temp2 = NULL; 2332 ListHead *pListHead; 2333 BOOL there= FALSE; 2334 2335 /* Always want smaller id first */ 2336 switch_lower(&id1,&id2); 2337 2338 pListHead = PolEdges[id1]; 2339 temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count); 2340 if (temp == NULL) 2341 /* new edge that was created might not be here */ 2342 return 0; 2343 while (temp->edge[0] != id2) 2344 { 2345 count++; 2346 temp = ( PF_EDGES )GetNextNode(temp); 2347 2348 if (temp == NULL) 2349 /* This edge was not there in the original, which 2350 mean that we created it in the partial triangulation. 2351 So it is adjacent to nothing. 2352 */ 2353 return 0; 2354 } 2355 /* Was not adjacent to anything else except itself */ 2356 if (temp->edge[2] == -1) 2357 return 0; 2358 else 2359 { 2360 /* It was adjacent to another polygon, but maybe we did this 2361 polygon already, and it was done partially so that this edge 2362 could have been done 2363 */ 2364 if (curr_id != temp->edge[1]) 2365 { 2366 /* Did we use this polygon already?and it was deleted 2367 completely from the structure 2368 */ 2369 pListHead = PolFaces[temp->edge[1]]; 2370 temp2 = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 ); 2371 if (Done(temp->edge[1],&size) == NULL) 2372 return 0; 2373 } 2374 else 2375 { 2376 pListHead = PolFaces[temp->edge[2]]; 2377 temp2 = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 ); 2378 if (Done(temp->edge[2],&size)== NULL) 2379 return 0; 2380 } 2381 2382 /* Now we have to check whether it was partially done, before 2383 we can say definitely if it is adjacent. 2384 Check each edge of the face and tally the number of adjacent 2385 polygons to this face. 2386 */ 2387 if ( temp2 != NULL ) 2388 { 2389 /* Size of the polygon */ 2390 size = temp2->nPolSize; 2391 for (y = 0; y< size; y++) 2392 { 2393 /* If we are doing partial triangulation, we must check 2394 to see whether the edge is still there in the polygon, 2395 since we might have done a portion of the polygon 2396 and saved the rest for later. 2397 */ 2398 if (y != (size-1)) 2399 { 2400 if(((id1 == *(temp2->pPolygon+y)) && 2401 (id2 ==*(temp2->pPolygon+y+1))) || 2402 ((id2 == *(temp2->pPolygon+y)) && 2403 (id1 ==*(temp2->pPolygon+y+1)))) 2404 /* edge is still there we are ok */ 2405 there = TRUE; 2406 } 2407 else 2408 { 2409 if(((id1 == *(temp2->pPolygon)) && 2410 (id2 == *(temp2->pPolygon+size-1))) || 2411 ((id2 == *(temp2->pPolygon)) && 2412 (id1 ==*(temp2->pPolygon+size-1)))) 2413 /* edge is still there we are ok */ 2414 there = TRUE; 2415 } 2416 } 2417 } 2418 2419 if (there ) 2420 return 1; 2421 return 0; 2422 } 2423 } 2424 2425 /// Min_Adj: 2426 int CustomStripifier::Min_Adj(int id) 2427 { 2428 /* Used for the lookahead to break ties. It will 2429 return the minimum adjacency found at this face. 2430 */ 2431 int y,numverts,t,x=60; 2432 PF_FACES temp=NULL; 2433 ListHead *pListHead; 2434 2435 /* If polygon was used then we can't use this face */ 2436 if (Done(id,&y) == NULL) 2437 return 60; 2438 2439 /* It was not used already */ 2440 pListHead = PolFaces[id]; 2441 temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 ); 2442 if ( temp != NULL ) 2443 { 2444 numverts = temp->nPolSize; 2445 for (y = 0; y< numverts; y++) 2446 { 2447 if (y != (numverts-1)) 2448 t = Number_Adj(*(temp->pPolygon+y),*(temp->pPolygon+y+1),id); 2449 else 2450 t = Number_Adj(*(temp->pPolygon),*(temp->pPolygon+(numverts-1)),id); 2451 if (t < x) 2452 x = t; 2453 } 2454 } 2455 if (x == -1) 2456 { 2457 printf("Error in the look\n"); 2458 exit(0); 2459 } 2460 return x; 2461 } 2462 2463 /// Edje_Least: 2464 void CustomStripifier::Edge_Least(int *index,int *new1,int *new2,int face_id,int size) 2465 { 2466 /* We had a polygon without an input edge and now we re going to pick one 2467 of the edges with the least number of adjacencies to be the input 2468 edge 2469 */ 2470 register int x,value,smallest=60; 2471 2472 for (x = 0; x<size; x++) 2473 { 2474 if (x != (size -1) ) 2475 value = Number_Adj(*(index+x),*(index+x+1),face_id); 2476 else 2477 value = Number_Adj(*(index),*(index+size-1),face_id); 2478 if (value < smallest) 2479 { 2480 smallest = value; 2481 if (x != (size -1)) 2482 { 2483 *new1 = *(index+x); 2484 *new2 = *(index+x+1); 2485 } 2486 else 2487 { 2488 *new1 = *(index); 2489 *new2 = *(index+size-1); 2490 } 2491 } 2492 } 2493 if ((smallest == 60) || (smallest < 0)) 2494 { 2495 printf("There is an error in getting the least edge\n"); 2496 exit(0); 2497 } 2498 } 2499 2500 /// Check_In_Polygon: 2501 void CustomStripifier::Check_In_Polygon(int face_id, int *min, int size) 2502 { 2503 /* Check to see the adjacencies by going into a polygon that has 2504 greater than 4 sides. 2505 */ 2506 2507 ListHead *pListHead; 2508 PF_FACES temp; 2509 int y,id1,id2,id3,x=0,z=0; 2510 int saved[2]; 2511 int big_saved[60]; 2512 2513 pListHead = PolFaces[face_id]; 2514 temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 ); 2515 2516 /* Get the input edge that we came in on */ 2517 Last_Edge(&id1,&id2,&id3,0); 2518 2519 /* Find the number of adjacencies to the edges that are adjacent 2520 to the input edge. 2521 */ 2522 for (y=0; y< size; y++) 2523 { 2524 if (y != (size-1)) 2525 { 2526 if (((*(temp->pPolygon+y) == id2) && (*(temp->pPolygon+y+1) != id3)) 2527 || ((*(temp->pPolygon+y) == id3) && (*(temp->pPolygon+y+1) != id2))) 2528 { 2529 saved[x++] = Number_Adj(*(temp->pPolygon+y), 2530 *(temp->pPolygon+y+1),face_id); 2531 big_saved[z++] = saved[x-1]; 2532 } 2533 else 2534 big_saved[z++] = Number_Adj(*(temp->pPolygon+y), 2535 *(temp->pPolygon+y+1),face_id); 2536 } 2537 else 2538 { 2539 if (((*(temp->pPolygon) == id2) && 2540 (*(temp->pPolygon+size-1) != id3)) || 2541 ((*(temp->pPolygon) == id3) && 2542 (*(temp->pPolygon+size-1) != id2))) 2543 { 2544 saved[x++] = Number_Adj(*(temp->pPolygon), 2545 *(temp->pPolygon+size-1),face_id); 2546 big_saved[z++] = saved[x-1]; 2547 } 2548 else 2549 big_saved[z++] = Number_Adj(*(temp->pPolygon), 2550 *(temp->pPolygon+size-1),face_id); 2551 } 2552 } 2553 /* There was an input edge */ 2554 if (x == 2) 2555 { 2556 if (saved[0] < saved[1]) 2557 /* Count the polygon that we will be cutting as another adjacency*/ 2558 *min = saved[0] + 1; 2559 else 2560 *min = saved[1] + 1; 2561 } 2562 /* There was not an input edge */ 2563 else 2564 { 2565 if (z != size) 2566 { 2567 printf("There is an error with the z %d %d\n",size,z); 2568 exit(0); 2569 } 2570 *min = 60; 2571 for (x = 0; x < size; x++) 2572 { 2573 if (*min > big_saved[x]) 2574 *min = big_saved[x]; 2575 } 2576 } 2577 } 2578 2579 /// New_Face: 2580 void CustomStripifier::New_Face (int face_id, int v1, int v2, int v3) 2581 { 2582 /* We want to change the face that was face_id, we will 2583 change it to a triangle, since the rest of the polygon 2584 was already outputtted 2585 */ 2586 ListHead *pListHead; 2587 PF_FACES temp = NULL; 2588 2589 pListHead = PolFaces[face_id]; 2590 temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0); 2591 /* Check each edge of the face and tally the number of adjacent 2592 polygons to this face. 2593 */ 2594 if ( temp != NULL ) 2595 { 2596 /* Size of the polygon */ 2597 if (temp->nPolSize != 4) 2598 { 2599 printf("There is a miscalculation in the partial\n"); 2600 exit (0); 2601 } 2602 temp->nPolSize = 3; 2603 *(temp->pPolygon) = v1; 2604 *(temp->pPolygon+1) = v2; 2605 *(temp->pPolygon+2) = v3; 2606 } 2607 } 2608 2609 /// New_Size_Face: 2610 void CustomStripifier::New_Size_Face(int face_id) 2611 { 2612 /* We want to change the face that was face_id, we will 2613 change it to a triangle, since the rest of the polygon 2614 was already outputtted 2615 */ 2616 ListHead *pListHead; 2617 PF_FACES temp = NULL; 2618 2619 pListHead = PolFaces[face_id]; 2620 temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 ); 2621 /* Check each edge of the face and tally the number of adjacent 2622 polygons to this face. 2623 */ 2624 if ( temp != NULL ) 2625 (temp->nPolSize)--; 2626 else 2627 printf("There is an error in updating the size\n"); 2628 } 2629 2630 /// Check_In_Quad: 2631 void CustomStripifier::Check_In_Quad(int face_id,int *min) 2632 { 2633 /* Check to see what the adjacencies are for the polygons that 2634 are inside the quad, ie the 2 triangles that we can form. 2635 */ 2636 ListHead *pListHead; 2637 int y,id1,id2,id3,x=0; 2638 int saved[4]; 2639 PF_FACES temp; 2640 register int size = 4; 2641 2642 pListHead = PolFaces[face_id]; 2643 temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 ); 2644 2645 /* Get the input edge that we came in on */ 2646 Last_Edge(&id1,&id2,&id3,0); 2647 2648 /* Now find the adjacencies for the inside triangles */ 2649 for (y = 0; y< size; y++) 2650 { 2651 /* Will not do this if the edge is the input edge */ 2652 if (y != (size-1)) 2653 { 2654 if ((((*(temp->pPolygon+y) == id2) && 2655 (*(temp->pPolygon+y+1) == id3))) || 2656 (((*(temp->pPolygon+y) == id3) && 2657 (*(temp->pPolygon+y+1) == id2)))) 2658 saved[x++] = -1; 2659 else 2660 { 2661 if (x == 4) 2662 { 2663 printf("There is an error in the check in quad \n"); 2664 exit(0); 2665 } 2666 /* Save the number of Adjacent Polygons to this edge */ 2667 saved[x++] = Number_Adj(*(temp->pPolygon+y), 2668 *(temp->pPolygon+y+1),face_id); 2669 } 2670 } 2671 else if ((((*(temp->pPolygon) == id2) && 2672 (*(temp->pPolygon+size-1) == id3))) || 2673 (((*(temp->pPolygon) == id3) && 2674 (*(temp->pPolygon+size-1) == id2))) ) 2675 saved[x++] = -1; 2676 else 2677 { 2678 if (x == 4) 2679 { 2680 printf("There is an error in the check in quad \n"); 2681 exit(0); 2682 } 2683 /* Save the number of Adjacent Polygons to this edge */ 2684 saved[x++] = Number_Adj(*(temp->pPolygon), 2685 *(temp->pPolygon+size-1),face_id); 2686 2687 } 2688 } 2689 if (x != 4) 2690 { 2691 printf("Did not enter all the values %d \n",x); 2692 exit(0); 2693 } 2694 2695 *min = 10; 2696 for (x=0; x<4; x++) 2697 { 2698 if (x!= 3) 2699 { 2700 if ((saved[x] != -1) && (saved[x+1] != -1) && 2701 ((saved[x] + saved[x+1]) < *min)) 2702 *min = saved[x] + saved[x+1]; 2703 } 2704 else 2705 { 2706 if ((saved[0] != -1) && (saved[x] != -1) && 2707 ((saved[x] + saved[0]) < *min)) 2708 *min = saved[0] + saved[x]; 2709 } 2710 } 2711 } 2712 2713 /// Get_Output_Edge: 2714 int CustomStripifier::Get_Output_Edge(int face_id, int size, int *index,int id2,int id3) 2715 { 2716 /* Return the vertex adjacent to either input1 or input2 that 2717 is adjacent to the least number of polygons on the edge that 2718 is shared with either input1 or input2. 2719 */ 2720 register int x=0,y; 2721 int saved[2]; 2722 int edges[2][1]; 2723 2724 for (y = 0; y < size; y++) 2725 { 2726 if (y != (size-1)) 2727 { 2728 if (((*(index+y) == id2) && (*(index+y+1) != id3)) 2729 || ((*(index+y) == id3) && (*(index+y+1) != id2))) 2730 { 2731 saved[x++] = Number_Adj(*(index+y),*(index+y+1),face_id); 2732 edges[x-1][0] = *(index+y+1); 2733 } 2734 else if (y != 0) 2735 { 2736 if (( (*(index+y) == id2) && (*(index+y-1) != id3) ) || 2737 ( (*(index+y) == id3) && (*(index+y-1) != id2)) ) 2738 { 2739 saved[x++] = Number_Adj(*(index+y),*(index+y-1),face_id); 2740 edges[x-1][0] = *(index+y-1); 2741 } 2742 } 2743 else if (y == 0) 2744 { 2745 if (( (*(index) == id2) && (*(index+size-1) != id3) ) || 2746 ( (*(index) == id3) && (*(index+size-1) != id2)) ) 2747 { 2748 saved[x++] = Number_Adj(*(index),*(index+size-1),face_id); 2749 edges[x-1][0] = *(index+size-1); 2750 } 2751 } 2752 2753 } 2754 else 2755 { 2756 if (((*(index+size-1) == id2) && (*(index) != id3)) 2757 || ((*(index+size-1) == id3) && (*(index) != id2))) 2758 { 2759 saved[x++] = Number_Adj(*(index),*(index+size-1),face_id); 2760 edges[x-1][0] = *(index); 2761 } 2762 2763 if (( (*(index+size-1) == id2) && (*(index+y-1) != id3) ) || 2764 ( (*(index+size-1) == id3) && (*(index+y-1) != id2)) ) 2765 { 2766 saved[x++] = Number_Adj(*(index+size-1),*(index+y-1),face_id); 2767 edges[x-1][0] = *(index+y-1); 2768 } 2769 } 2770 } 2771 if ((x != 2)) 2772 { 2773 printf("There is an error in getting the input edge %d \n",x); 2774 exit(0); 2775 } 2776 if (saved[0] < saved[1]) 2777 return edges[0][0]; 2778 else 2779 return edges[1][0]; 2780 2781 } 2782 2783 /// Get_Input_Edge: 2784 void CustomStripifier::Get_Input_Edge(int *index,int id1,int id2,int id3, 2785 int *new1,int *new2,int size,int face_id) 2786 { 2787 /* We had a polygon without an input edge and now we are going to pick one 2788 as the input edge. The last triangle was id1,id2,id3, we will try to 2789 get an edge to have something in common with one of those vertices, 2790 otherwise we will pick the edge with the least number of adjacencies. 2791 */ 2792 2793 register int x; 2794 int saved[3]; 2795 2796 saved[0] = -1; 2797 saved[1] = -1; 2798 saved[2] = -1; 2799 2800 /* Go through the edges to see if there is one in common with one 2801 of the vertices of the last triangle that we had, preferably id2 or 2802 id3 since those are the last 2 things in the stack of size 2. 2803 */ 2804 for (x=0; x< size; x++) 2805 { 2806 if (*(index+x) == id1) 2807 { 2808 if (x != (size-1)) 2809 saved[0] = *(index+x+1); 2810 else 2811 saved[0] = *(index); 2812 } 2813 2814 if (*(index+x) == id2) 2815 { 2816 if (x != (size-1)) 2817 saved[1] = *(index+x+1); 2818 else 2819 saved[1] = *(index); 2820 } 2821 2822 if (*(index+x) == id3) 2823 { 2824 if (x != (size -1)) 2825 saved[2] = *(index+x+1); 2826 else 2827 saved[2] = *(index); 2828 } 2829 } 2830 /* Now see what we saved */ 2831 if (saved[2] != -1) 2832 { 2833 *new1 = id3; 2834 *new2 = saved[2]; 2835 return; 2836 } 2837 else if (saved[1] != -1) 2838 { 2839 *new1 = id2; 2840 *new2 = saved[1]; 2841 return; 2842 } 2843 else if (saved[0] != -1) 2844 { 2845 *new1 = id1; 2846 *new2 = saved[0]; 2847 return; 2848 } 2849 /* We did not find anything so get the edge with the 2850 least number of adjacencies 2851 */ 2852 Edge_Least(index,new1,new2,face_id,size); 2853 2854 } 2855 2856 /// Find_Face: 2857 int CustomStripifier::Find_Face(int current_face, int id1, int id2, int *bucket) 2858 { 2859 /* Find the face that is adjacent to the edge and is not the 2860 current face. 2861 */ 2862 register int size,y,count=0; 2863 PF_EDGES temp = NULL; 2864 PF_FACES temp2 = NULL; 2865 ListHead *pListHead; 2866 int next_face; 2867 BOOL there = FALSE; 2868 2869 2870 /* Always want smaller id first */ 2871 switch_lower(&id1,&id2); 2872 2873 pListHead = PolEdges[id1]; 2874 temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count); 2875 /* The input edge was a new edge */ 2876 if (temp == NULL) 2877 return -1; 2878 2879 while (temp->edge[0] != id2) 2880 { 2881 count++; 2882 temp = ( PF_EDGES )GetNextNode(temp); 2883 2884 /* The input edge was a new edge */ 2885 if (temp == NULL) 2886 return -1; 2887 } 2888 /* Was not adjacent to anything else except itself */ 2889 if (temp->edge[2] == -1) 2890 return -1; 2891 else 2892 { 2893 if (temp->edge[2] == current_face) 2894 next_face = temp->edge[1]; 2895 else 2896 next_face = temp->edge[2]; 2897 } 2898 /* We have the other face adjacent to this edge, it is 2899 next_face. 2900 */ 2901 pListHead = PolFaces[next_face]; 2902 temp2 = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 ); 2903 2904 /* See if the face was already deleted, and where 2905 it is if it was not 2906 */ 2907 2908 if (Done(next_face,bucket) == NULL) 2909 return -1; 2910 2911 /* Make sure the edge is still in this polygon, and that it is not 2912 done 2913 */ 2914 /* Size of the polygon */ 2915 size = temp2->nPolSize; 2916 for (y = 0; y< size; y++) 2917 { 2918 /* Make sure that the edge is still in the 2919 polygon and was not deleted, because if the edge was 2920 deleted, then we used it already. 2921 */ 2922 if (y != (size-1)) 2923 { 2924 if( ((id1 == *(temp2->pPolygon+y)) && (id2 ==*(temp2->pPolygon+y+1))) 2925 || ((id2 == *(temp2->pPolygon+y)) && (id1 ==*(temp2->pPolygon+y+1)))) 2926 /* edge is still there we are ok */ 2927 there = TRUE; 2928 } 2929 else 2930 { 2931 if(((id1 == *(temp2->pPolygon)) && (id2 ==*(temp2->pPolygon+size-1))) || 2932 ((id2 == *(temp2->pPolygon)) && (id1 ==*(temp2->pPolygon+size-1)))) 2933 /* edge is still there we are ok */ 2934 there = TRUE; 2935 } 2936 } 2937 2938 if (!there) 2939 /* Edge already used and deleted from the polygon*/ 2940 return -1; 2941 else 2942 return next_face; 2943 } 2944 2945 /// Look_Up: 2946 BOOL CustomStripifier::Look_Up(int id1,int id2,int face_id) 2947 { 2948 /* See if the endpoints of the edge specified by id1 and id2 2949 are adjacent to the face with face_id 2950 */ 2951 register int count = 0; 2952 PF_EDGES temp = NULL; 2953 ListHead *pListHead; 2954 2955 /* Always want smaller id first */ 2956 switch_lower(&id1,&id2); 2957 2958 pListHead = PolEdges[id1]; 2959 temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count); 2960 if (temp == NULL) 2961 /* Was a new edge that we created */ 2962 return 0; 2963 2964 while (temp->edge[0] != id2) 2965 { 2966 count++; 2967 temp = ( PF_EDGES )GetNextNode(temp); 2968 2969 if (temp == NULL) 2970 /* Was a new edge that we created */ 2971 return 0; 2972 } 2973 /* Was not adjacent to anything else except itself */ 2974 if ((temp->edge[2] == face_id) || (temp->edge[1] == face_id)) 2975 { 2976 /* Edge was adjacent to face, make sure that edge is 2977 still there 2978 */ 2979 if (Exist(face_id,id1,id2)) 2980 return 1; 2981 else 2982 return 0; 2983 } 2984 else 2985 return 0; 2986 } 2987 2988 /// Add_Id_Strips: 2989 void CustomStripifier::Add_Id_Strips(int id, int where) 2990 { 2991 /* Just save the triangle for later */ 2992 P_STRIPS pfNode; 2993 2994 pfNode = (P_STRIPS) malloc(sizeof(Strips) ); 2995 if ( pfNode ) 2996 { 2997 pfNode->face_id = id; 2998 if (where == 1) 2999 AddTail(strips[0],(PLISTINFO) pfNode); 3000 /* We are backtracking in the strip */ 3001 else 3002 AddHead(strips[0],(PLISTINFO) pfNode); 3003 } 3004 else 3005 { 3006 printf("There is not enough memory to allocate for the strips\n"); 3007 exit(0); 3008 } 3009 } 3010 3011 /// Num_Adj: 3012 int CustomStripifier::Num_Adj(int id1, int id2) 3013 { 3014 /* Given edge whose endpoints are specified by id1 and id2, 3015 determine how many polygons share this edge and return that 3016 number minus one (since we do not want to include the polygon 3017 that the caller has already). 3018 */ 3019 3020 PF_EDGES temp = NULL; 3021 ListHead *pListHead; 3022 register count=-1; 3023 3024 /* Always want smaller id first */ 3025 switch_lower(&id1,&id2); 3026 3027 pListHead = PolEdges[id1]; 3028 temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count); 3029 if (temp == NULL) 3030 { 3031 printf("There is an error in the creation of the table \n"); 3032 exit(0); 3033 } 3034 while (temp->edge[0] != id2) 3035 { 3036 count++; 3037 temp = ( PF_EDGES )GetNextNode(temp); 3038 3039 if (temp == NULL) 3040 { 3041 printf("There is an error in the creation of the table\n"); 3042 exit(0); 3043 } 3044 } 3045 /* Was not adjacent to anything else except itself */ 3046 if (temp->edge[2] == -1) 3047 return 0; 3048 return 1; 3049 } 3050 3051 /// Add_Sgi_Adj: 3052 void CustomStripifier::Add_Sgi_Adj(int bucket,int face_id) 3053 { 3054 /* This routine will add the face to the proper bucket, 3055 depending on how many faces are adjacent to it (what the 3056 value bucket should be). 3057 */ 3058 P_ADJACENCIES pfNode; 3059 3060 pfNode = (P_ADJACENCIES) malloc(sizeof(ADJACENCIES) ); 3061 if ( pfNode ) 3062 { 3063 pfNode->face_id = face_id; 3064 AddHead(array[bucket],(PLISTINFO) pfNode); 3065 face_array[face_id].bucket = bucket; 3066 face_array[face_id].pfNode = pfNode; 3067 face_array[face_id].head = array[bucket]; 3068 } 3069 else 3070 { 3071 printf("Out of memory for the SGI adj list!\n"); 3072 exit(0); 3073 } 3074 } 3075 3076 /// Find_Adjacencies: 3077 void CustomStripifier::Find_Adjacencies(int num_faces) 3078 { 3079 register int x,y; 3080 register int numverts; 3081 PF_FACES temp =NULL; 3082 ListHead* pListHead; 3083 3084 /* Fill in the adjacencies data structure for all the faces */ 3085 for (x=0;x<num_faces;x++) 3086 { 3087 pListHead = PolFaces[x]; 3088 temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 ); 3089 if ( temp != NULL ) 3090 { 3091 numverts = temp->nPolSize; 3092 if (numverts != 1) 3093 { 3094 for (y = 0; y< numverts; y++) 3095 { 3096 if (y != (numverts-1)) 3097 Add_AdjEdge(*(temp->pPolygon+y), 3098 *(temp->pPolygon+y+1),x,y); 3099 3100 else 3101 Add_AdjEdge(*(temp->pPolygon), 3102 *(temp->pPolygon+(numverts-1)),x,numverts-1); 3103 3104 } 3105 } 3106 temp = NULL; 3107 } 3108 } 3109 } 3110 3111 /// Clear_Ties: 3112 void CustomStripifier::Clear_Ties() 3113 { 3114 /* Clear the buffer, because we do not have the tie 3115 any more that we had before */ 3116 last = 0; 3117 } 3118 3119 /// Add_Ties: 3120 void CustomStripifier::Add_Ties(int id) 3121 { 3122 /* We have a tie to add to the buffer */ 3123 ties_array[last++] = id; 3124 } 3125 3126 /// Alternate_Tie: 3127 int CustomStripifier::Alternate_Tie() 3128 { 3129 /* Alternate in what we choose to break the tie 3130 We are just alternating between the first and 3131 second thing that we found 3132 */ 3133 static int x = 0; 3134 register int t; 3135 3136 t = ties_array[x]; 3137 x++; 3138 if (x == 2) 3139 x = 0; 3140 return t; 3141 } 3142 3143 /// Random_Tie: 3144 int CustomStripifier::Random_Tie() 3145 { 3146 /* Randomly choose the next face with which 3147 to break the tie 3148 */ 3149 register int num; 3150 3151 num = rand(); 3152 while (num >= last) 3153 num = num/20; 3154 return (ties_array[num]); 3155 } 3156 3157 /// Look_Ahead: 3158 int CustomStripifier::Look_Ahead(int id) 3159 { 3160 /* Look ahead at this face and save the minimum 3161 adjacency of all the faces that are adjacent to 3162 this face. 3163 */ 3164 return Min_Adj(id); 3165 } 3166 3167 /// Random_Look: 3168 int CustomStripifier::Random_Look(int id[],int count) 3169 { 3170 /* We had a tie within a tie in the lookahead, 3171 break it randomly 3172 */ 3173 register int num; 3174 3175 num = rand(); 3176 while (num >= count) 3177 num = num/20; 3178 return (id[num]); 3179 } 3180 3181 /// Look_Ahead_Tie: 3182 int CustomStripifier::Look_Ahead_Tie() 3183 { 3184 /* Look ahead and find the face to go to that 3185 will give the least number of adjacencies 3186 */ 3187 int id[60],t,x,f=0,min = 60; 3188 3189 for (x = 0; x < last; x++) 3190 { 3191 t = Look_Ahead(ties_array[x]); 3192 /* We have a tie */ 3193 if (t == min) 3194 id[f++] = ties_array[x]; 3195 if (t < min) 3196 { 3197 f = 0; 3198 min = t; 3199 id[f++] = ties_array[x]; 3200 } 3201 } 3202 /* No tie within the tie */ 3203 if ( f == 1) 3204 return id[0]; 3205 /* Or ties, but we are at the end of strips */ 3206 if (min == 0) 3207 return id[0]; 3208 return (Random_Look(id,f)); 3209 } 3210 3211 /// Sequential_Tri: 3212 int CustomStripifier::Sequential_Tri(int *index) 3213 { 3214 /* We have a triangle and need to break the ties at it. 3215 We will choose the edge that is sequential. There 3216 is definitely one since we know we have a triangle 3217 and that there is a tie and there are only 2 edges 3218 for the tie. 3219 */ 3220 int reversed,e1,e2,e3,output1,output2,output3,output4; 3221 3222 /* e2 and e3 are the input edge to the triangle */ 3223 Last_Edge(&e1,&e2,&e3,0); 3224 3225 if ((e2 == 0) && (e3 == 0)) 3226 /* Starting the strip, don't need to do this */ 3227 return ties_array[0]; 3228 3229 /* For the 2 ties find the edge adjacent to face id */ 3230 reversed = Get_EdgeEx(&output1,&output2,index,ties_array[0],3,0,0); 3231 reversed = Get_EdgeEx(&output3,&output4,index,ties_array[1],3,0,0); 3232 3233 if ((output1 == e3) || (output2 == e3)) 3234 return ties_array[0]; 3235 if ((output3 == e3) || (output4 == e3)) 3236 return ties_array[1]; 3237 printf("There is an error trying to break sequential triangle \n"); 3238 return -1; 3239 } 3240 3241 /// Sequential_Quad: 3242 int CustomStripifier::Sequential_Quad(int *index, int triangulate) 3243 { 3244 /* We have a quad that need to break its ties, we will try 3245 and choose a side that is sequential, otherwise use lookahead 3246 */ 3247 int reversed,output1,output2,x,e1,e2,e3; 3248 3249 /* e2 and e3 are the input edge to the quad */ 3250 Last_Edge(&e1,&e2,&e3,0); 3251 3252 /* No input edge */ 3253 if ((e2 == 0) && (e3 == 0)) 3254 return ties_array[0]; 3255 3256 /* Go through the ties and see if there is a sequential one */ 3257 for (x = 0; x < last; x++) 3258 { 3259 reversed = Get_EdgeEx(&output1,&output2,index,ties_array[x],4,0,0); 3260 /* Partial and whole triangulation will have different requirements */ 3261 if (((output1 == e3) || (output2 == e3)) && (triangulate == PARTIAL)) 3262 return ties_array[x]; 3263 if (((output1 != e3) && (output1 != e2) && 3264 (output2 != e3) && (output2 != e2))) 3265 return ties_array[x]; 3266 } 3267 /* There was not a tie that was sequential */ 3268 return Look_Ahead_Tie(); 3269 } 3270 3271 /// Whole_Output: 3272 void CustomStripifier::Whole_Output(int in1, int *index, int size, int *out1, int *out2) 3273 { 3274 /* Used to sequentially break ties in the whole triangulation for polygons 3275 greater than 4 sides. We will find the output edge that is good 3276 for sequential triangulation. 3277 */ 3278 3279 int half; 3280 3281 /* Put the input edge first in the list */ 3282 Rearrange_IndexEx(index,size); 3283 3284 if (!(EVEN(size))) 3285 { 3286 if (*(index) == in1) 3287 half = size/2 ; 3288 else 3289 half = size/2 +1; 3290 } 3291 else 3292 half = size/2; 3293 3294 *out1 = *(index+half); 3295 *out2 = *(index+half+1); 3296 } 3297 3298 /// Sequential_Poly: 3299 int CustomStripifier::Sequential_Poly(int size, int *index, int triangulate) 3300 { 3301 /* We have a polygon of greater than 4 sides and wish to break the 3302 tie in the most sequential manner. 3303 */ 3304 3305 int x,reversed,output1,output2,e1,e2,e3,saved1=-1,saved2=-1,output3,output4; 3306 3307 /* e2 and e3 are the input edge to the quad */ 3308 Last_Edge(&e1,&e2,&e3,0); 3309 3310 /* If we are using whole, find the output edge that is sequential */ 3311 if (triangulate == WHOLE) 3312 Whole_Output(e2,index,size,&output3,&output4); 3313 3314 /* No input edge */ 3315 if ((e2 == 0) && (e3 == 0)) 3316 return ties_array[0]; 3317 3318 for (x = 0; x < last ; x++) 3319 { 3320 reversed = Get_EdgeEx(&output1,&output2,index,ties_array[x],size,0,0); 3321 /* Partial that can be removed in just one triangle */ 3322 if (((output1 == e3) || (output2 == e3)) && (triangulate == PARTIAL)) 3323 saved1 = ties_array[x]; 3324 /* Partial removed in more than one triangle */ 3325 if ((output1 != e3) && (output1 != e2) && 3326 (output2 != e3) && (output2 != e2) && 3327 (triangulate == PARTIAL) && (saved2 != -1)) 3328 saved2 = ties_array[x]; 3329 /* Whole is not so easy, since the whole polygon must be done. Given 3330 an input edge there is only one way to come out, approximately half 3331 way around the polygon. 3332 */ 3333 if (((output1 == output3) && (output2 == output4)) || 3334 ((output1 == output4) && (output2 == output3)) && 3335 (triangulate == WHOLE)) 3336 return ties_array[x]; 3337 } 3338 3339 if (saved1 != -1) 3340 return saved1; 3341 if (saved2 != -1) 3342 return saved2; 3343 3344 /* There was not a tie that was sequential */ 3345 return Look_Ahead_Tie(); 3346 } 3347 3348 /// Sequential_Tie: 3349 int CustomStripifier::Sequential_Tie(int face_id,int triangulate) 3350 { 3351 /* Break the tie by choosing the face that will 3352 not give us a swap and is sequential. If there 3353 is not one, then do the lookahead to break the 3354 tie. 3355 */ 3356 /* Separate into 3 cases for simplicity, if the current 3357 polygon has 3 sides, 4 sides or if the sides were 3358 greater. We can do the smaller cases faster, so that 3359 is why I separated the cases. 3360 */ 3361 3362 ListHead *pListFace; 3363 PF_FACES face; 3364 3365 /* Get the polygon with id face_id */ 3366 pListFace = PolFaces[face_id]; 3367 face = (PF_FACES) PeekList(pListFace,LISTHEAD,0); 3368 3369 if (face->nPolSize == 3) 3370 return(Sequential_Tri(face->pPolygon)); 3371 if (face->nPolSize == 4) 3372 return(Sequential_Quad(face->pPolygon,triangulate)); 3373 else 3374 return(Sequential_Poly(face->nPolSize,face->pPolygon,triangulate)); 3375 3376 } 3377 3378 /// Get_Next_Face: 3379 int CustomStripifier::Get_Next_Face(int t, int face_id, int triangulate) 3380 { 3381 /* Get the next face depending on what 3382 the user specified 3383 */ 3384 3385 /* Did not have a tie, don't do anything */ 3386 if (last == 1) 3387 return(ties_array[0]); 3388 if (t == RANDOM) 3389 return Random_Tie(); 3390 if (t == ALTERNA) 3391 return Alternate_Tie(); 3392 if (t == LOOK) 3393 return Look_Ahead_Tie(); 3394 if (t == SEQUENTIAL) 3395 return Sequential_Tie(face_id,triangulate); 3396 3397 printf("Illegal option specified for ties, using first \n"); 3398 return (ties_array[0]); 3399 } 3400 3401 /// new_vertex: 3402 BOOL CustomStripifier::new_vertex(double difference, int id1,int id2, 3403 struct vert_struct *n) 3404 { 3405 /* Is the difference between id1 and id2 (2 normal vertices that 3406 mapped to the same vertex) greater than the 3407 threshold that was specified? 3408 */ 3409 struct vert_struct *pn1,*pn2; 3410 double dot_product; 3411 double distance1, distance2,distance; 3412 double rad; 3413 char arg1[100]; 3414 char arg2[100]; 3415 3416 pn1 = n + id1; 3417 pn2 = n + id2; 3418 3419 dot_product = ((pn1->x) * (pn2->x)) + 3420 ((pn1->y) * (pn2->y)) + 3421 ((pn1->z) * (pn2->z)); 3422 /* Get the absolute value */ 3423 if (dot_product < 0) 3424 dot_product = dot_product * -1; 3425 3426 distance1 = sqrt( (pn1->x * pn1->x) + 3427 (pn1->y * pn1->y) + 3428 (pn1->z * pn1->z) ); 3429 distance2 = sqrt( (pn2->x * pn2->x) + 3430 (pn2->y * pn2->y) + 3431 (pn2->z * pn2->z) ); 3432 distance = distance1 * distance2; 3433 3434 rad = acos((double)dot_product/(double)distance); 3435 /* convert to degrees */ 3436 rad = (180 * rad)/GEO_PI; 3437 3438 if ( rad <= difference) 3439 return FALSE; 3440 3441 /* double checking because of imprecision with floating 3442 point acos function 3443 */ 3444 sprintf( arg1,"%.5f", rad ); 3445 sprintf( arg2,"%.5f", difference ); 3446 if ( strcmp( arg1, arg2 ) <=0 ) 3447 return( FALSE ); 3448 if ( rad <= difference) 3449 return FALSE; 3450 else 3451 return TRUE; 3452 } 3453 3454 /// Check_VN: 3455 BOOL CustomStripifier::Check_VN(int vertex,int normal, struct vert_added *added) 3456 { 3457 /* Check to see if we already added this vertex and normal */ 3458 register int x,n; 3459 3460 n = (added+vertex)->num; 3461 for (x = 0; x < n; x++) 3462 { 3463 if (*((added+vertex)->normal+x) == normal) 3464 return TRUE; 3465 } 3466 return FALSE; 3467 } 3468 3469 /// norm_array: 3470 BOOL CustomStripifier::norm_array(int id, int vertex, double normal_difference, 3471 struct vert_struct *n, int num_vert) 3472 { 3473 static int last; 3474 static struct vert_added *added; 3475 register int x; 3476 static BOOL first = TRUE; 3477 3478 if (first) 3479 { 3480 /* This is the first time that we are in here, so we will allocate 3481 a structure that will save the vertices that we added, so that we 3482 do not add the same thing twice 3483 */ 3484 first = FALSE; 3485 added = (struct vert_added *) malloc (sizeof (struct vert_added ) * num_vert); 3486 /* The number of vertices added for each vertex must be initialized to 3487 zero 3488 */ 3489 for (x = 0; x < num_vert; x++) 3490 (added+x)->num = 0; 3491 } 3492 3493 if (vertex) 3494 /* Set the pointer to the vertex, we will be calling again with the 3495 normal to fill it with 3496 */ 3497 last = id; 3498 else 3499 { 3500 /* Fill the pointer with the id of the normal */ 3501 if (*(vert_norms + last) == 0) 3502 *(vert_norms + last) = id; 3503 else if ((*(vert_norms + last) != id) && ((int)normal_difference != 360)) 3504 { 3505 /* difference is big enough, we need to create a new vertex */ 3506 if (new_vertex(normal_difference,id,*(vert_norms + last),n)) 3507 { 3508 /* First check to see if we added this vertex and normal already */ 3509 if (Check_VN(last,id,added)) 3510 return FALSE; 3511 /* OK, create the new vertex, and have its id = the number of 3512 vertices and its normal what we have here 3513 */ 3514 vert_norms = (int *)realloc(vert_norms, sizeof(int) * (num_vert + 1)); 3515 if (!vert_norms) 3516 { 3517 printf("Allocation error - aborting\n"); 3518 exit(1); 3519 } 3520 *(vert_norms + num_vert) = id; 3521 /* We created a new vertex, now put it in our added structure so 3522 we do not add the same thing twice 3523 */ 3524 (added+last)->num = (added+last)->num + 1; 3525 if ((added+last)->num == 1) 3526 { 3527 /* First time */ 3528 (added+last)->normal = (int *) malloc (sizeof (int ) * 1); 3529 *((added+last)->normal) = id; 3530 } 3531 else 3532 { 3533 /* Not the first time, reallocate space */ 3534 (added+last)->normal = (int *)realloc((added+last)->normal, sizeof(int) * (added+last)->num); 3535 *((added+last)->normal+((added+last)->num-1)) = id; 3536 } 3537 return TRUE; 3538 } 3539 } 3540 } 3541 return FALSE; 3542 } 3543 3544 /// add_texture: 3545 void CustomStripifier::add_texture(int id,BOOL vertex) 3546 { 3547 /* Save the texture with its vertex for future use when outputting */ 3548 static int last; 3549 3550 if (vertex) 3551 last = id; 3552 else 3553 *(vert_texture+last) = id; 3554 } 3555 3556 /// add_vert_id: 3557 int CustomStripifier::add_vert_id(int id, int index_count) 3558 { 3559 register int x; 3560 3561 // Test if degenerate, if so do not add degenerate vertex 3562 for (x = 1; x < index_count ; x++) 3563 { 3564 if (ids[x] == id) 3565 return 0; 3566 } 3567 ids[index_count] = id; 3568 3569 return 1; 3570 } 3571 3572 /// add_norm_id: 3573 void CustomStripifier::add_norm_id(int id, int index_count) 3574 { 3575 norms[index_count] = id; 3576 } 3577 3578 /// AddNewFace: 3579 void CustomStripifier::AddNewFace(int ids[MAX1], int vert_count, int face_id, int norms[MAX1]) 3580 { 3581 PF_FACES pfNode; 3582 PF_VERTICES pfVertNode; 3583 int *pTempInt; 3584 int *pnorms; 3585 F_EDGES **pTempVertptr; 3586 int *pTempmarked; 3587 int *pTempwalked; 3588 register int y; 3589 register int count = 0; 3590 3591 // Add a new face into our face data structure 3592 pfNode = (PF_FACES) malloc(sizeof(F_FACES)); 3593 3594 if (pfNode) 3595 { 3596 pfNode->pPolygon = (int*) malloc(sizeof(int) * (vert_count) ); 3597 pfNode->pNorms = (int*) malloc(sizeof(int) * (vert_count) ); 3598 3599 pfNode->VertandId = (F_EDGES**)malloc(sizeof(F_EDGES*) 3600 * 3601 (vert_count)); 3602 3603 pfNode->marked = (int*)malloc(sizeof(int) * (vert_count)); 3604 pfNode->walked = (int*)malloc(sizeof(int) * (vert_count)); 3605 } 3606 3607 pTempInt = pfNode->pPolygon; 3608 pnorms = pfNode->pNorms; 3609 pTempmarked = pfNode->marked; 3610 pTempwalked = pfNode->walked; 3611 pTempVertptr = pfNode->VertandId; 3612 pfNode->nPolSize = vert_count; 3613 pfNode->nOrgSize = vert_count; 3614 pfNode->seen = -1; 3615 pfNode->seen2 = -1; 3616 3617 for (y = 1; y <= vert_count; y++) 3618 { 3619 *(pTempInt + count) = ids[y]; 3620 *(pnorms + count) = norms[y]; 3621 *(pTempmarked + count) = FALSE; 3622 *(pTempwalked + count) = -1; 3623 *(pTempVertptr+count) = NULL; 3624 3625 count++; 3626 3627 /* Add this FaceNode to the Vertices Structure */ 3628 pfVertNode = (PF_VERTICES) malloc(sizeof(F_VERTICES)); 3629 pfVertNode->face = pfNode; 3630 3631 AddHead(Vertices[ids[y]],(PLISTINFO) pfVertNode); 3632 } 3633 3634 AddHead(PolFaces[face_id-1],(PLISTINFO) pfNode); 3635 3636 } 3637 3638 /// CopyFace: 3639 void CustomStripifier::CopyFace(int ids[MAX1], int vert_count, int face_id, int norms[MAX1]) 3640 { 3641 PF_FACES pfNode; 3642 int *pTempInt; 3643 int *pnorms; 3644 F_EDGES **pTempVertptr; 3645 int *pTempmarked; 3646 int *pTempwalked; 3647 register int y; 3648 register int count = 0; 3649 3650 /* Copy a face node into a new node, used after the global algorithm 3651 is run, so that we can save whatever is left into a new structure 3652 */ 3653 3654 pfNode = (PF_FACES) malloc(sizeof(F_FACES)); 3655 3656 if ( pfNode ) 3657 { 3658 pfNode->pPolygon = (int*) malloc( sizeof(int) 3659 * 3660 (vert_count)); 3661 3662 pfNode->pNorms = (int*) malloc( sizeof(int) 3663 * 3664 (vert_count)); 3665 3666 pfNode->VertandId = (F_EDGES**) malloc( sizeof(F_EDGES*) 3667 * 3668 (vert_count)); 3669 3670 pfNode->marked = (int*)malloc(sizeof(int) * (vert_count)); 3671 pfNode->walked = (int*)malloc(sizeof(int) * (vert_count)); 3672 } 3673 3674 pTempInt = pfNode->pPolygon; 3675 pnorms = pfNode->pNorms; 3676 pTempmarked = pfNode->marked; 3677 pTempwalked = pfNode->walked; 3678 pTempVertptr = pfNode->VertandId; 3679 pfNode->nPolSize = vert_count; 3680 pfNode->nOrgSize = vert_count; 3681 pfNode->seen = -1; 3682 pfNode->seen2 = -1; 3683 3684 for (y = 0; y < vert_count; y++) 3685 { 3686 *(pTempInt + count) = ids[y]; 3687 *(pnorms + count) = norms[y]; 3688 *(pTempmarked + count) = FALSE; 3689 *(pTempwalked + count) = -1; 3690 *(pTempVertptr+count) = NULL; 3691 3692 count++; 3693 } 3694 3695 AddHead(PolFaces[face_id-1],(PLISTINFO) pfNode); 3696 } 3697 3698 /// Add_AdjEdge: 3699 void CustomStripifier::Add_AdjEdge(int v1,int v2,int fnum,int index1 ) 3700 { 3701 PF_EDGES temp = NULL; 3702 PF_FACES temp2 = NULL; 3703 PF_EDGES pfNode; 3704 ListHead *pListHead; 3705 ListHead *pListFace; 3706 BOOL flag = TRUE; 3707 register int count = 0; 3708 register int t; 3709 register int v3 = -1; 3710 3711 if (v1 > v2) 3712 { 3713 t = v1; 3714 v1 = v2; 3715 v2 = t; 3716 } 3717 3718 pListFace = PolFaces[fnum]; 3719 temp2 = (PF_FACES) PeekList(pListFace,LISTHEAD,0); 3720 pListHead = PolEdges[v1]; 3721 temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count); 3722 3723 if (temp == NULL) 3724 { 3725 flag = FALSE; 3726 } 3727 3728 count++; 3729 3730 while (flag) 3731 { 3732 if (v2 == temp->edge[0]) 3733 { 3734 /* If greater than 2 polygons adjacent to an edge, 3735 then we will only save the first 2 that we found. 3736 We will have a small performance hit, 3737 but this does not happen often. 3738 */ 3739 if (temp->edge[2] == -1) 3740 { 3741 temp->edge[2] = fnum; 3742 } 3743 else 3744 { 3745 v3 = temp->edge[2]; 3746 3747 // More than 3 edges are adjacent. 3748 // The mesh is not Manifold. 3749 mError = 1; 3750 } 3751 3752 flag = FALSE; 3753 } 3754 else 3755 { 3756 temp = ( PF_EDGES ) GetNextNode(temp); 3757 3758 count++; 3759 3760 if (temp == NULL) 3761 { 3762 flag = FALSE; 3763 } 3764 } 3765 } 3766 3767 /* Did not find it */ 3768 if (temp == NULL) 3769 { 3770 pfNode = (PF_EDGES) malloc(sizeof(F_EDGES)); 3771 3772 if (pfNode) 3773 { 3774 pfNode->edge[0] = v2; 3775 pfNode->edge[1] = fnum; 3776 pfNode->edge[2] = v3; 3777 3778 AddTail(PolEdges[v1], (PLISTINFO) pfNode); 3779 } 3780 else 3781 { 3782 printf("Out of memory!\n"); 3783 exit(1); 3784 } 3785 3786 *(temp2->VertandId+index1) = pfNode; 3787 } 3788 else 3789 { 3790 *(temp2->VertandId+index1) = temp; 3791 } 3792 } 3793 3794 /// power_10: 3795 int CustomStripifier::power_10(int power) 3796 { 3797 /* Raise 10 to the power */ 3798 register int i,p; 3799 3800 p = 1; 3801 for (i = 1; i <= power; ++i) 3802 p = p * 10; 3803 return p; 3804 } 3805 3806 /// power_negative: 3807 float CustomStripifier::power_negative(int power) 3808 { 3809 /* Raise 10 to the negative power */ 3810 3811 register int i; 3812 float p; 3813 3814 p = (float)1; 3815 for (i = 1; i<=power; i++) 3816 p = p * (float).1; 3817 return p; 3818 } 3819 3820 /// convert_array: 3821 float CustomStripifier::convert_array(int num[],int stack_size) 3822 { 3823 /* Convert an array of characters to an integer */ 3824 3825 register int counter,c; 3826 float temp =(float)0.0; 3827 3828 for (c=(stack_size-1), counter = 0; c>=0; c--, counter++) 3829 { 3830 if (num[c] == -1) 3831 /* We are at the decimal point, convert to decimal 3832 less than 1 3833 */ 3834 { 3835 counter = -1; 3836 temp = power_negative(stack_size - c - 1) * temp; 3837 } 3838 else 3839 temp += power_10(counter) * num[c]; 3840 } 3841 3842 return(temp); 3843 } 3844 3845 /// print_usage: 3846 void CustomStripifier::print_usage(void) 3847 { 3848 printf("Usage: stripe [abfglopqrw] file_name\n"); 3849 printf("Options:\n"); 3850 printf(" -b\tSpecifies that the input file is in binary\n"); 3851 printf(" -g\tFind triangle strips only within the groups specified in the data file\n"); 3852 printf(" -o\tTurn off orientation checking\n\n"); 3853 3854 printf("Tie Breaking:\n"); 3855 printf(" -a\tAlternate left-right direction in choosing next polygon\n"); 3856 printf(" -f\tChoose the first polygon that it found\n"); 3857 printf(" -l\tLook ahead one level in choosing the next polygon\n"); 3858 printf(" -q\tChoose the polygon which does not produce a swap\n"); 3859 printf(" -r\tRandomly choose the next polygon\n\n"); 3860 3861 printf("Triangulation:\n"); 3862 printf(" -p\tPartially triangulate faces\n"); 3863 printf(" -w\tFully triangluate faces\n"); 3864 } 3865 3866 /// get_options: 3867 float CustomStripifier::get_options(int argc, 3868 char **argv, 3869 int *f, 3870 int *t, 3871 int *tr, 3872 int *group, 3873 int *orientation) 3874 { 3875 char c; 3876 int count = 0; 3877 int buffer[MAX1]; 3878 int next = 0; 3879 /* tie variable */ 3880 enum tie_options tie = FIRST; 3881 /* triangulation variable */ 3882 enum triangulation_options triangulate = WHOLE; 3883 /* normal difference variable (in degrees) */ 3884 float norm_difference = (float)360.0; 3885 /* file-type variable */ 3886 enum file_options file_type = ASCII; 3887 3888 *orientation = 1; 3889 3890 /* User has the wrong number of options */ 3891 if ((argc > 6) || (argc < 2)) 3892 { 3893 print_usage(); 3894 exit(0); 3895 } 3896 3897 /* Interpret the options specified */ 3898 while (--argc > 0 && (*++argv)[0] == '-') 3899 { 3900 /* At the next option that was specified */ 3901 next = 1; 3902 while ((c = *++argv[0])) 3903 switch (c) 3904 { 3905 case 'f': 3906 /* Use the first polygon we see. */ 3907 tie = FIRST; 3908 break; 3909 3910 case 'r': 3911 /* Randomly choose the next polygon */ 3912 tie = RANDOM; 3913 break; 3914 3915 case 'a': 3916 /* Alternate direction in choosing the next polygon */ 3917 tie = ALTERNA; 3918 break; 3919 3920 case 'l': 3921 /* Use lookahead to choose the next polygon */ 3922 tie = LOOK; 3923 break; 3924 3925 case 'q': 3926 /* Try to reduce swaps */ 3927 tie = SEQUENTIAL; 3928 break; 3929 3930 case 'p': 3931 /* Use partial triangulation of polygons */ 3932 triangulate = PARTIAL; 3933 break; 3934 3935 case 'w': 3936 /* Use whole triangulation of polygons */ 3937 triangulate = WHOLE; 3938 break; 3939 3940 case 'b': 3941 /* Input file is in binary */ 3942 file_type = BINARY; 3943 break; 3944 3945 case 'g': 3946 /* Strips will be grouped according to the groups in 3947 the data file. We will have to restrict strips to be 3948 in the grouping of the data file. 3949 */ 3950 *group = 1; 3951 break; 3952 3953 case 'o': 3954 *orientation = 0; 3955 3956 /* Get each the value of the integer */ 3957 /* We have an integer */ 3958 default: 3959 if ((c >= '0') && (c <= '9')) 3960 { 3961 /* More than one normal difference specified, use the last one */ 3962 if (next == 1) 3963 { 3964 count = 0; 3965 next = 0; 3966 } 3967 buffer[count++] = ATOI(c); 3968 } 3969 /* At the decimal point */ 3970 else if (c == '.') 3971 { 3972 /* More than one normal difference specified, use the last one */ 3973 if (next == 1) 3974 { 3975 count = 0; 3976 next = 0; 3977 } 3978 buffer[count++] = -1; 3979 } 3980 else 3981 break; 3982 } 3983 } 3984 /* Convert the buffer of characters to a floating pt integer */ 3985 if (count != 0) 3986 norm_difference = convert_array(buffer,count); 3987 *f = file_type; 3988 *t = tie; 3989 *tr = triangulate; 3990 return norm_difference; 3991 } 3992 3993 /// AdjacentEx: 3994 int CustomStripifier::AdjacentEx(int id2,int id1, int *list, int size) 3995 { 3996 /* Return the vertex that is adjacent to id1, 3997 but is not id2, in the list of integers. 3998 */ 3999 4000 register int x=0; 4001 4002 while (x < size) 4003 { 4004 if (*(list+x) == id1) 4005 { 4006 if ((x != (size -1)) && (x != 0)) 4007 { 4008 if ( *(list+x+1) != id2) 4009 return *(list+x+1); 4010 else 4011 return *(list+x-1); 4012 } 4013 else if (x == (size -1)) 4014 { 4015 if (*(list) != id2) 4016 return *(list); 4017 else 4018 return *(list+x-1); 4019 } 4020 else 4021 { 4022 if (*(list+size-1) != id2) 4023 return *(list+size-1); 4024 else 4025 return *(list+x+1); 4026 } 4027 } 4028 x++; 4029 } 4030 printf("Error in the list\n"); 4031 exit(0); 4032 } 4033 4034 /// Delete_From_ListEx: 4035 void CustomStripifier::Delete_From_ListEx(int id,int *list, int size) 4036 { 4037 /* Delete the occurence of id in the list. 4038 (list has size size) 4039 */ 4040 4041 int *temp; 4042 register int x,y=0; 4043 4044 temp = (int *) malloc(sizeof(int) * size); 4045 for (x=0; x<size; x++) 4046 { 4047 if (*(list+x) != id) 4048 { 4049 *(temp+y) = *(list+x); 4050 y++; 4051 } 4052 } 4053 if(y != (size-1)) 4054 { 4055 printf("There is an error in the delete\n"); 4056 exit(0); 4057 } 4058 *(temp+size-1) = -1; 4059 memcpy(list,temp,sizeof(int)*size); 4060 4061 } 4062 4063 /// Triangulate_QuadEx: 4064 void CustomStripifier::Triangulate_QuadEx(int out_edge1,int out_edge2,int in_edge1, 4065 int in_edge2,int size,int *index, 4066 int reversed, 4067 int where) 4068 { 4069 int vertex4,vertex5; 4070 4071 /* This routine will nonblindly triangulate a quad, meaning 4072 that there is a definite input and a definite output 4073 edge that we must adhere to. Reversed will tell the orientation 4074 of the input edge. (Reversed is -1 is we do not have an input 4075 edge, in other words we are at the beginning of a strip.) 4076 Out_edge* is the output edge, and in_edge* is the input edge. 4077 Index are the edges of the polygon 4078 and size is the size of the polygon. Begin is whether we are 4079 at the start of a new strip. 4080 */ 4081 4082 /* If we do not have an input edge, then we can make our input 4083 edge whatever we like, therefore it will be easier to come 4084 out on the output edge. 4085 */ 4086 if (reversed == -1) 4087 { 4088 vertex4 = AdjacentEx(out_edge1,out_edge2,index,size); 4089 vertex5 = Get_Other_Vertex(vertex4,out_edge1,out_edge2,index); 4090 Output_TriEx(vertex5,vertex4,out_edge1,-1,where); 4091 Output_TriEx(vertex4,out_edge1,out_edge2,-1,where); 4092 return; 4093 } 4094 4095 /* These are the 5 cases that we can have for the output edge */ 4096 4097 /* Are they consecutive so that we form a triangle to 4098 peel off, but cannot use the whole quad? 4099 */ 4100 4101 if (in_edge2 == out_edge1) 4102 { 4103 /* Output the triangle that comes out the correct 4104 edge last. First output the triangle that comes out 4105 the wrong edge. 4106 */ 4107 vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge2,index); 4108 Output_TriEx(in_edge1,in_edge2,vertex4,-1,where); 4109 Output_TriEx(vertex4,in_edge2,out_edge2,-1,where); 4110 return; 4111 } 4112 /* The next case is where it is impossible to come out the 4113 edge that we want. So we will have to start a new strip to 4114 come out on that edge. We will output the one triangle 4115 that we can, and then start the new strip with the triangle 4116 that comes out on the edge that we want to come out on. 4117 */ 4118 else if (in_edge1 == out_edge1) 4119 { 4120 /* We want to output the first triangle (whose output 4121 edge is not the one that we want. 4122 We have to find the vertex that we need, which is 4123 the other vertex which we do not have. 4124 */ 4125 vertex4 = Get_Other_Vertex(in_edge2,in_edge1,out_edge2,index); 4126 Output_TriEx(in_edge2,in_edge1,vertex4,-1,where); 4127 Output_TriEx(vertex4,in_edge1,out_edge2,-1,where); 4128 return; 4129 } 4130 4131 /* Consecutive cases again, but with the output edge reversed */ 4132 else if (in_edge1 == out_edge2) 4133 { 4134 vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge1,index); 4135 Output_TriEx(in_edge2,in_edge1,vertex4,-1,where); 4136 Output_TriEx(vertex4,in_edge1,out_edge1,-1,where); 4137 return; 4138 } 4139 else if (in_edge2 == out_edge2) 4140 { 4141 vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge1,index); 4142 Output_TriEx(in_edge1,in_edge2,vertex4,-1,where); 4143 Output_TriEx(vertex4,in_edge2,out_edge1,-1,where); 4144 return; 4145 } 4146 4147 /* The final case is where we want to come out the opposite edge.*/ 4148 else 4149 { 4150 if( ((!reversed) && 4151 (out_edge1 == (AdjacentEx(in_edge1,in_edge2,index,size)))) || 4152 ((reversed) && 4153 (out_edge2 == (AdjacentEx(in_edge2,in_edge1,index,size))))) 4154 { 4155 /* We need to know the orientation of the input 4156 edge, so we know which way to put the diagonal. 4157 And also the output edge, so that we triangulate correctly. 4158 */ 4159 Output_TriEx(in_edge1,in_edge2,out_edge2,-1,where); 4160 Output_TriEx(in_edge2,out_edge2,out_edge1,-1,where); 4161 } 4162 else 4163 { 4164 /* Input and output orientation was reversed, so diagonal will 4165 be reversed from above. 4166 */ 4167 Output_TriEx(in_edge1,in_edge2,out_edge1,-1,where); 4168 Output_TriEx(in_edge2,out_edge1,out_edge2,-1,where); 4169 } 4170 return; 4171 } 4172 } 4173 4174 /// Triangulate_PolygonEx: 4175 void CustomStripifier::Triangulate_PolygonEx( int out_edge1,int out_edge2, 4176 int in_edge1, int in_edge2, 4177 int size, int *index, 4178 int reversed, 4179 int face_id, int where) 4180 { 4181 /* We have a polygon that we need to nonblindly triangulate. 4182 We will recursively try to triangulate it, until we are left 4183 with a polygon of size 4, which can use the quad routine 4184 from above. We will be taking off a triangle at a time 4185 and outputting it. We will have 3 cases similar to the 4186 cases for the quad above. The inputs to this routine 4187 are the same as for the quad routine. 4188 */ 4189 4190 int vertex4; 4191 int *temp; 4192 4193 4194 /* Since we are calling this recursively, we have to check whether 4195 we are down to the case of the quad. 4196 */ 4197 4198 if (size == 4) 4199 { 4200 Triangulate_QuadEx(out_edge1,out_edge2,in_edge1,in_edge2,size, 4201 index,reversed,where); 4202 return; 4203 } 4204 4205 4206 4207 /* We do not have a specified input edge, and therefore we 4208 can make it anything we like, as long as we still come out 4209 the output edge that we want. 4210 */ 4211 if (reversed == -1) 4212 { 4213 /* Get the vertex for the last triangle, which is 4214 the one coming out the output edge, before we do 4215 any deletions to the list. We will be doing this 4216 bottom up. 4217 */ 4218 vertex4 = AdjacentEx(out_edge1,out_edge2,index,size); 4219 temp = (int *) malloc(sizeof(int) * size); 4220 memcpy(temp,index,sizeof(int)*size); 4221 Delete_From_ListEx(out_edge2,index,size); 4222 Triangulate_PolygonEx(out_edge1,vertex4,in_edge2, 4223 vertex4,size-1,index, 4224 reversed,face_id,where); 4225 memcpy(index,temp,sizeof(int)*size); 4226 /* Lastly do the triangle that comes out the output 4227 edge. 4228 */ 4229 Output_TriEx(vertex4,out_edge1,out_edge2,-1,where); 4230 return; 4231 } 4232 4233 /* These are the 5 cases that we can have for the output edge */ 4234 4235 /* Are they consecutive so that we form a triangle to 4236 peel off that comes out the correct output edge, 4237 but we cannot use the whole polygon? 4238 */ 4239 if (in_edge2 == out_edge1) 4240 { 4241 /* Output the triangle that comes out the correct 4242 edge last. First recursively do the rest of the 4243 polygon. 4244 */ 4245 /* Do the rest of the polygon without the triangle. 4246 We will be doing a fan triangulation. 4247 */ 4248 /* Get the vertex adjacent to in_edge1, but is not 4249 in_edge2. 4250 */ 4251 vertex4 = AdjacentEx(in_edge2,in_edge1,index,size); 4252 Output_TriEx(in_edge1,in_edge2,vertex4,-1,where); 4253 /* Create a new edgelist without the triangle that 4254 was just outputted. 4255 */ 4256 temp = (int *) malloc(sizeof(int) * size); 4257 memcpy(temp,index,sizeof(int)*size); 4258 Delete_From_ListEx(in_edge1,index,size); 4259 Triangulate_PolygonEx(out_edge1,out_edge2,in_edge2, 4260 vertex4,size-1,index, 4261 !reversed,face_id,where); 4262 memcpy(index,temp,sizeof(int)*size); 4263 return; 4264 } 4265 4266 /* Next case is where it is again consecutive, but the triangle 4267 formed by the consecutive edges do not come out of the 4268 correct output edge. For this case, we can not do much to 4269 keep it sequential. Try and do the fan. 4270 */ 4271 else if (in_edge1 == out_edge1) 4272 { 4273 /* Get vertex adjacent to in_edge2, but is not in_edge1 */ 4274 vertex4 = AdjacentEx(in_edge1,in_edge2,index,size); 4275 Output_TriEx(in_edge1,in_edge2,vertex4,-1,where); 4276 /* Since that triangle goes out of the polygon (the 4277 output edge of it), we can make our new input edge 4278 anything we like, so we will try to make it good for 4279 the strip. (This will be like starting a new strip, 4280 all so that we can go out the correct output edge.) 4281 */ 4282 temp = (int *) malloc(sizeof(int) * size); 4283 memcpy(temp,index,sizeof(int)*size); 4284 Delete_From_ListEx(in_edge2,index,size); 4285 Triangulate_PolygonEx(out_edge1,out_edge2,in_edge1, 4286 vertex4,size-1,index, 4287 reversed,face_id,where); 4288 memcpy(index,temp,sizeof(int)*size); 4289 return; 4290 } 4291 /* Consecutive cases again, but with the output edge reversed */ 4292 else if (in_edge1 == out_edge2) 4293 { 4294 /* Get vertex adjacent to in_edge2, but is not in_edge1 */ 4295 vertex4 = AdjacentEx(in_edge1,in_edge2,index,size); 4296 Output_TriEx(in_edge2,in_edge1,vertex4,-1,where); 4297 temp = (int *) malloc(sizeof(int) * size); 4298 memcpy(temp,index,sizeof(int)*size); 4299 Delete_From_ListEx(in_edge2,index,size); 4300 Triangulate_PolygonEx(out_edge1,out_edge2,in_edge1, 4301 vertex4,size-1,index, 4302 reversed,face_id,where); 4303 memcpy(index,temp,sizeof(int)*size); 4304 return; 4305 } 4306 else if (in_edge2 == out_edge2) 4307 { 4308 /* Get vertex adjacent to in_edge2, but is not in_edge1 */ 4309 vertex4 = AdjacentEx(in_edge2,in_edge1,index,size); 4310 Output_TriEx(in_edge1,in_edge2,vertex4,-1,where); 4311 temp = (int *) malloc(sizeof(int) * size); 4312 memcpy(temp,index,sizeof(int)*size); 4313 Delete_From_ListEx(in_edge1,index,size); 4314 Triangulate_PolygonEx(out_edge1,out_edge2,vertex4, 4315 in_edge2,size-1,index, 4316 reversed,face_id,where); 4317 memcpy(index,temp,sizeof(int)*size); 4318 return; 4319 } 4320 4321 /* Else the edge is not consecutive, and it is sufficiently 4322 far away, for us not to make a conclusion at this time. 4323 So we can take off a triangle and recursively call this 4324 function. 4325 */ 4326 else 4327 { 4328 vertex4 = AdjacentEx(in_edge2,in_edge1,index,size); 4329 Output_TriEx(in_edge1,in_edge2,vertex4,-1,where); 4330 temp = (int *) malloc(sizeof(int) * size); 4331 memcpy(temp,index,sizeof(int)*size); 4332 Delete_From_ListEx(in_edge1,index,size); 4333 Triangulate_PolygonEx(out_edge1,out_edge2,in_edge2, 4334 vertex4,size-1,index, 4335 !reversed,face_id,where); 4336 memcpy(index,temp,sizeof(int)*size); 4337 return; 4338 } 4339 } 4340 4341 /// TriangulateEx: 4342 void CustomStripifier::TriangulateEx(int out_edge1,int out_edge2,int in_edge1, 4343 int in_edge2,int size,int *index, 4344 int reversed,int face_id, int where) 4345 { 4346 /* We have the info we need to triangulate a polygon */ 4347 4348 if (size == 4) 4349 Triangulate_QuadEx(out_edge1,out_edge2,in_edge1,in_edge2,size, 4350 index,reversed,where); 4351 else 4352 Triangulate_PolygonEx(out_edge1,out_edge2,in_edge1,in_edge2,size, 4353 index,reversed,face_id,where); 4354 } 4355 4356 /// Non_Blind_TriangulateEx: 4357 void CustomStripifier::Non_Blind_TriangulateEx(int size,int *index, 4358 int next_face_id,int face_id,int where) 4359 { 4360 int id1,id2,id3; 4361 int nedge1,nedge2; 4362 int reversed; 4363 /* We have a polygon that has to be triangulated and we cannot 4364 do it blindly, ie we will try to come out on the edge that 4365 has the least number of adjacencies 4366 */ 4367 4368 Last_Edge(&id1,&id2,&id3,0); 4369 /* Find the edge that is adjacent to the new face , 4370 also return whether the orientation is reversed in the 4371 face of the input edge, which is id2 and id3. 4372 */ 4373 if (next_face_id == -1) 4374 { 4375 printf("The face is -1 and the size is %d\n",size); 4376 exit(0); 4377 } 4378 4379 reversed = Get_EdgeEx(&nedge1,&nedge2,index,next_face_id,size,id2,id3); 4380 /* Do the triangulation */ 4381 4382 /* If reversed is -1, the input edge is not in the polygon, 4383 therefore we can have the input edge to be anything we like, 4384 since we are at the beginning of a strip 4385 */ 4386 TriangulateEx(nedge1,nedge2,id2,id3,size,index,reversed, 4387 face_id, where); 4388 } 4389 4390 /// Rearrange_IndexEx: 4391 void CustomStripifier::Rearrange_IndexEx(int *index, int size) 4392 { 4393 /* If we are in the middle of a strip we must find the 4394 edge to start on, which is the last edge that we had 4395 transmitted. 4396 */ 4397 int x,f,y,e1,e2,e3; 4398 int increment = 1; 4399 int *temp; 4400 4401 /* Find where the input edge is in the input list */ 4402 Last_Edge(&e1,&e2,&e3,0); 4403 for (y = 0; y < size; y++) 4404 { 4405 if (*(index+y) == e2) 4406 { 4407 if ((y != (size - 1)) && (*(index+y+1) == e3)) 4408 break; 4409 else if ((y == (size - 1)) && (*(index) == e3)) 4410 break; 4411 else if ((y != 0) && (*(index+y-1) == e3)) 4412 { 4413 increment = -1; 4414 break; 4415 } 4416 else if ((y==0) && (*(index+size-1) == e3)) 4417 { 4418 increment = -1; 4419 break; 4420 } 4421 } 4422 if (*(index+y) == e3) 4423 { 4424 if ((y != (size - 1)) && (*(index+y+1) == e2)) 4425 break; 4426 else if ((y == (size - 1)) && (*(index) == e2)) 4427 break; 4428 else if ((y != 0) && (*(index+y-1) == e2)) 4429 { 4430 increment = -1; 4431 break; 4432 } 4433 else if ((y==0) && (*(index+size-1) == e2)) 4434 { 4435 increment = -1; 4436 break; 4437 } 4438 } 4439 /* Edge is not here, we are at the beginning */ 4440 if ((y == (size-1)) && (increment != -1)) 4441 return; 4442 } 4443 4444 /* Now put the list into a new list, starting with the 4445 input edge. Increment tells us whether we have to go 4446 forward or backward. 4447 */ 4448 /* Was in good position already */ 4449 if ((y == 0) && (increment == 1)) 4450 return; 4451 4452 4453 temp = (int *) malloc(sizeof(int) * size); 4454 memcpy(temp,index,sizeof(int)*size); 4455 4456 if (increment == 1) 4457 { 4458 x=0; 4459 for (f = y ; f< size; f++) 4460 { 4461 *(index+x) = *(temp+f); 4462 x++; 4463 } 4464 /* Finish the rest of the list */ 4465 for(f = 0; f < y ; f++) 4466 { 4467 *(index+x) = *(temp+f); 4468 x++; 4469 } 4470 } 4471 else 4472 { 4473 x=0; 4474 for (f = y ; f >= 0; f--) 4475 { 4476 *(index+x) = *(temp+f); 4477 x++; 4478 } 4479 /* Finish the rest of the list */ 4480 for(f = (size - 1); f > y ; f--) 4481 { 4482 *(index+x) = *(temp+f); 4483 x++; 4484 } 4485 } 4486 } 4487 4488 /// Blind_TriangulateEx: 4489 void CustomStripifier::Blind_TriangulateEx(int size, int *index, 4490 BOOL begin, int where ) 4491 { 4492 /* save sides in temp array, we need it so we know 4493 about swaps. 4494 */ 4495 int mode, decreasing,increasing,e1,e2,e3; 4496 4497 /* Rearrange the index list so that the input edge is first 4498 */ 4499 if (!begin) 4500 Rearrange_IndexEx(index,size); 4501 4502 /* We are given a polygon of more than 3 sides 4503 and want to triangulate it. We will output the 4504 triangles to the output file. 4505 */ 4506 4507 /* Find where the input edge is in the input list */ 4508 Last_Edge(&e1,&e2,&e3,0); 4509 if (( (!begin) && (*(index) == e2) ) || (begin)) 4510 { 4511 Output_TriEx(*(index+0),*(index+1),*(index+size-1),-1,where); 4512 /* If we have a quad, (chances are yes), then we know that 4513 we can just add one diagonal and be done. (divide the 4514 quad into 2 triangles. 4515 */ 4516 if (size == 4) 4517 { 4518 Output_TriEx(*(index+1),*(index+size-1),*(index+2),-1,where); 4519 return; 4520 } 4521 increasing = 1; 4522 mode = 1; 4523 4524 } 4525 else if (!begin) 4526 { 4527 Output_TriEx(*(index+1),*(index+0),*(index+size-1),-1,where); 4528 if (size == 4) 4529 { 4530 Output_TriEx(*(index+0),*(index+size-1),*(index+2),-1,where); 4531 return; 4532 } 4533 Output_TriEx(*(index+0),*(index+size-1),*(index+2),-1,where); 4534 increasing = 2; 4535 mode = 0; 4536 } 4537 if (size != 4) 4538 { 4539 /* We do not have a quad, we have something bigger. */ 4540 decreasing = size - 1; 4541 4542 do 4543 { 4544 /* Will be alternating diagonals, so we will be increasing 4545 and decreasing around the polygon. 4546 */ 4547 if (mode) 4548 { 4549 Output_TriEx(*(index+increasing),*(index+decreasing), 4550 *(index+increasing+1),-1,where); 4551 increasing++; 4552 } 4553 else 4554 { 4555 Output_TriEx(*(index+decreasing),*(index+increasing), 4556 *(index+decreasing-1),-1,where); 4557 decreasing--; 4558 } 4559 mode = !mode; 4560 } while ((decreasing - increasing) >= 2); 4561 4562 } 4563 } 4564 4565 /// Get_EdgeEx: 4566 int CustomStripifier::Get_EdgeEx(int *edge1,int *edge2,int *index,int face_id, 4567 int size, int id1, int id2) 4568 { 4569 /* Put the edge that is adjacent to face_id into edge1 4570 and edge2. For each edge see if it is adjacent to 4571 face_id. Id1 and id2 is the input edge, so see if 4572 the orientation is reversed, and save it in reversed. 4573 */ 4574 int x; 4575 int reversed = -1; 4576 BOOL set = FALSE; 4577 4578 for (x=0; x< size; x++) 4579 { 4580 if (x == (size-1)) 4581 { 4582 if ((*(index) == id1) && (*(index+size-1)==id2)) 4583 { 4584 if (set) 4585 return 1; 4586 reversed = 1; 4587 } 4588 else if ((*(index) == id2) && (*(index+size-1)==id1)) 4589 { 4590 if (set) 4591 return 0; 4592 reversed = 0; 4593 } 4594 4595 if (Look_Up(*(index),*(index+size-1),face_id)) 4596 { 4597 if ( (out1Ex != -1) && 4598 ( (out1Ex == *(index)) || (out1Ex == *(index+size-1)) ) && 4599 ( (out2Ex == *(index)) || (out2Ex == *(index+size-1)) )) 4600 { 4601 set = TRUE; 4602 *edge1 = *(index); 4603 *edge2 = *(index+size-1); 4604 } 4605 else if (out1Ex == -1) 4606 { 4607 set = TRUE; 4608 *edge1 = *(index); 4609 *edge2 = *(index+size-1); 4610 } 4611 if ((reversed != -1) && (set)) 4612 return reversed; 4613 } 4614 } 4615 else 4616 { 4617 if ((*(index+x) == id1) && (*(index+x+1)==id2)) 4618 { 4619 if (set) 4620 return 0; 4621 reversed = 0; 4622 } 4623 else if ((*(index+x) == id2) && (*(index+x+1)==id1)) 4624 { 4625 if (set) 4626 return 1; 4627 reversed = 1; 4628 } 4629 4630 if (Look_Up(*(index+x),*(index+x+1),face_id)) 4631 { 4632 if ( (out1Ex != -1) && 4633 ( (out1Ex == *(index+x)) || (out1Ex == *(index+x+1)) ) && 4634 ((out2Ex == *(index+x)) || (out2Ex == *(index+x+1)))) 4635 { 4636 set = TRUE; 4637 *edge1 = *(index+x); 4638 *edge2 = *(index+x+1); 4639 } 4640 else if (out1Ex == -1) 4641 { 4642 set = TRUE; 4643 *edge1 = *(index+x); 4644 *edge2 = *(index+x + 1); 4645 } 4646 if ((reversed != -1) && (set)) 4647 return reversed; 4648 } 4649 } 4650 } 4651 if ((x == size) && (reversed != -1)) 4652 { 4653 /* Could not find the output edge */ 4654 printf("Error in the Lookup %d %d %d %d %d %d %d %d\n", 4655 face_id,id1,id2,reversed,*edge1,*edge2,out1Ex,out2Ex); 4656 exit(0); 4657 } 4658 return reversed; 4659 } 4660 4661 /// Update_FaceEx: 4662 void CustomStripifier::Update_FaceEx( int *next_bucket,int *min_face, 4663 int face_id, int *e1, 4664 int *e2,int temp1, 4665 int temp2,int *ties) 4666 { 4667 /* We have a face id that needs to be decremented. 4668 We have to determine where it is in the structure, 4669 so that we can decrement it. 4670 */ 4671 /* The number of adjacencies may have changed, so to locate 4672 it may be a little tricky. However we know that the number 4673 of adjacencies is less than or equal to the original number 4674 of adjacencies, 4675 */ 4676 int y,size; 4677 ListHead *pListHead; 4678 PF_FACES temp = NULL; 4679 PLISTINFO lpListInfo; 4680 static int each_poly = 0; 4681 BOOL there = FALSE; 4682 4683 pListHead = PolFaces[face_id]; 4684 temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 ); 4685 /* Check each edge of the face and tally the number of adjacent 4686 polygons to this face. 4687 */ 4688 if ( temp != NULL ) 4689 { 4690 /* Size of the polygon */ 4691 size = temp->nPolSize; 4692 for (y = 0; y< size; y++) 4693 { 4694 /* If we are doing partial triangulation, we must check 4695 to see whether the edge is still there in the polygon, 4696 since we might have done a portion of the polygon 4697 and saved the rest for later. 4698 */ 4699 if (y != (size-1)) 4700 { 4701 if( ((temp1 == *(temp->pPolygon+y)) && 4702 (temp2 ==*(temp->pPolygon+y+1))) || 4703 ((temp2 == *(temp->pPolygon+y)) && 4704 (temp1 ==*(temp->pPolygon+y+1)))) 4705 /* edge is still there we are ok */ 4706 there = TRUE; 4707 } 4708 else 4709 { 4710 if( ((temp1 == *(temp->pPolygon)) && 4711 (temp2 == *(temp->pPolygon+size-1))) || 4712 ((temp2 == *(temp->pPolygon)) && 4713 (temp1 ==*(temp->pPolygon+size-1)))) 4714 /* edge is still there we are ok */ 4715 there = TRUE; 4716 } 4717 } 4718 4719 if (!there) 4720 /* Original edge was already used, we cannot use this polygon */ 4721 return; 4722 4723 /* We have a starting point to start our search to locate 4724 this polygon. 4725 */ 4726 4727 /* Check to see if this polygon was done */ 4728 lpListInfo = Done(face_id,&y); 4729 4730 if (lpListInfo == NULL) 4731 return; 4732 4733 /* Was not done, but there is an error in the adjacency calculations */ 4734 /* If more than one edge is adj to it then maybe it was not updated */ 4735 if (y == 0) 4736 return; 4737 4738 /* Now put the face in the proper bucket depending on tally. */ 4739 /* First add it to the new bucket, then remove it from the old */ 4740 Add_Sgi_Adj(y-1,face_id); 4741 RemoveList(array[y],lpListInfo); 4742 4743 /* Save it if it was the smallest seen so far since then 4744 it will be the next face 4745 Here we will have different options depending on 4746 what we want for resolving ties: 4747 1) First one we see we will use 4748 2) Random resolving 4749 3) Look ahead 4750 4) Alternating direction 4751 */ 4752 /* At a new strip */ 4753 if (*next_bucket == 60) 4754 *ties = *ties + each_poly; 4755 /* Have a tie */ 4756 if (*next_bucket == (y-1)) 4757 { 4758 Add_Ties(face_id); 4759 each_poly++; 4760 } 4761 /* At a new minimum */ 4762 if (*next_bucket > (y-1)) 4763 { 4764 *next_bucket = y-1; 4765 *min_face = face_id; 4766 *e1 = temp1; 4767 *e2 = temp2; 4768 each_poly = 0; 4769 Clear_Ties(); 4770 Add_Ties(face_id); 4771 } 4772 } 4773 } 4774 4775 /// Delete_AdjEx: 4776 void CustomStripifier::Delete_AdjEx(int id1, int id2, 4777 int *next_bucket, int *min_face, 4778 int current_face, int *e1, 4779 int *e2, int *ties) 4780 { 4781 /* Find the face that is adjacent to the edge and is not the 4782 current face. Delete one adjacency from it. Save the min 4783 adjacency seen so far. 4784 */ 4785 register int count=0; 4786 PF_EDGES temp = NULL; 4787 ListHead *pListHead; 4788 int next_face; 4789 4790 /* Always want smaller id first */ 4791 switch_lower(&id1,&id2); 4792 4793 pListHead = PolEdges[id1]; 4794 temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count); 4795 if (temp == NULL) 4796 /* It could be a new edge that we created. So we can 4797 exit, since there is not a face adjacent to it. 4798 */ 4799 return; 4800 while (temp->edge[0] != id2) 4801 { 4802 count++; 4803 temp = ( PF_EDGES )GetNextNode(temp); 4804 4805 if (temp == NULL) 4806 /* Was a new edge that was created and therefore 4807 does not have anything adjacent to it 4808 */ 4809 return; 4810 } 4811 /* Was not adjacent to anything else except itself */ 4812 if (temp->edge[2] == -1) 4813 return; 4814 4815 /* Was adjacent to something */ 4816 else 4817 { 4818 if (temp->edge[2] == current_face) 4819 next_face = temp->edge[1]; 4820 else 4821 next_face = temp->edge[2]; 4822 } 4823 /* We have the other face adjacent to this edge, it is 4824 next_face. Now we need to decrement this faces' adjacencies. 4825 */ 4826 Update_FaceEx(next_bucket, min_face, next_face,e1,e2,id1,id2,ties); 4827 } 4828 4829 /// Change_FaceEx: 4830 int CustomStripifier::Change_FaceEx(int face_id,int in1,int in2, 4831 ListHead *pListHead, BOOL no_check) 4832 { 4833 /* We are doing a partial triangulation and we need to 4834 put the new face of triangle into the correct bucket 4835 */ 4836 int input_adj,y; 4837 P_ADJACENCIES lpListInfo; 4838 4839 /* Find the old number of adjacencies to this face, 4840 so we know where to delete it from 4841 */ 4842 y = Old_Adj(face_id); 4843 pListHead = array[y]; 4844 lpListInfo = face_array[face_id].pfNode; 4845 4846 if (lpListInfo == NULL) 4847 { 4848 printf("There is an error finding the next polygon3 %d\n",face_id); 4849 exit(0); 4850 } 4851 4852 /* Do we need to change the adjacency? Maybe the edge on the triangle 4853 that was outputted was not adjacent to anything. We know if we 4854 have to check by "check". We came out on the output edge 4855 that we needed, then we know that the adjacencies will decrease 4856 by exactly one. 4857 */ 4858 if (!no_check) 4859 { 4860 input_adj = Number_Adj(in1,in2,face_id); 4861 /* If there weren't any then don't do anything */ 4862 if (input_adj == 0) 4863 return y; 4864 } 4865 4866 if (face_array[lpListInfo->face_id].head == pListHead) 4867 face_array[lpListInfo->face_id].pfNode = NULL; 4868 RemoveList(pListHead,(PLISTINFO)/*(temp*/lpListInfo); 4869 /* Before we had a quad with y adjacencies. The in edge 4870 did not have an adjacency, since it was just deleted, 4871 since we came in on it. The outedge must have an adjacency 4872 otherwise we would have a bucket 0, and would not be in this 4873 routine. Therefore the new adjacency must be y-1 4874 */ 4875 4876 Add_Sgi_Adj(y-1,face_id); 4877 return (y-1); 4878 } 4879 4880 /// Update_AdjacenciesEx: 4881 int CustomStripifier::Update_AdjacenciesEx(int face_id, int *next_bucket, int *e1, int *e2, 4882 int *ties) 4883 { 4884 /* Give the face with id face_id, we want to decrement 4885 all the faces that are adjacent to it, since we will 4886 be deleting face_id from the data structure. 4887 We will return the face that has the least number 4888 of adjacencies. 4889 */ 4890 PF_FACES temp = NULL; 4891 ListHead *pListHead; 4892 int size,y,min_face = -1; 4893 4894 *next_bucket = 60; 4895 pListHead = PolFaces[face_id]; 4896 temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 ); 4897 4898 if ( temp == NULL ) 4899 { 4900 printf("The face was already deleted, there is an error\n"); 4901 exit(0); 4902 } 4903 4904 /* Size of the polygon */ 4905 size = temp->nPolSize; 4906 for (y = 0; y< size; y++) 4907 { 4908 if (y != (size-1)) 4909 Delete_AdjEx(*(temp->pPolygon+y),*(temp->pPolygon+y+1), 4910 next_bucket,&min_face,face_id,e1,e2,ties); 4911 else 4912 Delete_AdjEx(*(temp->pPolygon),*(temp->pPolygon+(size-1)), 4913 next_bucket,&min_face,face_id,e1,e2,ties); 4914 } 4915 return (min_face); 4916 } 4917 4918 /// Find_Adj_TallyEx: 4919 void CustomStripifier::Find_Adj_TallyEx(int id1, int id2, 4920 int *next_bucket, int *min_face, 4921 int current_face, int *ties) 4922 { 4923 /* Find the face that is adjacent to the edge and is not the 4924 current face. Save the min adjacency seen so far. 4925 */ 4926 int size,each_poly=0,y,count=0; 4927 PF_EDGES temp = NULL; 4928 PF_FACES temp2 = NULL; 4929 ListHead *pListHead; 4930 int next_face; 4931 BOOL there = FALSE; 4932 4933 4934 /* Always want smaller id first */ 4935 switch_lower(&id1,&id2); 4936 4937 pListHead = PolEdges[id1]; 4938 temp = (PF_EDGES) PeekList(pListHead,LISTHEAD,count); 4939 if (temp == NULL) 4940 /* This was a new edge that was created, so it is 4941 adjacent to nothing. 4942 */ 4943 return; 4944 while (temp->edge[0] != id2) 4945 { 4946 count++; 4947 temp =( PF_EDGES ) GetNextNode(temp); 4948 4949 if (temp == NULL) 4950 /* This was a new edge that we created */ 4951 return; 4952 } 4953 /* Was not adjacent to anything else except itself */ 4954 if (temp->edge[2] == -1) 4955 return; 4956 else 4957 { 4958 if (temp->edge[2] == current_face) 4959 next_face = temp->edge[1]; 4960 else 4961 next_face = temp->edge[2]; 4962 } 4963 /* We have the other face adjacent to this edge, it is 4964 next_face. Find how many faces it is adjacent to. 4965 */ 4966 pListHead = PolFaces[next_face]; 4967 temp2 = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 ); 4968 /* Check each edge of the face and tally the number of adjacent 4969 polygons to this face. This will be the original number of 4970 polygons adjacent to this polygon, we must then see if this 4971 number has been decremented 4972 */ 4973 if ( temp2 != NULL ) 4974 { 4975 /* Size of the polygon */ 4976 size = temp2->nPolSize; 4977 for (y = 0; y< size; y++) 4978 { 4979 /* Make sure that the edge is still in the 4980 polygon and was not deleted, because if the edge was 4981 deleted, then we used it already. 4982 */ 4983 if (y != (size-1)) 4984 { 4985 if( ((id1 == *(temp2->pPolygon+y)) && 4986 (id2 ==*(temp2->pPolygon+y+1))) || 4987 ((id2 == *(temp2->pPolygon+y)) && 4988 (id1 ==*(temp2->pPolygon+y+1)))) 4989 /* edge is still there we are ok */ 4990 there = TRUE; 4991 } 4992 else 4993 { 4994 if( ((id1 == *(temp2->pPolygon)) && 4995 (id2 ==*(temp2->pPolygon+size-1))) || 4996 ((id2 == *(temp2->pPolygon)) && 4997 (id1 ==*(temp2->pPolygon+size-1)))) 4998 /* edge is still there we are ok */ 4999 there = TRUE; 5000 } 5001 } 5002 5003 if (!there) 5004 /* Edge already used and deleted from the polygon*/ 5005 return; 5006 5007 /* See if the face was already deleted, and where 5008 it is if it was not 5009 */ 5010 if (Done(next_face,&y) == NULL) 5011 return; 5012 5013 /* Save it if it was the smallest seen so far since then 5014 it will be the next face 5015 Here we will have different options depending on 5016 what we want for resolving ties: 5017 1) First one we see we will use 5018 2) Random resolving 5019 3) Look ahead 5020 4) Alternating direction 5021 */ 5022 5023 /* At a new strip */ 5024 if (*next_bucket == 60) 5025 *ties = *ties + each_poly; 5026 /* Have a tie */ 5027 if (*next_bucket == (y-1)) 5028 { 5029 Add_Ties(next_face); 5030 each_poly++; 5031 } 5032 /* At a new minimum */ 5033 if (*next_bucket > (y-1)) 5034 { 5035 *next_bucket = y-1; 5036 *min_face = next_face; 5037 each_poly = 0; 5038 Clear_Ties(); 5039 Add_Ties(next_face); 5040 } 5041 } 5042 } 5043 5044 /// Min_Face_AdjEx: 5045 int CustomStripifier::Min_Face_AdjEx(int face_id, int *next_bucket, int *ties) 5046 { 5047 /* Used for the Partial triangulation to find the next 5048 face. It will return the minimum adjacency face id 5049 found at this face. 5050 */ 5051 PF_FACES temp = NULL; 5052 ListHead *pListHead; 5053 int size,y,min_face,test_face; 5054 5055 *next_bucket = 60; 5056 pListHead = PolFaces[face_id]; 5057 temp = ( PF_FACES ) PeekList( pListHead, LISTHEAD, 0 ); 5058 5059 if ( temp == NULL ) 5060 { 5061 printf("The face was already deleted, there is an error\n"); 5062 exit(0); 5063 } 5064 5065 /* Size of the polygon */ 5066 size = temp->nPolSize; 5067 for (y = 0; y< size; y++) 5068 { 5069 if (y != (size-1)) 5070 Find_Adj_TallyEx(*(temp->pPolygon+y),*(temp->pPolygon+y+1), 5071 next_bucket,&min_face,face_id,ties); 5072 else 5073 Find_Adj_TallyEx(*(temp->pPolygon),*(temp->pPolygon+(size-1)), 5074 next_bucket,&min_face,face_id,ties); 5075 } 5076 /* Maybe we can do better by triangulating the face, because 5077 by triangulating the face we will go to a polygon of lesser 5078 adjacencies 5079 */ 5080 if (size == 4) 5081 { 5082 /* Checking for a quad whether to do the whole polygon will 5083 result in better performance because the triangles in the polygon 5084 have less adjacencies 5085 */ 5086 Check_In_Quad(face_id,&test_face); 5087 if (*next_bucket > test_face) 5088 /* We can do better by going through the polygon */ 5089 min_face = face_id; 5090 } 5091 5092 /* We have a polygon with greater than 4 sides, check to see if going 5093 inside is better than going outside the polygon for the output edge. 5094 */ 5095 else 5096 { 5097 Check_In_Polygon(face_id,&test_face,size); 5098 if (*next_bucket > test_face) 5099 /* We can do better by going through the polygon */ 5100 min_face = face_id; 5101 } 5102 5103 return (min_face); 5104 } 5105 5106 /// Find_StripsEx: 5107 void CustomStripifier::Find_StripsEx(int *ties, 5108 int tie, int triangulate, 5109 int swaps,int *next_id) 5110 { 5111 /* This routine will peel off the strips from the model */ 5112 5113 ListHead *pListHead; 5114 P_ADJACENCIES temp = NULL; 5115 register int max,bucket = 0; 5116 BOOL whole_flag = TRUE; 1141 /// Stripification: 1142 void CustomStripifier::Stripification() 1143 { 1144 int max,NumAdj = 0; 1145 int whole_flag = true; 5117 1146 int dummy = 0; 5118 1147 int cont = 0; 5119 5120 /* Set the last known input edge to be null */ 5121 Last_Edge(&dummy,&dummy,&dummy,1); 5122 5123 /* Search for lowest adjacency polygon and output strips */ 1148 int face,ties=0; 1149 1150 lastTri[0]=0; 1151 lastTri[1]=0; 1152 lastTri[2]=0; 1153 5124 1154 while (whole_flag) 5125 { 5126 bucket = -1; 5127 /* Search for polygons in increasing number of adjacencies */ 5128 while (bucket < 59) 1155 { 1156 NumAdj = -1; 1157 1158 while (NumAdj < 59) 1159 { 1160 NumAdj++; 1161 1162 max = StripArray[NumAdj].size(); 1163 1164 if (max > 0) 5129 1165 { 5130 bucket++; 5131 pListHead = array[bucket]; 5132 max = NumOnList(pListHead); 5133 if (max > 0) 5134 { 5135 temp = (P_ADJACENCIES) PeekList(pListHead,LISTHEAD,0); 5136 if (temp == NULL) 5137 { 5138 printf("Error in the buckets%d %d %d\n",bucket,max,0); 5139 exit(0); 5140 } 5141 5142 Polygon_OutputEx(temp,temp->face_id,bucket,pListHead,ties,tie,triangulate,swaps,next_id,1); 5143 /* Try to extend backwards, if the starting polygon in the 5144 strip had 2 or more adjacencies to begin with 5145 */ 5146 if (bucket >= 2) 5147 Extend_BackwardsEx(temp->face_id,ties,tie, triangulate,swaps,next_id); 5148 5149 break; 5150 } 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; 5151 1174 } 5152 /* Went through the whole structure, it is empty and we are done. 5153 */ 5154 if ((bucket == 59) && (max == 0)) 5155 whole_flag = FALSE; 5156 5157 /* We just finished a strip, send dummy data to signal the end 5158 of the strip so that we can output it. 5159 */ 1175 } 1176 1177 1178 if ((NumAdj == 59) && (max == 0)) 1179 { 1180 whole_flag = false; 1181 } 5160 1182 else 5161 { 5162 Output_TriEx(-1,-2,-3,-10,1); 5163 Last_Edge(&dummy,&dummy,&dummy,1); 1183 { 1184 AddTri(-1,-2,-3,-10,1); 1185 lastTri[0]=0; 1186 lastTri[1]=0; 1187 lastTri[2]=0; 5164 1188 cont++; 5165 } 5166 } 5167 printf("We got %d strips\n",cont); 5168 } 5169 5170 /// SGI_Strip: 5171 void CustomStripifier::SGI_Strip(int num_faces, int ties, int triangulate) 5172 { 5173 int next_id = -1,t=0; 5174 5175 /* We are going to output and find triangle strips 5176 according the the method that SGI uses, ie always 5177 choosing as the next triangle in our strip the triangle 5178 that has the least number of adjacencies. We do not have 5179 all triangles and will be triangulating on the fly those 5180 polygons that have more than 3 sides. 5181 */ 5182 5183 /* Build a table that has all the polygons sorted by the number 5184 of polygons adjacent to it. 5185 */ 5186 /* Initialize it */ 5187 Init_Table_SGI(num_faces); 5188 /* Build it */ 5189 Build_SGI_Table(num_faces); 5190 5191 /* We will have a structure to hold all the strips, until 5192 outputted. 5193 */ 5194 InitStripTable(); 5195 /* Now we have the structure built to find the polygons according 5196 to the number of adjacencies. Now use the SGI Method to find 5197 strips according to the adjacencies 5198 */ 5199 5200 Find_StripsEx(&t,ties,triangulate,ON,&next_id); 5201 5202 } 5203 5204 /// P_Triangulate_Quad: 5205 void CustomStripifier::P_Triangulate_Quad(int out_edge1,int out_edge2, 5206 int in_edge1, int in_edge2, 5207 int size, int *index, 5208 int reversed, int face_id, 5209 ListHead *pListHead, 5210 P_ADJACENCIES temp, 5211 int where) 5212 { 5213 int vertex4,vertex5,dummy=60; 5214 5215 /* This routine will nonblindly triangulate a quad, meaning 5216 that there is a definite input and a definite output 5217 edge that we must adhere to. Reversed will tell the orientation 5218 of the input edge. (Reversed is -1 is we do not have an input 5219 edge, in other words we are at the beginning of a strip.) 5220 Out_edge* is the output edge, and in_edge* is the input edge. 5221 Index are the edges of the polygon 5222 and size is the size of the polygon. Begin is whether we are 5223 at the start of a new strip. 5224 Note that we will not necessarily triangulate the whole quad; 5225 maybe we will do half and leave the other half (a triangle) 5226 for later. 5227 */ 5228 5229 5230 /* If we do not have an input edge, then we can make our input 5231 edge whatever we like, therefore it will be easier to come 5232 out on the output edge. In this case the whole quad is done. 5233 */ 5234 if (reversed == -1) 5235 { 5236 vertex4 = AdjacentEx(out_edge1,out_edge2,index,size); 5237 vertex5 = Get_Other_Vertex(vertex4,out_edge1,out_edge2,index); 5238 Output_TriEx(vertex5,vertex4,out_edge1,-1,where); 5239 Output_TriEx(vertex4,out_edge1,out_edge2,-1,where); 5240 dummy = Update_AdjacenciesEx(face_id, &dummy, &dummy,&dummy,&dummy); 5241 5242 if (face_array[temp->face_id].head == pListHead) 5243 face_array[temp->face_id].pfNode = NULL; 5244 RemoveList(pListHead,(PLISTINFO) temp); 5245 return; 5246 } 5247 5248 /* These are the 5 cases that we can have for the output edge */ 5249 5250 /* Are they consecutive so that we form a triangle to 5251 peel off, but cannot use the whole quad? 5252 */ 5253 5254 if (in_edge2 == out_edge1) 5255 { 5256 /* Output the triangle that comes out the correct 5257 edge. Save the other half for later. 5258 */ 5259 vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge2,index); 5260 Output_TriEx(in_edge1,in_edge2,out_edge2,-1,where); 5261 /* Now we have a triangle used, and a triangle that is 5262 left for later. 5263 */ 5264 5265 /* Now delete the adjacencies by one for all the faces 5266 that are adjacent to the triangle that we just outputted. 5267 */ 5268 Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy, 5269 face_id,&dummy,&dummy,&dummy); 5270 Delete_AdjEx(out_edge2,in_edge2,&dummy,&dummy, 5271 face_id,&dummy,&dummy,&dummy); 5272 /* Put the new face in the proper bucket of adjacencies 5273 There are 2 edges that need to be checked for the triangle 5274 that was just outputted. For the output edge we definitely 5275 will be decreasing the adjacency, but we must check for the 5276 input edge. 5277 */ 5278 5279 dummy = Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE); 5280 dummy = Change_FaceEx(face_id,in_edge2,out_edge2,pListHead,TRUE); 5281 5282 /* Update the face data structure, by deleting the old 5283 face and putting in the triangle as the new face 5284 */ 5285 New_Face(face_id,in_edge1,out_edge2,vertex4); 5286 return; 5287 } 5288 else if (in_edge1 == out_edge1) 5289 { 5290 /* We want to output the first triangle (whose output 5291 edge is not the one that we want. 5292 We have to find the vertex that we need, which is 5293 the other vertex which we do not have. 5294 */ 5295 vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge2,index); 5296 Output_TriEx(in_edge2,in_edge1,out_edge2,-1,where); 5297 /* Now we have a triangle used, and a triangle that is 5298 left for later. 5299 */ 5300 5301 /* Now delete the adjacencies by one for all the faces 5302 that are adjacent to the triangle that we just outputted. 5303 */ 5304 Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id, 5305 &dummy,&dummy,&dummy); 5306 Delete_AdjEx(out_edge2,out_edge1,&dummy,&dummy, 5307 face_id,&dummy,&dummy,&dummy); 5308 5309 /* Put the new face in the proper bucket of adjacencies */ 5310 dummy = Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE); 5311 dummy = Change_FaceEx(face_id,in_edge1,out_edge2,pListHead,TRUE); 5312 5313 /* Update the face data structure, by deleting the old 5314 face and putting in the triangle as the new face 5315 */ 5316 New_Face(face_id,in_edge2,out_edge2,vertex4); 5317 return; 5318 } 5319 5320 /* Consecutive cases again, but with the output edge reversed */ 5321 else if (in_edge1 == out_edge2) 5322 { 5323 vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge1,index); 5324 Output_TriEx(in_edge2,in_edge1,out_edge1,-1,where); 5325 /* Now we have a triangle used, and a triangle that is 5326 left for later. 5327 */ 5328 5329 /* Now delete the adjacencies by one for all the faces 5330 that are adjacent to the triangle that we just outputted. 5331 */ 5332 Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id, 5333 &dummy,&dummy,&dummy); 5334 Delete_AdjEx(out_edge2,out_edge1,&dummy,&dummy, 5335 face_id,&dummy,&dummy,&dummy); 5336 5337 /* Put the new face in the proper bucket of adjacencies */ 5338 dummy = Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE); 5339 dummy = Change_FaceEx(face_id,out_edge1,out_edge2,pListHead,TRUE); 5340 5341 /* Update the face data structure, by deleting the old 5342 face and putting in the triangle as the new face 5343 */ 5344 New_Face(face_id,in_edge2,out_edge1,vertex4); 5345 return; 5346 } 5347 else if (in_edge2 == out_edge2) 5348 { 5349 vertex4 = Get_Other_Vertex(in_edge1,in_edge2,out_edge1,index); 5350 Output_TriEx(in_edge1,in_edge2,out_edge1,-1,where); 5351 /* Now we have a triangle used, and a triangle that is 5352 left for later. 5353 */ 5354 /* Now delete the adjacencies by one for all the faces 5355 that are adjacent to the triangle that we just outputted. 5356 */ 5357 Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id, 5358 &dummy,&dummy,&dummy); 5359 Delete_AdjEx(out_edge2,out_edge1,&dummy,&dummy, 5360 face_id,&dummy,&dummy,&dummy); 5361 5362 /* Put the new face in the proper bucket of adjacencies */ 5363 dummy = Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE); 5364 dummy = Change_FaceEx(face_id,out_edge1,out_edge2,pListHead,TRUE); 5365 5366 /* Update the face data structure, by deleting the old 5367 face and putting in the triangle as the new face 5368 */ 5369 New_Face(face_id,in_edge1,out_edge1,vertex4); 5370 return; 5371 } 5372 5373 /* The final case is where we want to come out the opposite 5374 edge. 5375 */ 5376 else 5377 { 5378 if( ((!reversed) && 5379 (out_edge1 == (AdjacentEx(in_edge1,in_edge2,index,size)))) || 5380 ((reversed) && 5381 (out_edge2 == (AdjacentEx(in_edge2,in_edge1,index,size))))) 5382 { 5383 /* We need to know the orientation of the input 5384 edge, so we know which way to put the diagonal. 5385 And also the output edge, so that we triangulate 5386 correctly. Does not need partial. 5387 */ 5388 Output_TriEx(in_edge1,in_edge2,out_edge2,-1,where); 5389 Output_TriEx(in_edge2,out_edge2,out_edge1,-1,where); 5390 dummy = Update_AdjacenciesEx(face_id, &dummy, &dummy,&dummy,&dummy); 1189 } 1190 } 1191 } 1192 1193 1194 /// Finished: 1195 int 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); 5391 1209 5392 if (face_array[temp->face_id].head == pListHead) 5393 face_array[temp->face_id].pfNode = NULL; 5394 RemoveList(pListHead,(PLISTINFO) temp); 5395 } 5396 else 5397 { 5398 /* Input and output orientation was reversed, so diagonal will 5399 be reversed from above. 5400 */ 5401 Output_TriEx(in_edge1,in_edge2,out_edge1,-1,where); 5402 Output_TriEx(in_edge2,out_edge1,out_edge2,-1,where); 5403 dummy = Update_AdjacenciesEx(face_id, &dummy, &dummy,&dummy,&dummy); 5404 5405 if (face_array[temp->face_id].head == pListHead) 5406 face_array[temp->face_id].pfNode = NULL; 5407 RemoveList(pListHead,(PLISTINFO) temp); 5408 } 5409 return; 5410 } 5411 } 5412 5413 /// P_Triangulate_Polygon: 5414 void CustomStripifier::P_Triangulate_Polygon( int out_edge1,int out_edge2, 5415 int in_edge1, int in_edge2, 5416 int size, int *index, 5417 int reversed, 5418 int face_id, int *next_id, 5419 ListHead *pListHead, 5420 P_ADJACENCIES temp2, 5421 int where) 5422 { 5423 /* We have a polygon greater than 4 sides, which we wish 5424 to partially triangulate 5425 */ 5426 int next_bucket,vertex4,dummy = 60; 5427 int *temp; 5428 5429 5430 /* Since we are calling this recursively, we have to check whether 5431 we are down to the case of the quad. 5432 */ 5433 if (size == 4) 5434 { 5435 P_Triangulate_Quad(out_edge1,out_edge2,in_edge1,in_edge2,size, 5436 index,reversed,face_id, 5437 pListHead,temp2,where); 5438 return; 5439 } 5440 5441 /* We do not have a specified input edge, and therefore we 5442 can make it anything we like, as long as we still come out 5443 the output edge that we want. 5444 */ 5445 if (reversed == -1) 5446 { 5447 /* Get the vertex for the last triangle, which is 5448 the one coming out the output edge, before we do 5449 any deletions to the list. We will be doing this 5450 bottom up. 5451 */ 5452 vertex4 = AdjacentEx(out_edge1,out_edge2,index,size); 5453 temp = (int *) malloc(sizeof(int) * size); 5454 memcpy(temp,index,sizeof(int)*size); 5455 Delete_From_ListEx(out_edge2,index,size); 5456 /* We do not have to partially triangulate, since 5457 we will do the whole thing, so use the whole routine 5458 */ 5459 Triangulate_PolygonEx(vertex4,out_edge1,in_edge2, 5460 vertex4,size-1,index, 5461 reversed,face_id, 5462 where); 5463 memcpy(index,temp,sizeof(int)*size); 5464 /* Lastly do the triangle that comes out the output 5465 edge. 5466 */ 5467 Output_TriEx(vertex4,out_edge1,out_edge2,-1,where); 5468 /* We were able to do the whole polygon, now we 5469 can delete the whole thing from our data structure. 5470 */ 5471 dummy = Update_AdjacenciesEx(face_id, &dummy, &dummy,&dummy,&dummy); 5472 5473 if (face_array[temp2->face_id].head == pListHead) 5474 face_array[temp2->face_id].pfNode = NULL; 5475 RemoveList(pListHead,(PLISTINFO) temp2); 5476 return; 5477 } 5478 5479 /* These are the 5 cases that we can have for the output edge */ 5480 5481 /* Are they consecutive so that we form a triangle to 5482 peel off that comes out the correct output edge, 5483 but we cannot use the whole polygon? 5484 */ 5485 if (in_edge2 == out_edge1) 5486 { 5487 Output_TriEx(in_edge1,out_edge1,out_edge2,-1,where); 5488 5489 /* Now delete the adjacencies by one for all the faces 5490 that are adjacent to the triangle that we just outputted. 5491 */ 5492 Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id, 5493 &dummy,&dummy,&dummy); 5494 Delete_AdjEx(out_edge2,out_edge1,&dummy,&dummy, 5495 face_id,&dummy,&dummy,&dummy); 5496 5497 /* Put the new face in the proper bucket of adjacencies */ 5498 next_bucket=Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE); 5499 next_bucket=Change_FaceEx(face_id,out_edge1,out_edge2,pListHead,TRUE); 5500 5501 /* Create a new edgelist without the triangle that 5502 was just outputted. 5503 */ 5504 Delete_From_ListEx(in_edge2,index,size); 5505 /* Update the face data structure, by deleting the old 5506 face and putting in the polygon minus the triangle 5507 as the new face, here we will be decrementing the size 5508 by one. 5509 */ 5510 New_Size_Face(face_id); 5511 return; 5512 } 5513 5514 /* Next case is where it is again consecutive, but the triangle 5515 formed by the consecutive edges do not come out of the 5516 correct output edge. (the input edge will be reversed in 5517 the next triangle) 5518 */ 5519 else if (in_edge1 == out_edge1) 5520 { 5521 /* Get vertex adjacent to in_edge2, but is not in_edge1 */ 5522 Output_TriEx(in_edge2,in_edge1,out_edge2,-1,where); 5523 5524 /* Now delete the adjacencies by one for all the faces 5525 that are adjacent to the triangle that we just outputted. 5526 */ 5527 Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id, 5528 &dummy,&dummy,&dummy); 5529 Delete_AdjEx(out_edge2,out_edge1,&dummy,&dummy, 5530 face_id,&dummy,&dummy,&dummy); 5531 5532 /* Put the new face in the proper bucket of adjacencies */ 5533 next_bucket=Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE); 5534 next_bucket=Change_FaceEx(face_id,out_edge1,out_edge2,pListHead,TRUE); 5535 5536 /* Create a new edgelist without the triangle that 5537 was just outputted. 5538 */ 5539 Delete_From_ListEx(in_edge1,index,size); 5540 /* Update the face data structure, by deleting the old 5541 face and putting in the polygon minus the triangle 5542 as the new face, here we will be decrementing the size 5543 by one. 5544 */ 5545 New_Size_Face(face_id); 5546 return; 5547 } 5548 5549 /* Consecutive cases again, but with the output edge reversed */ 5550 else if (in_edge1 == out_edge2) 5551 { 5552 Output_TriEx(in_edge2,in_edge1,out_edge1,-1,where); 5553 5554 /* Now delete the adjacencies by one for all the faces 5555 that are adjacent to the triangle that we just outputted. 5556 */ 5557 Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id, 5558 &dummy,&dummy,&dummy); 5559 Delete_AdjEx(out_edge1,out_edge2,&dummy,&dummy, 5560 face_id,&dummy,&dummy,&dummy); 5561 5562 /* Put the new face in the proper bucket of adjacencies */ 5563 next_bucket=Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE); 5564 next_bucket=Change_FaceEx(face_id,out_edge1,out_edge2,pListHead,TRUE); 5565 5566 /* Create a new edgelist without the triangle that 5567 was just outputted. 5568 */ 5569 Delete_From_ListEx(in_edge1,index,size); 5570 /* Update the face data structure, by deleting the old 5571 face and putting in the polygon minus the triangle 5572 as the new face, here we will be decrementing the size 5573 by one. 5574 */ 5575 New_Size_Face(face_id); 5576 return; 5577 } 5578 else if (in_edge2 == out_edge2) 5579 { 5580 Output_TriEx(in_edge1,in_edge2,out_edge1,-1,where); 5581 5582 /* Now delete the adjacencies by one for all the faces 5583 that are adjacent to the triangle that we just outputted. 5584 */ 5585 Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id, 5586 &dummy,&dummy,&dummy); 5587 Delete_AdjEx(out_edge2,out_edge1,&dummy,&dummy, 5588 face_id,&dummy,&dummy,&dummy); 5589 5590 /* Put the new face in the proper bucket of adjacencies */ 5591 next_bucket=Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE); 5592 next_bucket=Change_FaceEx(face_id,out_edge1,out_edge2,pListHead,TRUE); 5593 5594 /* Create a new edgelist without the triangle that 5595 was just outputted. 5596 */ 5597 Delete_From_ListEx(in_edge2,index,size); 5598 /* Update the face data structure, by deleting the old 5599 face and putting in the polygon minus the triangle 5600 as the new face, here we will be decrementing the size 5601 by one. 5602 */ 5603 New_Size_Face(face_id); 5604 return; 5605 } 5606 5607 /* Else the edge is not consecutive, and it is sufficiently 5608 far away, for us not to make a conclusion at this time. 5609 So we can take off a triangle and recursively call this 5610 function. 5611 */ 5612 else 5613 { 5614 if (!reversed) 5615 { 5616 vertex4 = AdjacentEx(in_edge2,in_edge1,index,size); 5617 Output_TriEx(in_edge1,in_edge2,vertex4,-1,where); 5618 5619 /* Now delete the adjacencies by one for all the faces 5620 that are adjacent to the triangle that we just outputted. 5621 */ 5622 Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id, 5623 &dummy,&dummy,&dummy); 5624 Delete_AdjEx(in_edge1,vertex4,&dummy,&dummy, 5625 face_id,&dummy,&dummy,&dummy); 5626 5627 /* Put the new face in the proper bucket of adjacencies */ 5628 next_bucket = Change_FaceEx(face_id,in_edge1,in_edge2, 5629 pListHead,FALSE); 5630 next_bucket = Change_FaceEx(face_id,in_edge1,vertex4, 5631 pListHead,FALSE); 5632 5633 /* Create a new edgelist without the triangle that 5634 was just outputted. 5635 */ 5636 Delete_From_ListEx(in_edge1,index,size); 5637 /* Update the face data structure, by deleting the old 5638 face and putting in the polygon minus the triangle 5639 as the new face, here we will be decrementing the size 5640 by one. 5641 */ 5642 New_Size_Face(face_id); 5643 5644 /* Save the info for the new bucket, we will need it on 5645 the next pass for the variables, pListHead and temp 5646 */ 5647 pListHead = array[next_bucket]; 5648 temp2 = face_array[face_id].pfNode; 5649 if (temp2 == NULL) 5650 { 5651 printf("There is an error finding the next polygon10\n", 5652 next_bucket,face_id); 5653 exit(0); 5654 } 5655 5656 P_Triangulate_Polygon(out_edge1,out_edge2,in_edge2, 5657 vertex4,size-1,index,!reversed, 5658 face_id,next_id,pListHead,temp2,where); 5659 } 5660 else 5661 { 5662 vertex4 = AdjacentEx(in_edge1,in_edge2,index,size); 5663 Output_TriEx(in_edge2,in_edge1,vertex4,-1,where); 5664 5665 /* Now delete the adjacencies by one for all the faces 5666 that are adjacent to the triangle that we just outputted. 5667 */ 5668 Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id, 5669 &dummy,&dummy,&dummy); 5670 Delete_AdjEx(in_edge2,vertex4,&dummy,&dummy, 5671 face_id,&dummy,&dummy,&dummy); 5672 5673 /* Put the new face in the proper bucket of adjacencies */ 5674 next_bucket = Change_FaceEx(face_id,in_edge1,in_edge2, 5675 pListHead,FALSE); 5676 next_bucket = Change_FaceEx(face_id,in_edge2,vertex4, 5677 pListHead,FALSE); 5678 5679 /* Create a new edgelist without the triangle that 5680 was just outputted. 5681 */ 5682 Delete_From_ListEx(in_edge2,index,size); 5683 5684 /* Update the face data structure, by deleting the old 5685 face and putting in the polygon minus the triangle 5686 as the new face, here we will be decrementing the size 5687 by one. 5688 */ 5689 New_Size_Face(face_id); 5690 5691 /* Save the info for the new bucket, we will need it on 5692 the next pass for the variables, pListHead and temp 5693 */ 5694 pListHead = array[next_bucket]; 5695 temp2 = face_array[face_id].pfNode; 5696 if (temp2 == NULL) 5697 { 5698 printf("There is an error finding the next polygon11 %d %d\n", 5699 face_id,next_bucket); 5700 exit(0); 5701 } 5702 5703 P_Triangulate_Polygon(out_edge1,out_edge2,vertex4, 5704 in_edge1,size-1,index,!reversed, 5705 face_id,next_id,pListHead,temp2,where); 5706 } 5707 return; 5708 } 5709 } 5710 5711 /// P_Triangulate: 5712 void CustomStripifier::P_Triangulate( int out_edge1,int out_edge2,int in_edge1, 5713 int in_edge2, int size, int *index, 5714 int reversed, int face_id, 5715 int *next_id, ListHead *pListHead, 5716 P_ADJACENCIES temp,int where) 5717 { 5718 5719 if (size == 4) 5720 P_Triangulate_Quad(out_edge1,out_edge2,in_edge1,in_edge2,size, 5721 index,reversed,face_id, 5722 pListHead,temp,where); 5723 else 5724 P_Triangulate_Polygon(out_edge1,out_edge2,in_edge1,in_edge2,size, 5725 index,reversed,face_id,next_id, 5726 pListHead,temp,where); 5727 } 5728 5729 void CustomStripifier::Partial_Triangulate(int size,int *index, 5730 int next_face_id,int face_id, 5731 int *next_id,ListHead *pListHead, 5732 P_ADJACENCIES temp, int where) 5733 { 5734 int id1,id2,id3; 5735 int nedge1,nedge2; 5736 int reversed; 5737 5738 /* We have a polygon that has to be triangulated and we cannot 5739 do it blindly, ie we will try to come out on the edge that 5740 has the least number of adjacencies, But also we do not 5741 want to triangulate the whole polygon now, so that means 5742 we will output the least number of triangles that we can 5743 and then update the data structures, with the polygon 5744 that is left after we are done. 5745 */ 5746 Last_Edge(&id1,&id2,&id3,0); 5747 5748 /* Find the edge that is adjacent to the new face , 5749 also return whether the orientation is reversed in the 5750 face of the input edge, which is id2 and id3. 5751 */ 5752 reversed = Get_EdgeEx(&nedge1,&nedge2,index,next_face_id,size,id2,id3); 5753 5754 /* Input edge and output edge can be the same if there are more than 5755 one polygon on an edge 5756 */ 5757 if ( ((nedge1 == id2) && (nedge2 == id3)) || 5758 ((nedge1 == id3) && (nedge2 == id2)) ) 5759 /* Set output edge arbitrarily but when come out of here the 5760 next face will be on the old output edge (identical one) 5761 */ 5762 nedge2 = Return_Other(index,id2,id3); 5763 5764 /* Do the triangulation */ 5765 P_Triangulate(nedge1,nedge2,id2,id3,size,index,reversed, 5766 face_id,next_id,pListHead,temp,where); 5767 } 5768 5769 /// Input_Edge: 5770 void CustomStripifier::Input_Edge(int face_id, int *index, 5771 int size, int in_edge1, 5772 int in_edge2, ListHead *pListHead, 5773 int where) 5774 { 5775 /* The polygon had an input edge, specified by input1 and input2 */ 5776 5777 int output1,next_bucket; 5778 int vertex4, vertex5,dummy=60; 5779 5780 output1 = Get_Output_Edge(face_id,size,index,in_edge1,in_edge2); 5781 vertex5 = AdjacentEx(in_edge2,in_edge1,index,size); 5782 vertex4 = AdjacentEx(in_edge1,in_edge2,index,size); 5783 5784 if (vertex4 == output1) 5785 { 5786 Output_TriEx(in_edge2,in_edge1,output1,-1,where); 5787 /* Now delete the adjacencies by one for all the faces 5788 that are adjacent to the triangle that we just outputted. 5789 */ 5790 Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id, 5791 &dummy,&dummy,&dummy); 5792 Delete_AdjEx(in_edge2,output1,&dummy,&dummy, 5793 face_id,&dummy,&dummy,&dummy); 5794 /* Put the new face in the proper bucket of adjacencies */ 5795 next_bucket=Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE); 5796 next_bucket=Change_FaceEx(face_id,in_edge2,output1,pListHead,FALSE); 5797 5798 /* Create a new edgelist without the triangle that 5799 was just outputted. 5800 */ 5801 Delete_From_ListEx(in_edge2,index,size); 5802 5803 } 5804 else if (vertex5 == output1) 5805 { 5806 Output_TriEx(in_edge1,in_edge2,vertex5,-1,where); 5807 /* Now delete the adjacencies by one for all the faces 5808 that are adjacent to the triangle that we just outputted. 5809 */ 5810 Delete_AdjEx(in_edge1,in_edge2,&dummy,&dummy,face_id, 5811 &dummy,&dummy,&dummy); 5812 Delete_AdjEx(in_edge1,vertex5,&dummy,&dummy, 5813 face_id,&dummy,&dummy,&dummy); 5814 /* Put the new face in the proper bucket of adjacencies */ 5815 next_bucket=Change_FaceEx(face_id,in_edge1,in_edge2,pListHead,FALSE); 5816 next_bucket=Change_FaceEx(face_id,in_edge1,vertex5,pListHead,FALSE); 5817 5818 /* Create a new edgelist without the triangle that 5819 was just outputted. 5820 */ 5821 Delete_From_ListEx(in_edge1,index,size); 5822 } 5823 5824 /* Update the face data structure, by deleting the old 5825 face and putting in the polygon minus the triangle 5826 as the new face, here we will be decrementing the size 5827 by one. 5828 */ 5829 New_Size_Face(face_id); 5830 return; 5831 } 5832 5833 /// Inside_Polygon: 5834 void CustomStripifier::Inside_Polygon(int size,int *index, 5835 int face_id,ListHead *pListHead, int where) 5836 { 5837 /* We know that we have a polygon that is greater than 4 sides, and 5838 that it is better for us to go inside the polygon for the next 5839 one, since inside will have less adjacencies than going outside. 5840 So, we are not doing partial for a part of the polygon. 5841 */ 5842 int id1,id2,id3; 5843 int new1,new2; 5844 5845 Last_Edge(&id1,&id2,&id3,0); 5846 5847 /* See if the input edge existed in the polygon, that will help us */ 5848 if (Exist(face_id,id2,id3)) 5849 Input_Edge(face_id,index,size,id2,id3,pListHead,where); 5850 else 5851 { 5852 /* Make one of the input edges 5853 We will choose it by trying to get an edge that has something 5854 in common with the last triangle, or by getting the edge that 5855 is adjacent to the least number of thigs, with preference given 5856 to the first option 5857 */ 5858 5859 Get_Input_Edge(index,id1,id2,id3,&new1,&new2,size,face_id); 5860 Input_Edge(face_id,index,size,new1,new2,pListHead,where); 5861 } 5862 } 5863 5864 /// Finished: 5865 int CustomStripifier::Finished(int *swap, int startnewstrip) 5866 { 5867 /* We have finished all the triangles, now is time to output to 5868 the data file. In the strips data structure, every three ids 5869 is a triangle. Now we see whether we can swap, or make a new strip 5870 or continue the strip, and output the data accordingly to the 5871 data file. 5872 */ 5873 int num,x,vertex1,vertex2; 5874 ListHead *pListHead; 5875 int id[2],other1,other2,index = 0,a,b,c; 5876 P_STRIPS temp1,temp2,temp3,temp4,temp5,temp6; 5877 BOOL cptexture; 5878 *swap =0; 5879 5880 cptexture = text; 5881 pListHead = strips[0]; 5882 if (pListHead == NULL) 5883 return 0; 5884 5885 num = NumOnList(pListHead); 5886 //printf ("There are %d triangles in the extend\n",num/3); 5887 5888 // Go through the list triangle by triangle 5889 temp1 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 0); 5890 temp2 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 1); 5891 temp3 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 2); 5892 5893 // Next triangle for lookahead 5894 temp4 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 3); 5895 5896 // There is only one polygon in the strip 5897 if (temp4 == NULL) 5898 { 5899 // Data might be mixed and we do not have textures for some of the vertices 5900 if ((text) && (vt[temp3->face_id] == 0)) 5901 cptexture = FALSE; 5902 if ((norm) && (!cptexture)) { 5903 if (startnewstrip && orient) // If we want to keep orientation 5904 preserve_strip_orientation_with_normal(temp3->face_id+1,vn[temp3->face_id]+1, 5905 temp2->face_id+1,vn[temp2->face_id]+1, temp1->face_id+1,vn[temp1->face_id]+1); 5906 5907 /* fprintf(output," %d//%d %d//%d %d//%d", temp3->face_id+1,vn[temp3->face_id]+1, 5908 temp2->face_id+1,vn[temp2->face_id]+1, temp1->face_id+1,vn[temp1->face_id]+1);*/ 5909 } 5910 else if ((cptexture) && (!norm)) { 5911 if (startnewstrip && orient) /* If we want to keep orientation */ 5912 preserve_strip_orientation_with_texture(temp3->face_id+1,vt[temp3->face_id]+1, 5913 temp2->face_id+1,vt[temp2->face_id]+1, temp1->face_id+1,vt[temp1->face_id]+1); 5914 5915 /* fprintf(output," %d/%d %d/%d %d/%d", temp3->face_id+1,vt[temp3->face_id]+1, 5916 temp2->face_id+1,vt[temp2->face_id]+1, temp1->face_id+1,vt[temp1->face_id]+1);*/ 5917 } 5918 else if ((cptexture)&& (norm)) { 5919 if (startnewstrip && orient) /* If we want to keep orientation */ 5920 preserve_strip_orientation_with_texture_and_normal(temp3->face_id+1,vt[temp3->face_id]+1,vn[temp3->face_id]+1, 5921 temp2->face_id+1,vt[temp2->face_id]+1,vn[temp2->face_id]+1, temp1->face_id+1,vt[temp1->face_id]+1,vn[temp1->face_id]+1); 5922 5923 /* fprintf(output," %d/%d/%d %d/%d/%d %d/%d/%d", temp3->face_id+1,vt[temp3->face_id]+1,vn[temp3->face_id]+1, 5924 temp2->face_id+1,vt[temp2->face_id]+1,vn[temp2->face_id]+1, temp1->face_id+1,vt[temp1->face_id]+1,vn[temp1->face_id]+1);*/ 5925 } 5926 else 5927 { 5928 if (startnewstrip && orient) /* If we want to keep orientation */ 5929 preserve_strip_orientation(temp3->face_id+1,temp2->face_id+1,temp1->face_id+1); 5930 5931 // fprintf(output," %d %d %d", temp3->face_id+1,temp2->face_id+1,temp1->face_id+1); 5932 mi_vector[num_tiras].push_back(temp3->face_id); 5933 mi_vector[num_tiras].push_back(temp2->face_id); 5934 mi_vector[num_tiras].push_back(temp1->face_id); 5935 } 5936 Free_Strips(); 5937 5938 return 1; 5939 } 5940 5941 // We have a real strip 5942 temp5 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 4); 5943 temp6 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 5); 5944 5945 if ((temp1 == NULL) || (temp2 == NULL) || (temp3 == NULL) || (temp5 == NULL) || (temp6 == NULL)) 5946 { 5947 printf("There is an error in the output of the triangles\n"); 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 { 5948 1221 exit(0); 5949 1222 } 5950 1223 5951 // Find the vertex in the first triangle that is not in the second 5952 vertex1 = Different(temp1->face_id,temp2->face_id,temp3->face_id, temp4->face_id,temp5->face_id,temp6->face_id, &other1,&other2); 5953 // Find the vertex in the second triangle that is not in the first 5954 vertex2 = Different(temp4->face_id,temp5->face_id,temp6->face_id, temp1->face_id,temp2->face_id,temp3->face_id, &other1,&other2); 5955 5956 // Lookahead for the correct order of the 2nd and 3rd vertex of the first triangle 5957 temp1 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 6); 5958 temp2 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 7); 5959 temp3 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, 8); 5960 5961 if (temp1 != NULL) 5962 other1 = Different(temp3->face_id,temp4->face_id,temp5->face_id, temp1->face_id,temp2->face_id,temp3->face_id,&other1,&a); 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); 5963 1229 5964 1230 id[index] = vertex1; index = !index; … … 5966 1232 id[index] = other2; index = !index; 5967 1233 5968 a = temp4->face_id; 5969 b = temp5->face_id; 5970 c = temp6->face_id; 5971 5972 /* 5973 // If we need to rearrange the first sequence because otherwise there would have been a swap. 5974 if ((temp3 != NULL) && (text) && ( vt[temp3->face_id]==0)) 5975 cptexture = FALSE; 5976 if ((norm) && (!cptexture)) { 5977 if (orient && startnewstrip) // If we want to keep orientation 5978 preserve_strip_orientation_with_normal(output, vertex1+1,vn[vertex1]+1, other1+1,vn[other1]+1, other2+1,vn[other2]+1); 1234 a = Strips[3]; 1235 b = Strips[4]; 1236 c = Strips[5]; 1237 1238 Orient(vertex1+1,other1+1,other2+1); 5979 1239 5980 fprintf(output," %d//%d %d//%d %d//%d", vertex1+1,vn[vertex1]+1, other1+1,vn[other1]+1, other2+1,vn[other2]+1); 5981 } 5982 else if ((cptexture) && (!norm)) { 5983 if (orient && startnewstrip) // If we want to keep orientation 5984 preserve_strip_orientation_with_texture(output, vertex1+1,vt[vertex1]+1, other1+1,vt[other1]+1, other2+1,vt[other2]+1); 5985 5986 fprintf(output," %d/%d %d/%d %d/%d", vertex1+1,vt[vertex1]+1, other1+1,vt[other1]+1, other2+1,vt[other2]+1); 5987 } 5988 else if ((cptexture) && (norm)) { 5989 if (orient && startnewstrip) // If we want to keep orientation 5990 preserve_strip_orientation_with_texture_and_normal(output, vertex1+1,vt[vertex1]+1,vn[vertex1]+1, 5991 other1+1,vt[other1]+1,vn[other1]+1, other2+1,vt[other2]+1,vn[other2]+1); 5992 5993 fprintf(output," %d/%d/%d %d/%d/%d %d/%d/%d", vertex1+1,vt[vertex1]+1,vn[vertex1]+1, 5994 other1+1,vt[other1]+1,vn[other1]+1, other2+1,vt[other2]+1,vn[other2]+1); 5995 } 5996 else 5997 { 5998 */ 5999 if (orient && startnewstrip) // If we want to keep orientation 6000 preserve_strip_orientation(vertex1+1,other1+1,other2+1); 6001 6002 // fprintf(output," %d %d %d",vertex1+1,other1+1,other2+1); 6003 mi_vector[num_tiras].push_back(vertex1); 6004 mi_vector[num_tiras].push_back(other1); 6005 mi_vector[num_tiras].push_back(other2); 6006 6007 /* 6008 } 6009 */ 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 6010 1244 for (x = 6; x < num ; x = x+3) 6011 1245 { 6012 // Get the next triangle6013 temp1 = ( P_STRIPS ) PeekList( pListHead, LISTHEAD, x);6014 temp2 = ( P_STRIPS ) GetNextNode(temp1);6015 temp3 = ( P_STRIPS ) GetNextNode(temp2);6016 6017 1246 // Error checking 6018 if (!(member(id[0],a,b,c)) || !(member(id[1],a,b,c)) || !(member(vertex2,a,b,c))) 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))) 6019 1250 { 6020 // If we used partial we might have a break in the middle of a strip 6021 // fprintf(output,"\nt"); 6022 startnewstrip = 1; 6023 mi_vector_tipo nada; 6024 mi_vector.push_back(nada); 1251 vector_int nada; 1252 my_vector.push_back(nada); 1253 6025 1254 num_tiras++; 6026 // Find the vertex in the first triangle that is not in the second 6027 vertex1 = Different(a,b,c,temp1->face_id,temp2->face_id,temp3->face_id,&other1,&other2); 6028 // Find the vertex in the second triangle that is not in the first 6029 vertex2 = Different(temp1->face_id,temp2->face_id,temp3->face_id, a,b,c,&other1,&other2); 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); 6030 1258 6031 1259 id[index] = vertex1; index = !index; … … 6034 1262 } 6035 1263 6036 if ((temp1 == NULL ) || (temp2 == NULL) || (temp3 == NULL)) 6037 { 6038 printf("There is an error in the triangle list \n"); 6039 exit(0); 6040 } 6041 1264 6042 1265 if ((id[0] == id[1]) || (id[0] == vertex2)) 6043 1266 continue; 6044 1267 6045 if (( member(id[index],temp1->face_id,temp2->face_id,temp3->face_id)))1268 if ((id[index] == Strips[x]) || (id[index] == Strips[x+1]) || (id[index] == Strips[x+2])) 6046 1269 { 6047 if ((text) && ( vt[id[index]]==0)) 6048 cptexture = FALSE; 6049 if ((!norm) && (!cptexture)) 6050 { 6051 // fprintf(output," %d",id[index]+1); 6052 mi_vector[num_tiras].push_back(id[index]); 6053 } 6054 /* else if ((norm) && (!cptexture)) 6055 fprintf(output," %d//%d",id[index]+1,vn[id[index]]+1); 6056 else if ((!norm) && (cptexture)) 6057 fprintf(output," %d/%d",id[index]+1,vt[id[index]]+1); 6058 else 6059 fprintf(output," %d/%d/%d", id[index]+1,vt[id[index]]+1,vn[id[index]]+1);*/ 1270 1271 my_vector[num_tiras].push_back(id[index]); 1272 6060 1273 6061 1274 index = !index; 6062 *swap = *swap + 1;6063 1275 } 6064 1276 6065 if ((text) && ( vt[vertex2]==0)) 6066 cptexture = FALSE; 6067 if ((!norm) && (!cptexture)) 6068 { 6069 // fprintf(output,"\nq %d",vertex2+1); 6070 mi_vector[num_tiras].push_back(vertex2); 6071 } 6072 /* else if ((norm) && (!cptexture)) 6073 fprintf(output,"\nq %d//%d",vertex2+1,vn[vertex2]+1); 6074 else if ((!norm) && (cptexture)) 6075 fprintf(output,"\nq %d/%d",vertex2+1,vt[vertex2]+1); 6076 else 6077 fprintf(output,"\nq %d/%d/%d",vertex2+1,vt[vertex2]+1,vn[vertex2]+1); 6078 */ 1277 my_vector[num_tiras].push_back(vertex2); 1278 6079 1279 id[index] = vertex2; index = !index; 6080 1280 6081 // Get the next vertex not in common 6082 vertex2 = Different(temp1->face_id,temp2->face_id,temp3->face_id, a,b,c,&other1,&other2); 6083 a = temp1->face_id; 6084 b = temp2->face_id; 6085 c = temp3->face_id; 6086 } 6087 // Do the last vertex 6088 if ((text) && (vt[vertex2]==0)) 6089 { 6090 /* if (cptexture) 6091 fprintf(output,"\nq");*/ 6092 cptexture = FALSE; 6093 } 6094 6095 if ((!norm) && (!cptexture)) 6096 { 6097 // fprintf(output," %d",vertex2+1); 6098 mi_vector[num_tiras].push_back(vertex2); 6099 } 6100 /* else if ((norm) && (!cptexture)) 6101 fprintf(output," %d//%d",vertex2+1,vn[vertex2]+1); 6102 else if ((!norm) && (cptexture)) 6103 fprintf(output," %d/%d",vertex2+1,vt[vertex2]+1); 6104 else 6105 fprintf(output," %d/%d/%d",vertex2+1,vt[vertex2]+1,vn[vertex2]+1); 6106 */ 6107 Free_Strips(); 6108 return (num/3); 6109 } 6110 6111 /// Output_Tri: 6112 void CustomStripifier::Output_Tri(int id1, int id2, int id3,BOOL end) 6113 { 6114 /* We will save everything into a list, rather than output at once, 6115 as was done in the old routine. This way for future modifications 6116 we can change the strips later on if we want to. 6117 */ 6118 6119 int temp1,temp2,temp3; 6120 6121 /* Make sure we do not have an error */ 6122 /* There are degeneracies in some of the files */ 6123 if ( (id1 == id2) || (id1 == id3) || (id2 == id3)) 6124 { 6125 printf("Degenerate triangle %d %d %d\n",id1,id2,id3); 6126 exit(0); 6127 } 6128 else 6129 { 6130 Last_Edge(&temp1,&temp2,&temp3,0); 6131 Add_Id_Strips(id1,end); 6132 Add_Id_Strips(id2,end); 6133 Add_Id_Strips(id3,end); 6134 Last_Edge(&id1,&id2,&id3,1); 6135 } 6136 } 6137 6138 /// Polygon_Output: 6139 int CustomStripifier::Polygon_Output( P_ADJACENCIES temp, int face_id, 6140 int bucket, ListHead *pListHead, 6141 BOOL first, int *swaps, 6142 int color1, 6143 int color2, int color3, 6144 BOOL global, BOOL end) 6145 { 6146 ListHead *pListFace; 6147 PF_FACES face; 6148 int next_face_id,next_bucket,e1,e2,e3,other1,other2,other3; 6149 P_ADJACENCIES lpListInfo; 6150 int ties=0; 6151 6152 /* We have a polygon to output, the id is face id, and the number 6153 of adjacent polygons to it is bucket. This routine extends the patches from 6154 either end to make longer triangle strips. 6155 */ 6156 6157 6158 /* Now get the edge */ 6159 Last_Edge(&e1,&e2,&e3,0); 6160 6161 /* Get the polygon with id face_id */ 6162 pListFace = PolFaces[face_id]; 6163 face = (PF_FACES) PeekList(pListFace,LISTHEAD,0); 6164 6165 /* We can't go any more */ 6166 if ((face->nPolSize == 1) || ((face->nPolSize == 4) && (global))) 6167 /* if global, then we are still doing patches */ 6168 { 6169 /* Remove it from the list so we do not have to waste 6170 time visiting it in the future, or winding up in an infinite loop 6171 if it is the first on that we are looking at for a possible strip 6172 */ 6173 if (face->nPolSize == 1) { 6174 if (face_array[temp->face_id].head == pListHead) 6175 face_array[temp->face_id].pfNode = NULL; 6176 RemoveList(pListHead,(PLISTINFO) temp); 6177 } 6178 if (first) 6179 return 0; 6180 else 6181 return (Finished(swaps,0)); 6182 } 6183 6184 if (face->nPolSize == 3) 6185 { 6186 /* It is already a triangle */ 6187 if (bucket == 0) 6188 { 6189 /* It is not adjacent to anything so we do not have to 6190 worry about the order of the sides or updating adjacencies 6191 */ 6192 6193 next_face_id = Different(*(face->pPolygon),*(face->pPolygon+1), 6194 *(face->pPolygon+2), 6195 e1,e2,e3,&other1,&other2); 6196 face->nPolSize = 1; 6197 6198 /* If this is the first triangle in the strip */ 6199 if ((e2 == 0) && (e3 ==0)) 6200 { 6201 e2 = other1; 6202 e3 = other2; 6203 } 6204 6205 Output_Tri(e2,e3,next_face_id,end); 6206 if (face_array[temp->face_id].head == pListHead) 6207 face_array[temp->face_id].pfNode = NULL; 6208 RemoveList(pListHead,(PLISTINFO) temp); 6209 return (Finished(swaps,0)); 6210 } 6211 6212 6213 /* It is a triangle with adjacencies. This means that we 6214 have to: 6215 1. Update the adjacencies in the list, because we are 6216 using this polygon and it will be deleted. 6217 2. Get the next polygon. 6218 */ 6219 else 6220 { 6221 /* Return the face_id of the next polygon we will be using, 6222 while updating the adjacency list by decrementing the 6223 adjacencies of everything adjacent to the current triangle. 6224 */ 6225 6226 next_face_id = Update_Adjacencies(face_id, &next_bucket, &e1,&e2,&ties); 6227 /* Maybe we deleted something in a patch and could not 6228 find an adj polygon */ 6229 if (next_face_id == -1) 6230 { 6231 Output_Tri(*(face->pPolygon),*(face->pPolygon+1), 6232 *(face->pPolygon+2),end); 6233 face->nPolSize = 1; 6234 if (face_array[temp->face_id].head == pListHead) 6235 face_array[temp->face_id].pfNode = NULL; 6236 RemoveList(pListHead,(PLISTINFO) temp); 6237 return (Finished(swaps,0)); 6238 } 6239 6240 6241 /* Find the other vertex to transmit in the triangle */ 6242 e3 = Return_Other(face->pPolygon,e1,e2); 6243 Last_Edge(&other1,&other2,&other3,0); 6244 6245 if ((other2 != 0) && (other3 != 0)) 6246 { 6247 /* See which vertex in the output edge is not in the input edge */ 6248 if ((e1 != other2) && (e1 != other3)) 6249 e3 = e1; 6250 else if ((e2 != other2) && (e2 != other3)) 6251 e3 = e2; 6252 else 6253 { 6254 printf("There is an error in the tri with adj\n"); 6255 exit(0); 6256 } 6257 6258 /* See which vertex of the input edge is not in the output edge */ 6259 if ((other2 != e1) && (other2 != e2)) 6260 { 6261 other1 = other2; 6262 other2 = other3; 6263 } 6264 else if ((other3 != e1) && (other3 != e2)) 6265 other1 = other3; 6266 else 6267 { 6268 printf("There is an error in getting the tri with adj\n"); 6269 exit(0); 6270 } 6271 6272 } 6273 else 6274 { 6275 /* We are the first triangle in the strip and the starting edge 6276 has not been set yet 6277 */ 6278 /* Maybe we deleted something in a patch and could not 6279 find an adj polygon */ 6280 if (next_face_id == -1) 6281 { 6282 Output_Tri(*(face->pPolygon),*(face->pPolygon+1), 6283 *(face->pPolygon+2),end); 6284 face->nPolSize = 1; 6285 face_array[temp->face_id].pfNode = NULL; 6286 RemoveList(pListHead,(PLISTINFO) temp); 6287 return (Finished(swaps,0)); 6288 } 6289 6290 other1 = e3; 6291 e3 = e2; 6292 other2 = e1; 6293 } 6294 6295 /* At this point the adjacencies have been updated and we 6296 have the next polygon id 6297 */ 6298 6299 Output_Tri(other1,other2,e3,end); 6300 face->nPolSize = 1; 6301 if (face_array[temp->face_id].head == pListHead) 6302 face_array[temp->face_id].pfNode = NULL; 6303 RemoveList(pListHead,(PLISTINFO) temp); 6304 6305 /* Maybe we deleted something in a patch and could not 6306 find an adj polygon */ 6307 if (next_face_id == -1) 6308 return (Finished(swaps,0)); 6309 6310 if (Done(next_face_id,&next_bucket) == NULL) 6311 { 6312 printf("We deleted the next face 4%d\n",next_face_id); 6313 exit(0); 6314 } 6315 6316 pListHead = array[next_bucket]; 6317 lpListInfo = face_array[next_face_id].pfNode; 6318 if (lpListInfo == NULL) 6319 { 6320 printf("There is an error finding the next polygon3 %d\n", 6321 next_face_id); 6322 exit(0); 6323 } 6324 return (Polygon_Output(lpListInfo,next_face_id,next_bucket, 6325 pListHead, FALSE, swaps, 6326 color1,color2,color3,global,end)); 6327 6328 } 6329 } 6330 6331 else 6332 { 6333 /* It is not a triangle, we have to triangulate it . 6334 Since it is not adjacent to anything we can triangulate it 6335 blindly 6336 */ 6337 if (bucket == 0) 6338 { 6339 /* It is the first polygon in the strip, therefore there is no 6340 input edge to start with. 6341 */ 6342 if ((e2 == 0) && (e3 ==0)) 6343 Blind_Triangulate(face->nPolSize,face->pPolygon,TRUE,1); 6344 6345 else 6346 Blind_Triangulate(face->nPolSize,face->pPolygon,FALSE,1); 6347 6348 if (face_array[temp->face_id].head == pListHead) 6349 face_array[temp->face_id].pfNode = NULL; 6350 RemoveList(pListHead,(PLISTINFO) temp); 6351 6352 /* We will be at the beginning of the next strip. */ 6353 face->nPolSize = 1; 6354 return (Finished(swaps,0)); 6355 } 6356 6357 6358 else 6359 { 6360 6361 6362 /* WHOLE triangulation */ 6363 /* It is not a triangle and has adjacencies. 6364 This means that we have to: 6365 1. Triangulate this polygon, not blindly because 6366 we have an edge that we want to come out on, that 6367 is the edge that is adjacent to a polygon with the 6368 least number of adjacencies. Also we must come in 6369 on the last seen edge. 6370 2. Update the adjacencies in the list, because we are 6371 using this polygon . 6372 3. Get the next polygon. 6373 */ 6374 /* Return the face_id of the next polygon we will be using, 6375 while updating the adjacency list by decrementing the 6376 adjacencies of everything adjacent to the current polygon. 6377 */ 6378 6379 next_face_id = Update_Adjacencies(face_id, &next_bucket, &e1,&e2,&ties); 6380 6381 /* Maybe we deleted something in a patch and could not 6382 find an adj polygon */ 6383 if (next_face_id == -1) 6384 { 6385 6386 /* If we are at the first polygon in the strip and 6387 there is no input 6388 edge, then begin is TRUE 6389 */ 6390 if ((e2 == 0) && (e3 == 0)) 6391 Blind_Triangulate(face->nPolSize,face->pPolygon,TRUE,1); 6392 6393 else 6394 Blind_Triangulate(face->nPolSize,face->pPolygon,FALSE,1); 6395 6396 if (face_array[temp->face_id].head == pListHead) 6397 face_array[temp->face_id].pfNode = NULL; 6398 RemoveList(pListHead,(PLISTINFO) temp); 6399 6400 /* We will be at the beginning of the next strip. */ 6401 face->nPolSize = 1; 6402 return (Finished(swaps,0)); 6403 } 6404 6405 if (Done(next_face_id,&next_bucket) == NULL) 6406 { 6407 printf("We deleted the next face 6 %d %d\n",next_face_id,face_id); 6408 exit(0); 6409 } 6410 6411 Non_Blind_Triangulate(face->nPolSize,face->pPolygon, 6412 next_face_id,face_id,1, 6413 color1,color2,color3); 6414 6415 if (face_array[temp->face_id].head == pListHead) 6416 face_array[temp->face_id].pfNode = NULL; 6417 RemoveList(pListHead,(PLISTINFO) temp); 6418 face->nPolSize = 1; 6419 pListHead = array[next_bucket]; 6420 lpListInfo = face_array[next_face_id].pfNode; 6421 6422 if (lpListInfo == NULL) 6423 { 6424 printf("There is an error finding the next polygon2 %d %d\n", 6425 next_face_id,next_bucket); 6426 exit(0); 6427 } 6428 return (Polygon_Output(lpListInfo,next_face_id,next_bucket, 6429 pListHead, FALSE, swaps, 6430 color1,color2,color3,global,end)); 6431 } 6432 6433 } 6434 } 6435 6436 /// Extend_Face: 6437 int CustomStripifier::Extend_Face(int face_id, 6438 int e1, 6439 int e2, 6440 int *swaps, 6441 int color1, 6442 int color2, 6443 int color3, 6444 int *vert_norm, 6445 int normals, 6446 int *vert_texture, 6447 int texture) 6448 { 6449 int dummy = 0; 6450 int next_bucket; 6451 P_ADJACENCIES lpListInfo; 6452 ListHead *pListHead; 6453 6454 /* Try to extend backwards off of the local strip that we just found */ 6455 6456 vn = vert_norm; 6457 vt = vert_texture; 6458 norm = normals; 6459 text = texture; 6460 6461 *swaps = 0; 6462 /* Find the face that is adjacent to the edge and is not the 6463 current face. 6464 */ 6465 face_id = Find_Face(face_id, e1, e2,&next_bucket); 6466 if (face_id == -1) 6467 return 0; 6468 6469 pListHead = array[next_bucket]; 6470 lpListInfo = face_array[face_id].pfNode; 6471 6472 if (lpListInfo == NULL) 6473 { 6474 printf("There is an error finding the next polygon3 %d\n",face_id); 6475 exit(0); 6476 } 6477 Last_Edge(&dummy,&e1,&e2,1); 6478 6479 /* Find a strip extending from the patch and return the cost */ 6480 return (Polygon_Output(lpListInfo,face_id,next_bucket,pListHead,TRUE,swaps, 6481 color1,color2,color3,TRUE,TRUE)); 6482 } 6483 6484 /// ParseAndFreeList: 6485 void CustomStripifier::ParseAndFreeList( ListHead *pListHead ) 6486 { 6487 PLISTINFO value; 6488 register int c; 6489 register int num; 6490 6491 /* Freeing a linked list */ 6492 num = NumOnList(pListHead); 6493 6494 for (c = 0; c< num; c++) 6495 { 6496 value = RemHead(pListHead); 6497 } 6498 } 6499 6500 /// Free_Strips: 6501 void CustomStripifier::Free_Strips() 6502 { 6503 /* Free strips data structure */ 6504 if (strips[0] == NULL) 6505 return; 6506 else 6507 ParseAndFreeList(strips[0]); 6508 } 6509 6510 /// FreeFaceTable: 6511 void CustomStripifier::FreeFaceTable(int nSize) 6512 { 6513 register int nIndex; 6514 6515 for ( nIndex=0; nIndex < nSize; nIndex++ ) 6516 { 6517 if ( PolFaces[nIndex] != NULL ) 6518 ParseAndFreeList( PolFaces[nIndex] ); 6519 } 6520 free( PolFaces ); 6521 } 6522 6523 /// FreeEdgeTable: 6524 void CustomStripifier::FreeEdgeTable(int nSize) 6525 { 6526 register int nIndex; 6527 6528 for ( nIndex=0; nIndex < nSize; nIndex++ ) 6529 { 6530 if ( PolEdges[nIndex] != NULL ) 6531 ParseAndFreeList( PolEdges[nIndex] ); 6532 } 6533 free( PolEdges ); 6534 } 6535 6536 /// End_Face_Struct: 6537 void CustomStripifier::End_Face_Struct(int numfaces) 6538 { 6539 FreeFaceTable(numfaces); 6540 } 6541 6542 /// End_Edge_Struct: 6543 void CustomStripifier::End_Edge_Struct(int numverts) 6544 { 6545 FreeEdgeTable(numverts); 6546 } 6547 6548 /// Calculate_Walks: 6549 int CustomStripifier::Calculate_Walks(int lastvert,int y, PF_FACES temp2) 6550 { 6551 /* Find the length of the walk */ 6552 6553 int previous_edge1, previous_edge2; 6554 register int nextvert,numverts,counter,walk=0; 6555 BOOL flag; 6556 F_EDGES *node; 6557 ListHead *pListHead; 6558 static int seen = 0; 6559 6560 /* Find the edge that we are currently on */ 6561 if (y != 3) 6562 { 6563 previous_edge1 = *(temp2->pPolygon +y); 6564 previous_edge2 = *(temp2->pPolygon + y + 1); 6565 } 6566 else 6567 { 6568 previous_edge1 = *(temp2->pPolygon +y); 6569 previous_edge2 = *(temp2->pPolygon); 6570 } 6571 6572 temp2->seen = seen; 6573 counter = y; 6574 6575 /*Find the adjacent face to this edge */ 6576 node = *(temp2->VertandId+y); 6577 if (node->edge[2] != lastvert) 6578 nextvert = node->edge[2]; 6579 else 6580 nextvert = node->edge[1]; 6581 6582 /* Keep walking in this direction until we cannot do so */ 6583 while ((nextvert != lastvert) && (nextvert != -1)) 6584 { 6585 walk++; 6586 pListHead = PolFaces[nextvert]; 6587 temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0); 6588 numverts = temp2->nPolSize; 6589 if ((numverts != 4) || (temp2->seen == seen)) 6590 { 6591 walk--; 6592 nextvert = -1; 6593 } 6594 else 6595 { 6596 temp2->seen = seen; 6597 /* Find edge that is not adjacent to the previous one */ 6598 counter = 0; 6599 flag = TRUE; 6600 while ((counter < 3) && (flag)) 6601 { 6602 if ( ((*(temp2->pPolygon+counter) == previous_edge1) || 6603 (*(temp2->pPolygon+counter+1) == previous_edge2)) || 6604 ((*(temp2->pPolygon+counter) == previous_edge2) || 6605 (*(temp2->pPolygon+counter+1) == previous_edge1)) ) 6606 counter++; 6607 else 6608 flag = FALSE; 6609 } 6610 /* Get the IDs of the next edge */ 6611 if (counter < 3) 6612 { 6613 previous_edge1 = *(temp2->pPolygon + counter); 6614 previous_edge2 = *(temp2->pPolygon + counter + 1); 6615 } 6616 else 6617 { 6618 previous_edge1 = *(temp2->pPolygon + counter); 6619 previous_edge2 = *(temp2->pPolygon); 6620 } 6621 6622 node = *(temp2->VertandId + counter); 6623 if (node->edge[1] == nextvert) 6624 nextvert = node->edge[2]; 6625 else 6626 nextvert = node->edge[1]; 6627 } 6628 } 6629 seen++; 6630 return walk; 6631 } 6632 6633 /// Check_Right: 6634 BOOL CustomStripifier::Check_Right( int last_seen,PF_FACES temp2, 6635 int y,int face_id) 6636 { 6637 /* Check when we last saw the face to the right of the current 6638 one. We want to have seen it just before we started this strip 6639 */ 6640 6641 F_EDGES *node; 6642 ListHead *pListHead; 6643 register int nextvert,oldy; 6644 PF_FACES t; 6645 6646 oldy = y; 6647 if (y != 3) 6648 y = y+1; 6649 else 6650 y = 0; 6651 node = *(temp2->VertandId + y); 6652 if (face_id == node->edge[1]) 6653 nextvert = node->edge[2]; 6654 else 6655 nextvert = node->edge[1]; 6656 6657 if (nextvert == -1) 6658 return FALSE; 6659 6660 pListHead = PolFaces[nextvert]; 6661 t = (PF_FACES) PeekList(pListHead,LISTHEAD,0); 6662 if (t->seen != (last_seen - 1)) 6663 { 6664 /* maybe because of the numbering, we are not 6665 on the right orientation, so we have to check the 6666 opposite one to be sure 6667 */ 6668 if (oldy != 0) 6669 y = oldy-1; 6670 else 6671 y = 3; 6672 node = *(temp2->VertandId + y); 6673 if (face_id == node->edge[1]) 6674 nextvert = node->edge[2]; 6675 else 6676 nextvert = node->edge[1]; 6677 if (nextvert == -1) 6678 return FALSE; 6679 pListHead = PolFaces[nextvert]; 6680 t = (PF_FACES) PeekList(pListHead,LISTHEAD,0); 6681 if (t->seen != (last_seen - 1)) 6682 return FALSE; 6683 } 6684 return TRUE; 6685 } 6686 6687 /// Update_and_Test: 6688 int CustomStripifier::Update_and_Test(PF_FACES temp2,int y, 6689 BOOL first,int distance, 6690 int lastvert, int val) 6691 { 6692 6693 static int last_seen = 17; 6694 int previous_edge1, previous_edge2; 6695 register int original_distance,nextvert,numverts,counter; 6696 BOOL flag; 6697 F_EDGES *node; 6698 ListHead *pListHead; 6699 6700 original_distance = distance; 6701 /* Find the edge that we are currently on */ 6702 if (y != 3) 6703 { 6704 previous_edge1 = *(temp2->pPolygon +y); 6705 previous_edge2 = *(temp2->pPolygon + y + 1); 6706 } 6707 else 6708 { 6709 previous_edge1 = *(temp2->pPolygon +y); 6710 previous_edge2 = *(temp2->pPolygon); 6711 } 6712 6713 temp2->seen = val; 6714 temp2->seen2 = val; 6715 6716 node = *(temp2->VertandId+y); 6717 if (lastvert != node->edge[2]) 6718 nextvert = node->edge[2]; 6719 else 6720 nextvert = node->edge[1]; 6721 6722 /* Keep walking in this direction until we cannot do so or 6723 we go to distance */ 6724 while ((distance > 0) && (nextvert != lastvert) && (nextvert != -1)) 6725 { 6726 distance--; 6727 6728 pListHead = PolFaces[nextvert]; 6729 temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0); 6730 temp2->seen = val; 6731 6732 if (temp2->seen2 == val) 6733 { 6734 last_seen++; 6735 return (original_distance - distance); 6736 } 6737 6738 temp2->seen2 = val; 6739 6740 numverts = temp2->nPolSize; 6741 6742 if (numverts != 4) 6743 nextvert = -1; 6744 6745 else if ((!first) && (!(Check_Right(last_seen,temp2,y,nextvert)))) 6746 { 6747 last_seen++; 6748 return (original_distance - distance); 6749 } 6750 else 6751 { 6752 /* Find edge that is not adjacent to the previous one */ 6753 counter = 0; 6754 flag = TRUE; 6755 while ((counter < 3) && (flag)) 6756 { 6757 if ( ((*(temp2->pPolygon+counter) == previous_edge1) || 6758 (*(temp2->pPolygon+counter+1) == previous_edge2)) || 6759 ((*(temp2->pPolygon+counter) == previous_edge2) || 6760 (*(temp2->pPolygon+counter+1) == previous_edge1)) ) 6761 counter++; 6762 else 6763 flag = FALSE; 6764 } 6765 /* Get the IDs of the next edge */ 6766 if (counter < 3) 6767 { 6768 previous_edge1 = *(temp2->pPolygon + counter); 6769 previous_edge2 = *(temp2->pPolygon + counter + 1); 6770 } 6771 else 6772 { 6773 previous_edge1 = *(temp2->pPolygon + counter); 6774 previous_edge2 = *(temp2->pPolygon); 6775 } 6776 if ( ((*(temp2->walked+counter) == -1) && 6777 (*(temp2->walked+counter+2) == -1))) 6778 { 6779 printf("There is an error in the walks!\n"); 6780 printf("1Code %d %d \n",*(temp2->walked+counter), 6781 *(temp2->walked+counter+2)); 6782 exit(0); 6783 } 6784 else 6785 { 6786 if ((*(temp2->walked+counter) == -1) && 6787 (*(temp2->walked+counter-2) == -1)) 6788 { 6789 printf("There is an error in the walks!\n"); 6790 printf("2Code %d %d \n",*(temp2->walked+counter), 6791 *(temp2->walked+counter-2)); 6792 exit(0); 6793 } 6794 } 6795 node = *(temp2->VertandId + counter); 6796 y = counter; 6797 if (node->edge[1] == nextvert) 6798 nextvert = node->edge[2]; 6799 else 6800 nextvert = node->edge[1]; 6801 } 6802 } 6803 6804 last_seen++; 6805 6806 if (distance != 0) 6807 { 6808 if (((nextvert == -1) || (nextvert == lastvert)) && (distance != 1)) 6809 return (original_distance - distance); 6810 } 6811 return original_distance; 6812 } 6813 6814 /// Test_Adj: 6815 int CustomStripifier::Test_Adj(PF_FACES temp2,int x,int north,int distance,int lastvert, int value) 6816 { 6817 /* if first time, then just update the last seen field */ 6818 if (x==1) 6819 return(Update_and_Test(temp2,north,TRUE,distance,lastvert,value)); 6820 /* else we have to check if we are adjacent to the last strip */ 6821 else 6822 return(Update_and_Test(temp2,north,FALSE,distance,lastvert,value)); 6823 } 6824 6825 /// Find_Max: 6826 int CustomStripifier::Find_Max( PF_FACES temp2, int lastvert, 6827 int north, int left, 6828 int *lastminup, int *lastminleft) 6829 { 6830 int temp,walk,counter,minup,x,band_value; 6831 int previous_edge1, previous_edge2; 6832 F_EDGES *node; 6833 ListHead *pListHead; 6834 BOOL flag; 6835 static int last_seen = 0; 6836 register int smallest_so_far,nextvert,max=-1; 6837 6838 *lastminup = MAX_BAND; 6839 *lastminleft = 1; 6840 6841 if (left == 3) 6842 { 6843 previous_edge1 = *(temp2->pPolygon + left); 6844 previous_edge2 = *(temp2->pPolygon); 6845 } 6846 6847 else 6848 { 6849 previous_edge1 = *(temp2->pPolygon + left + 1); 6850 previous_edge2 = *(temp2->pPolygon + left); 6851 } 6852 6853 temp2->seen = last_seen; 6854 walk = *(temp2->walked + left); 6855 6856 for (x=1;x<=(walk+1); x++) 6857 { 6858 /* test to see if we have a true band 6859 that is, are they adjacent to each other 6860 */ 6861 6862 minup = *(temp2->walked + north) + 1; 6863 6864 /* if we are at the very first face, then we do not 6865 have to check the adjacent faces going up 6866 and our north distance is the distance of this face's 6867 north direction. 6868 */ 6869 if (x == 1) 6870 { 6871 *lastminup = minup; 6872 minup = Test_Adj(temp2,x,north,*lastminup,lastvert,last_seen); 6873 *lastminup = minup; 6874 smallest_so_far = minup; 6875 } 6876 6877 6878 /* find the largest band that we can have */ 6879 if (minup < (*lastminup)) 6880 { 6881 /* see if we really can go up all the way 6882 temp should by less than our equal to minup 6883 if it is less, then one of the faces was not 6884 adjacent to those next to it and the band height 6885 will be smaller 6886 */ 6887 temp = Test_Adj(temp2,x,north,minup,lastvert,last_seen); 6888 if (temp > minup) 6889 { 6890 printf("There is an error in the test adj\n"); 6891 exit(0); 6892 } 6893 minup = temp; 6894 band_value = x * minup; 6895 if (minup < smallest_so_far) 6896 { 6897 if (band_value > max) 6898 { 6899 smallest_so_far = minup; 6900 *lastminup = minup; 6901 *lastminleft = x; 6902 max = band_value; 6903 } 6904 else 6905 smallest_so_far = minup; 6906 } 6907 else 6908 { 6909 band_value = x * smallest_so_far; 6910 if (band_value > max) 6911 { 6912 *lastminup = smallest_so_far; 6913 *lastminleft = x; 6914 max = band_value; 6915 } 6916 } 6917 } 6918 else 6919 { 6920 if (x != 1) 6921 { 6922 temp = Test_Adj(temp2,x,north,smallest_so_far,lastvert,last_seen); 6923 if (temp > smallest_so_far) 6924 { 6925 printf("There is an error in the test adj\n"); 6926 exit(0); 6927 } 6928 smallest_so_far = temp; 6929 } 6930 band_value = x * smallest_so_far; 6931 if (band_value > max) 6932 { 6933 *lastminup = smallest_so_far; 6934 *lastminleft = x; 6935 max = band_value; 6936 } 6937 } 6938 if ( x != (walk + 1)) 6939 { 6940 node = *(temp2->VertandId+left); 6941 if (lastvert == node->edge[1]) 6942 nextvert = node->edge[2]; 6943 else 6944 nextvert = node->edge[1]; 6945 6946 lastvert = nextvert; 6947 6948 if (nextvert == -1) 6949 return max; 6950 6951 pListHead = PolFaces[nextvert]; 6952 temp2 = (PF_FACES) PeekList(pListHead, LISTHEAD, 0); 6953 6954 /* if we have visited this face before, then there is an error */ 6955 if (((*(temp2->walked) == -1) && (*(temp2->walked+1) == -1) && 6956 (*(temp2->walked+2) == -1) && (*(temp2->walked+3) == -1)) 6957 || (temp2->nPolSize !=4) || (temp2->seen == last_seen)) 6958 { 6959 6960 if (lastvert == node->edge[1]) 6961 nextvert = node->edge[2]; 6962 else 6963 nextvert = node->edge[1]; 6964 if (nextvert == -1) 6965 return max; 6966 lastvert = nextvert; 6967 /* Last attempt to get the face ... */ 6968 pListHead = PolFaces[nextvert]; 6969 temp2 = (PF_FACES) PeekList(pListHead, LISTHEAD, 0); 6970 if (((*(temp2->walked) == -1) && (*(temp2->walked+1) == -1) && 6971 (*(temp2->walked+2) == -1) && (*(temp2->walked+3) == -1)) 6972 || (temp2->nPolSize !=4) || (temp2->seen == last_seen)) 6973 return max; /* The polygon was not saved with the edge, not 6974 enough room. We will get the walk when we come 6975 to that polygon later. 6976 */ 6977 } 6978 else 6979 { 6980 counter = 0; 6981 flag = TRUE; 6982 temp2->seen = last_seen; 6983 6984 while ((counter < 3) && (flag)) 6985 { 6986 6987 if ( ((*(temp2->pPolygon+counter) == previous_edge1) || 6988 (*(temp2->pPolygon+counter+1) == previous_edge2)) || 6989 ((*(temp2->pPolygon+counter) == previous_edge2) || 6990 (*(temp2->pPolygon+counter+1) == previous_edge1)) ) 6991 counter++; 6992 else 6993 flag = FALSE; 6994 } 6995 } 6996 6997 /* Get the IDs of the next edge */ 6998 left = counter; 6999 north = left+1; 7000 if (left ==3) 7001 north = 0; 7002 if (counter < 3) 7003 { 7004 previous_edge1 = *(temp2->pPolygon + counter + 1); 7005 previous_edge2 = *(temp2->pPolygon + counter); 7006 } 7007 else 7008 { 7009 previous_edge1 = *(temp2->pPolygon + counter); 7010 previous_edge2 = *(temp2->pPolygon); 7011 } 7012 7013 } 7014 7015 } 7016 last_seen++; 7017 return max; 7018 } 7019 7020 /// Mark_Face: 7021 void CustomStripifier::Mark_Face( PF_FACES temp2, int color1, 7022 int color2, int color3, 7023 BOOL end, 7024 int *edge1, int *edge2, 7025 int *face_id, int norms, 7026 int texture) 7027 { 7028 static int last_quad[4]; 7029 register int x,y,z=0; 7030 int saved[2]; 7031 static int output1, output2,last_id; 7032 BOOL cptexture; 7033 7034 /* Are we done with the patch? If so return the last edge that 7035 we will come out on, and that will be the edge that we will 7036 start to extend upon. 7037 */ 7038 7039 cptexture = texture; 7040 if (end) 7041 { 7042 *edge1 = output1; 7043 *edge2 = output2; 7044 *face_id = last_id; 7045 return; 7046 } 7047 7048 last_id = *face_id; 7049 *(temp2->walked) = -1; 7050 *(temp2->walked+1) = -1; 7051 *(temp2->walked+2) = -1; 7052 *(temp2->walked+3) = -1; 7053 added_quad++; 7054 temp2->nPolSize = 1; 7055 7056 if (patch == 0) 7057 { 7058 /* At the first quad in the strip -- save it */ 7059 last_quad[0] = *(temp2->pPolygon); 7060 last_quad[1] = *(temp2->pPolygon+1); 7061 last_quad[2] = *(temp2->pPolygon+2); 7062 last_quad[3] = *(temp2->pPolygon+3); 7063 patch++; 7064 } 7065 else 7066 { 7067 /* Now we have a triangle to output, find the edge in common */ 7068 for (x=0; x < 4 ;x++) 7069 { 7070 for (y=0; y< 4; y++) 7071 { 7072 if (last_quad[x] == *(temp2->pPolygon+y)) 7073 { 7074 saved[z++] = last_quad[x]; 7075 if (z > 2) 7076 { 7077 /* This means that there was a non convex or 7078 an overlapping polygon 7079 */ 7080 z--; 7081 break; 7082 } 7083 } 7084 } 7085 } 7086 7087 if (z != 2) 7088 { 7089 printf("Z is not 2 %d \n",patch); 7090 printf("4 %d %d %d %d %d %d %d\n",*(temp2->pPolygon), 7091 *(temp2->pPolygon+1),*(temp2->pPolygon+2),*(temp2->pPolygon+3), 7092 color1,color2,color3); 7093 printf("%d %d %d %d\n",last_quad[0],last_quad[1], 7094 last_quad[2],last_quad[3]); 7095 exit(1); 7096 } 7097 7098 if (patch == 1) 7099 { 7100 /* First one to output, there was no output edge */ 7101 patch++; 7102 x = Adjacent(saved[0],saved[1],last_quad,4); 7103 y = Adjacent(saved[1],saved[0],last_quad,4); 7104 7105 /* Data might be mixed and we do not have textures 7106 for some of the vertices 7107 */ 7108 if ((texture) && 7109 (((vt[x]) == 0) || 7110 ((vt[y])==0) || 7111 ((vt[saved[1]])==0))) 7112 cptexture = FALSE; 7113 7114 if ((!norms) && (!cptexture)) 7115 { 7116 // fprintf(output_file,"\nt"); 7117 if (orient) /* If we want to preserve normal orientation */ 7118 preserve_strip_orientation(x+1,y+1,saved[1]+1); 7119 7120 // fprintf(output_file," %d %d %d",x+1,y+1,saved[1]+1); 7121 // fprintf(output_file," %d",saved[0]+1); 7122 } 7123 else if ((norms) && (!cptexture)) 7124 { 7125 // fprintf(output_file,"\nt"); 7126 if (orient) /* If we want to preserve normal orientation */ 7127 preserve_strip_orientation_with_normal( 7128 x+1,vn[x] +1, 7129 y+1,vn[y] +1, 7130 saved[1]+1,vn[saved[1]]+1); 7131 7132 /* fprintf(output_file," %d//%d %d//%d %d//%d", 7133 x+1,vn[x] +1, 7134 y+1,vn[y] +1, 7135 saved[1]+1,vn[saved[1]]+1); 7136 fprintf(output_file," %d//%d",saved[0]+1,vn[saved[0]]+1);*/ 7137 } 7138 else if ((cptexture) && (!norms)) 7139 { 7140 // fprintf(output_file,"\nt"); 7141 if (orient) 7142 preserve_strip_orientation_with_texture( 7143 x+1,vt[x] +1, 7144 y+1,vt[y] +1, 7145 saved[1]+1,vt[saved[1]]+1); 7146 7147 /* fprintf(output_file," %d/%d %d/%d %d/%d", 7148 x+1,vt[x] +1, 7149 y+1,vt[y] +1, 7150 saved[1]+1,vt[saved[1]]+1); 7151 7152 fprintf(output_file," %d//%d",saved[0]+1,vt[saved[0]]+1);*/ 7153 } 7154 else 7155 { 7156 // fprintf(output_file,"\nt"); 7157 if (orient) 7158 preserve_strip_orientation_with_texture_and_normal( 7159 x+1,vt[x]+1,vn[x] +1, 7160 y+1,vt[y]+1,vn[y] +1, 7161 saved[1]+1,vt[saved[1]]+1,vn[saved[1]]+1); 7162 7163 /* fprintf(output_file," %d/%d/%d %d/%d/%d %d/%d/%d", 7164 x+1,vt[x]+1,vn[x] +1, 7165 y+1,vt[y]+1,vn[y] +1, 7166 saved[1]+1,vt[saved[1]]+1,vn[saved[1]]+1); 7167 7168 fprintf(output_file," %d/%d/%d", 7169 saved[0]+1,vt[saved[0]]+1,vn[saved[0]]+1);*/ 7170 } 7171 7172 x = Adjacent(saved[0],saved[1],temp2->pPolygon,4); 7173 y = Adjacent(saved[1],saved[0],temp2->pPolygon,4); 7174 7175 /* Data might be mixed and we do not have textures 7176 for some of the vertices 7177 */ 7178 if ((texture) && ( (vt[x] == 0) || (vt[y]==0))) 7179 { 7180 /* if (cptexture) 7181 fprintf(output_file,"\nq");*/ 7182 cptexture = FALSE; 7183 } 7184 if ((!norms) && (!cptexture)) 7185 { 7186 // fprintf(output_file," %d",x+1); 7187 // fprintf(output_file," %d",y+1); 7188 } 7189 else if ((norms) && (!cptexture)) 7190 { 7191 // fprintf(output_file," %d//%d",x+1,vn[x]+1); 7192 // fprintf(output_file," %d//%d",y+1,vn[y]+1); 7193 } 7194 else if ((cptexture) && (!norms)) 7195 { 7196 // fprintf(output_file," %d/%d",x+1,vt[x]+1); 7197 // fprintf(output_file," %d/%d",y+1,vt[y]+1); 7198 } 7199 else 7200 { 7201 // fprintf(output_file," %d/%d/%d",x+1,vt[x]+1,vn[x]+1); 7202 // fprintf(output_file," %d/%d/%d",y+1,vt[y]+1,vn[y]+1); 7203 } 7204 7205 output1 = x; 7206 output2 = y; 7207 } 7208 7209 else 7210 { 7211 x = Adjacent(output2,output1,temp2->pPolygon,4); 7212 y = Adjacent(output1,output2,temp2->pPolygon,4); 7213 /* Data might be mixed and we do not have textures 7214 for some of the vertices */ 7215 if ((texture) && ( ((vt[x]) == 0) || ((vt[y])==0) )) 7216 texture = FALSE; 7217 7218 if ((!norms) && (!texture)) 7219 { 7220 // fprintf(output_file,"\nq %d",x+1); 7221 // fprintf(output_file," %d",y+1); 7222 } 7223 else if ((norms) && (!texture)) 7224 { 7225 // fprintf(output_file,"\nq %d//%d",x+1,vn[x]+1); 7226 // fprintf(output_file," %d//%d" ,y+1,vn[y]+1); 7227 } 7228 else if ((texture) && (!norms)) 7229 { 7230 // fprintf(output_file,"\nq %d/%d",x+1,vt[x]+1); 7231 // fprintf(output_file," %d/%d",y+1,vt[y]+1); 7232 } 7233 else 7234 { 7235 // fprintf(output_file,"\nq %d/%d/%d",x+1,vt[x]+1,vn[x]+1); 7236 // fprintf(output_file," %d/%d/%d",y+1,vt[y]+1,vn[y]+1); 7237 } 7238 7239 output1 = x; 7240 output2 = y; 7241 } 7242 7243 last_quad[0] = *(temp2->pPolygon); 7244 last_quad[1] = *(temp2->pPolygon+1); 7245 last_quad[2] = *(temp2->pPolygon+2); 7246 last_quad[3] = *(temp2->pPolygon+3); 7247 } 7248 } 7249 7250 /// Assign_Walk: 7251 void CustomStripifier::Assign_Walk( int lastvert, PF_FACES temp2, 7252 int front_walk, int y, 7253 int back_walk) 7254 { 7255 /* Go back and do the walk again, but this time save the lengths inside 7256 the data structure. 7257 y was the starting edge number for the front_walk length 7258 back_walk is the length of the walk along the opposite edge 7259 */ 7260 int previous_edge1, previous_edge2; 7261 register int walk = 0,nextvert,numverts,counter; 7262 BOOL flag; 7263 F_EDGES *node; 7264 ListHead *pListHead; 7265 static int seen = 0; 7266 static BOOL first = TRUE; 7267 BOOL wrap = FALSE, set = FALSE; 7268 7269 7270 /* In the "Fast_Reset" resetting will be true */ 7271 if ((resetting) && (first)) 7272 { 7273 seen = 0; 7274 first = FALSE; 7275 } 7276 7277 seen++; 7278 7279 /* Had a band who could be a cycle */ 7280 if (front_walk == back_walk) 7281 wrap = TRUE; 7282 7283 /* Find the edge that we are currently on */ 7284 if (y != 3) 7285 { 7286 previous_edge1 = *(temp2->pPolygon +y); 7287 previous_edge2 = *(temp2->pPolygon + y + 1); 7288 } 7289 else 7290 { 7291 previous_edge1 = *(temp2->pPolygon +y); 7292 previous_edge2 = *(temp2->pPolygon); 7293 } 7294 7295 /* Assign the lengths */ 7296 if (y < 2) 7297 { 7298 *(temp2->walked+y) = front_walk--; 7299 *(temp2->walked+y+2) = back_walk++; 7300 } 7301 else 7302 { 7303 *(temp2->walked+y) = front_walk--; 7304 *(temp2->walked+y-2) = back_walk++; 7305 } 7306 7307 /*Find the adjacent face to this edge */ 7308 node = *(temp2->VertandId+y); 7309 7310 if (node->edge[2] != lastvert) 7311 nextvert = node->edge[2]; 7312 else 7313 nextvert = node->edge[1]; 7314 7315 temp2->seen3 = seen; 7316 7317 /* Keep walking in this direction until we cannot do so */ 7318 while ((nextvert != lastvert) && (nextvert != -1) && (front_walk >= 0)) 7319 { 7320 walk++; 7321 pListHead = PolFaces[nextvert]; 7322 7323 temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0); 7324 numverts = temp2->nPolSize; 7325 if ((numverts != 4)) 7326 { 7327 nextvert = -1; 7328 /* Don't include this face in the walk */ 7329 walk--; 7330 } 7331 else 7332 { 7333 /* Find edge that is not adjacent to the previous one */ 7334 counter = 0; 7335 flag = TRUE; 7336 while ((counter < 3) && (flag)) 7337 { 7338 if ( ((*(temp2->pPolygon+counter) == previous_edge1) || 7339 (*(temp2->pPolygon+counter+1) == previous_edge2)) || 7340 ((*(temp2->pPolygon+counter) == previous_edge2) || 7341 (*(temp2->pPolygon+counter+1) == previous_edge1)) ) 7342 counter++; 7343 else 7344 flag = FALSE; 7345 } 7346 /* Get the IDs of the next edge */ 7347 if (counter < 3) 7348 { 7349 previous_edge1 = *(temp2->pPolygon + counter); 7350 previous_edge2 = *(temp2->pPolygon + counter + 1); 7351 } 7352 else 7353 { 7354 previous_edge1 = *(temp2->pPolygon + counter); 7355 previous_edge2 = *(temp2->pPolygon); 7356 } 7357 7358 7359 /* Put in the walk lengths */ 7360 if (counter < 2) 7361 { 7362 if (((*(temp2->walked + counter) >= 0) 7363 || (*(temp2->walked +counter + 2) >= 0))) 7364 { 7365 if ((resetting == FALSE) && ((temp2->seen3) != (seen-1))) 7366 { 7367 /* If there are more than 2 polygons adjacent 7368 to an edge then we can be trying to assign more than 7369 once. We will save the smaller one 7370 */ 7371 temp2->seen3 = seen; 7372 if ( (*(temp2->walked+counter) <= front_walk) && 7373 (*(temp2->walked+counter+2) <= back_walk) ) 7374 return; 7375 if (*(temp2->walked+counter) > front_walk) 7376 *(temp2->walked+counter) = front_walk--; 7377 else 7378 front_walk--; 7379 if (*(temp2->walked+counter+2) > back_walk) 7380 *(temp2->walked+counter+2) = back_walk++; 7381 else 7382 back_walk++; 7383 } 7384 else if (resetting == FALSE) 7385 { 7386 /* if there was a cycle then all lengths are the same */ 7387 walk--; 7388 back_walk--; 7389 front_walk++; 7390 temp2->seen3 = seen; 7391 *(temp2->walked+counter) = front_walk--; 7392 *(temp2->walked+counter+2) = back_walk++; 7393 } 7394 else if (((temp2->seen3 == (seen-1)) 7395 && (wrap) && (walk == 1)) || (set)) 7396 { 7397 /* if there was a cycle then all lengths are the same */ 7398 set = TRUE; 7399 walk--; 7400 back_walk--; 7401 front_walk++; 7402 temp2->seen3 = seen; 7403 *(temp2->walked+counter) = front_walk--; 7404 *(temp2->walked+counter+2) = back_walk++; 7405 } 7406 else 7407 { 7408 temp2->seen3 = seen; 7409 *(temp2->walked+counter) = front_walk--; 7410 *(temp2->walked+counter+2) = back_walk++; 7411 } 7412 } /* if was > 0 */ 7413 else 7414 { 7415 temp2->seen3 = seen; 7416 *(temp2->walked+counter) = front_walk--; 7417 *(temp2->walked+counter+2) = back_walk++; 7418 } 7419 } 7420 7421 else 7422 { 7423 if (((*(temp2->walked + counter) >= 0 ) 7424 || (*(temp2->walked +counter - 2) >= 0)) ) 7425 { 7426 if ((temp2->seen3 != (seen-1)) && (resetting == FALSE)) 7427 { 7428 /* If there are more than 2 polygons adjacent 7429 to an edge then we can be trying to assign more than 7430 once. We will save the smaller one 7431 */ 7432 temp2->seen3 = seen; 7433 if ( (*(temp2->walked+counter) <= front_walk) && 7434 (*(temp2->walked+counter-2) <= back_walk) ) 7435 return; 7436 if (*(temp2->walked+counter) > front_walk) 7437 *(temp2->walked+counter) = front_walk--; 7438 else 7439 front_walk--; 7440 if (*(temp2->walked+counter-2) > back_walk) 7441 *(temp2->walked+counter-2) = back_walk++; 7442 else 7443 back_walk++; 7444 } 7445 else if (resetting == FALSE) 7446 { 7447 walk--; 7448 back_walk--; 7449 front_walk++; 7450 temp2->seen3 = seen; 7451 *(temp2->walked+counter) = front_walk--; 7452 *(temp2->walked+counter-2) = back_walk++; 7453 } 7454 else if (((temp2->seen3 == (seen-1)) && (walk == 1) && (wrap)) 7455 || (set)) 7456 { 7457 /* if there was a cycle then all lengths are the same */ 7458 set = TRUE; 7459 walk--; 7460 back_walk--; 7461 front_walk++; 7462 temp2->seen3 = seen; 7463 *(temp2->walked+counter) = front_walk--; 7464 *(temp2->walked+counter-2) = back_walk++; 7465 } 7466 else 7467 { 7468 temp2->seen3 = seen; 7469 *(temp2->walked+counter) = front_walk--; 7470 *(temp2->walked+counter-2) = back_walk++; 7471 } 7472 } 7473 else 7474 { 7475 temp2->seen3 = seen; 7476 *(temp2->walked+counter) = front_walk--; 7477 *(temp2->walked+counter-2) = back_walk++; 7478 } 7479 7480 } 7481 if (nextvert != -1) 7482 { 7483 node = *(temp2->VertandId + counter); 7484 if (node->edge[1] == nextvert) 7485 nextvert = node->edge[2]; 7486 else 7487 nextvert = node->edge[1]; 7488 } 7489 7490 } 7491 } 7492 if ((EVEN(seen)) ) 7493 seen+=2; 7494 } 7495 7496 /// Fast_Reset: 7497 void CustomStripifier::Fast_Reset(int x) 7498 { 7499 register int y,numverts; 7500 register int front_walk, back_walk; 7501 ListHead *pListHead; 7502 PF_FACES temp = NULL; 7503 7504 pListHead = PolFaces[x]; 7505 temp = (PF_FACES) PeekList(pListHead,LISTHEAD,0); 7506 numverts = temp->nPolSize; 7507 7508 front_walk = 0; 7509 back_walk = 0; 7510 resetting = TRUE; 7511 7512 /* we are doing this only for quads */ 7513 if (numverts == 4) 7514 { 7515 /* for each face not seen yet, do North and South together 7516 and East and West together 7517 */ 7518 for (y=0;y<2;y++) 7519 { 7520 /* Check if the opposite sides were seen already */ 7521 /* Find walk for the first edge */ 7522 front_walk = Calculate_Walks(x,y,temp); 7523 /* Find walk in the opposite direction */ 7524 back_walk = Calculate_Walks(x,y+2,temp); 7525 /* Now put into the data structure the numbers that 7526 we have found 7527 */ 7528 Assign_Walk(x,temp,front_walk,y,back_walk); 7529 Assign_Walk(x,temp,back_walk,y+2,front_walk); 7530 } 7531 } 7532 resetting = FALSE; 7533 } 7534 7535 /// Reset_Max: 7536 void CustomStripifier::Reset_Max( PF_FACES temp2,int face_id, 7537 int north,int last_north, 7538 int orientation,int last_left, 7539 int color1, 7540 int color2,int color3, 7541 BOOL start) 7542 { 7543 int previous_edge1,previous_edge2; 7544 F_EDGES *node; 7545 ListHead *pListHead; 7546 int f,t,nextvert,counter; 7547 BOOL flag; 7548 7549 7550 /* Reset walks on faces, since we just found a patch */ 7551 if (orientation !=3) 7552 { 7553 previous_edge1 = *(temp2->pPolygon + orientation+1); 7554 previous_edge2 = *(temp2->pPolygon + orientation ); 7555 } 7556 else 7557 { 7558 previous_edge1 = *(temp2->pPolygon + orientation ); 7559 previous_edge2 = *(temp2->pPolygon); 7560 } 7561 7562 /* only if we are going left, otherwise there will be -1 there */ 7563 /*Find the adjacent face to this edge */ 7564 7565 for (t = 0; t <=3 ; t++) 7566 { 7567 node = *(temp2->VertandId+t); 7568 7569 if (face_id == node->edge[1]) 7570 f = node->edge[2]; 7571 else 7572 f = node->edge[1]; 7573 7574 if (f != -1) 7575 Fast_Reset(f); 7576 } 7577 7578 node = *(temp2->VertandId+orientation); 7579 if (face_id == node->edge[1]) 7580 nextvert = node->edge[2]; 7581 else 7582 nextvert = node->edge[1]; 7583 7584 while ((last_left--) > 1) 7585 { 7586 7587 if (start) 7588 Reset_Max(temp2,face_id,orientation,last_left,north,last_north, 7589 color1,color2,color3,FALSE); 7590 7591 face_id = nextvert; 7592 pListHead = PolFaces[nextvert]; 7593 temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0); 7594 if ((temp2->nPolSize != 4) && (temp2->nPolSize != 1)) 7595 { 7596 /* There is more than 2 polygons on the edge, and we could have 7597 gotten the wrong one 7598 */ 7599 if (nextvert != node->edge[1]) 7600 nextvert = node->edge[1]; 7601 else 7602 nextvert = node->edge[2]; 7603 pListHead = PolFaces[nextvert]; 7604 temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0); 7605 node = *(temp2->VertandId+orientation); 7606 } 7607 7608 7609 if (!start) 7610 { 7611 for (t = 0; t <=3 ; t++) 7612 { 7613 node = *(temp2->VertandId+t); 7614 7615 if (face_id == node->edge[1]) 7616 f = node->edge[2]; 7617 else 7618 f = node->edge[1]; 7619 7620 if (f != -1) 7621 Fast_Reset(f); 7622 } 7623 } 7624 7625 7626 counter = 0; 7627 flag = TRUE; 7628 while ((counter < 3) && (flag)) 7629 { 7630 if ( ((*(temp2->pPolygon+counter) == previous_edge1) || 7631 (*(temp2->pPolygon+counter+1) == previous_edge2)) || 7632 ((*(temp2->pPolygon+counter) == previous_edge2) || 7633 (*(temp2->pPolygon+counter+1) == previous_edge1)) ) 7634 counter++; 7635 else 7636 flag = FALSE; 7637 } 7638 7639 /* Get the IDs of the next edge */ 7640 if (counter < 3) 7641 { 7642 previous_edge1 = *(temp2->pPolygon + counter+1); 7643 previous_edge2 = *(temp2->pPolygon + counter); 7644 } 7645 else 7646 { 7647 previous_edge1 = *(temp2->pPolygon + counter); 7648 previous_edge2 = *(temp2->pPolygon); 7649 } 7650 orientation = counter; 7651 7652 node = *(temp2->VertandId + counter); 7653 if (node->edge[1] == nextvert) 7654 nextvert = node->edge[2]; 7655 else 7656 nextvert = node->edge[1]; 7657 7658 if (!reversed) 7659 { 7660 if (counter != 3) 7661 north = counter +1; 7662 else 7663 north = 0; 7664 } 7665 else 7666 { 7667 if (counter != 0) 7668 north = counter -1; 7669 else 7670 north = 3; 7671 7672 } 7673 } 7674 if (start) 7675 Reset_Max(temp2,face_id,orientation,last_left,north,last_north, 7676 color1,color2,color3,FALSE); 7677 else if (nextvert != -1) 7678 Fast_Reset(nextvert); 7679 7680 } 7681 7682 /// Peel_Max 7683 int CustomStripifier::Peel_Max( PF_FACES temp2,int face_id, 7684 int north,int last_north, 7685 int orientation,int last_left, 7686 int color1, 7687 int color2,int color3, 7688 BOOL start, int *swaps_added, 7689 int norms, int texture) 7690 { 7691 int end1,end2,last_id,s=0,walk = 0; 7692 int previous_edge1,previous_edge2; 7693 int static last_seen = 1000; 7694 F_EDGES *node; 7695 ListHead *pListHead; 7696 int nextvert,numverts,counter,dummy,tris=0; 7697 BOOL flag; 7698 7699 /* Peel the patch from the model. 7700 We will try and extend off the end of each strip in the patch. We will return 7701 the number of triangles completed by this extension only, and the number of 7702 swaps in the extension only. 7703 */ 7704 patch = 0; 7705 7706 if (orientation !=3) 7707 { 7708 previous_edge1 = *(temp2->pPolygon + orientation+1); 7709 previous_edge2 = *(temp2->pPolygon + orientation ); 7710 } 7711 else 7712 { 7713 previous_edge1 = *(temp2->pPolygon + orientation ); 7714 previous_edge2 = *(temp2->pPolygon); 7715 } 7716 7717 7718 walk = *(temp2->walked + orientation); 7719 7720 /* only if we are going left, otherwise there will be -1 there */ 7721 if ((start) && ((walk+1) < last_left)) 7722 { 7723 printf("There is an error in the left %d %d\n",walk,last_left); 7724 exit(0); 7725 } 7726 7727 /* Find the adjacent face to this edge */ 7728 node = *(temp2->VertandId+orientation); 7729 if (face_id == node->edge[1]) 7730 nextvert = node->edge[2]; 7731 else 7732 nextvert = node->edge[1]; 7733 temp2->seen = last_seen; 7734 7735 7736 while ((last_left--) > 1) 7737 { 7738 if (start) 7739 tris += Peel_Max(temp2,face_id,orientation,last_left,north,last_north, 7740 color1,color2,color3,FALSE,swaps_added, 7741 norms,texture); 7742 else 7743 Mark_Face(temp2,color1,color2,color3,FALSE, 7744 &dummy,&dummy,&face_id,norms,texture); 7745 7746 7747 pListHead = PolFaces[nextvert]; 7748 temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0); 7749 numverts = temp2->nPolSize; 7750 7751 if ((numverts != 4) || (temp2->seen == last_seen) 7752 || (nextvert == -1)) 7753 { 7754 7755 /* There is more than 2 polygons on the edge, and we could have 7756 gotten the wrong one 7757 */ 7758 if (nextvert != node->edge[1]) 7759 nextvert = node->edge[1]; 7760 else 7761 nextvert = node->edge[2]; 7762 pListHead = PolFaces[nextvert]; 7763 temp2 = (PF_FACES) PeekList(pListHead,LISTHEAD,0); 7764 numverts = temp2->nPolSize; 7765 if ((numverts != 4) || (temp2->seen == last_seen) ) 7766 { 7767 printf("Peel 2 %d\n",numverts); 7768 exit(1); 7769 } 7770 } 7771 7772 face_id = nextvert; 7773 temp2->seen = last_seen; 7774 7775 counter = 0; 7776 flag = TRUE; 7777 while ((counter < 3) && (flag)) 7778 { 7779 if ( ((*(temp2->pPolygon+counter) == previous_edge1) || 7780 (*(temp2->pPolygon+counter+1) == previous_edge2)) || 7781 ((*(temp2->pPolygon+counter) == previous_edge2) || 7782 (*(temp2->pPolygon+counter+1) == previous_edge1)) ) 7783 counter++; 7784 else 7785 flag = FALSE; 7786 } 7787 /* Get the IDs of the next edge */ 7788 if (counter < 3) 7789 { 7790 previous_edge1 = *(temp2->pPolygon + counter+1); 7791 previous_edge2 = *(temp2->pPolygon + counter); 7792 } 7793 else 7794 { 7795 previous_edge1 = *(temp2->pPolygon + counter); 7796 previous_edge2 = *(temp2->pPolygon); 7797 } 7798 orientation = counter; 7799 7800 node = *(temp2->VertandId + counter); 7801 if (node->edge[1] == nextvert) 7802 nextvert = node->edge[2]; 7803 else 7804 nextvert = node->edge[1]; 7805 7806 if (!reversed) 7807 { 7808 if (counter != 3) 7809 north = counter +1; 7810 else 7811 north = 0; 7812 } 7813 else 7814 { 7815 if (counter != 0) 7816 north = counter -1; 7817 else 7818 north = 3; 7819 } 7820 } 7821 7822 if (start) 7823 tris += Peel_Max(temp2,face_id,orientation,last_left,north,last_north, 7824 color1,color2,color3,FALSE,swaps_added, 7825 norms,texture); 7826 else 7827 Mark_Face(temp2,color1,color2,color3,FALSE, 7828 &dummy,&dummy,&face_id,norms,texture);/* do the last face */ 7829 7830 last_seen++; 7831 7832 /* Get the edge that we came out on the last strip of the patch */ 7833 Mark_Face(NULL,0,0,0,TRUE,&end1,&end2,&last_id,norms,texture); 7834 tris += Extend_Face(last_id,end1,end2,&s,color1,color2,color3, 7835 vn,norms,vt,texture); 7836 *swaps_added = *swaps_added + s; 7837 return tris; 7838 } 7839 7840 /// Find_Bands: 7841 void CustomStripifier::Find_Bands(int numfaces, int *swaps, int *bands, 7842 int *cost, int *tri, 7843 int norms, int *vert_norms, 7844 int texture, int *vert_texture) 7845 { 7846 7847 register int x,y,max1,max2,numverts,face_id,flag,maximum = 25; 7848 ListHead *pListHead; 7849 PF_FACES temp = NULL; 7850 int color1 = 0, color2 = 100, color3 = 255; 7851 int smaller; 7852 int north_length1,last_north,left_length1,last_left,north_length2,left_length2; 7853 int total_tri = 0, total_swaps = 0,last_id; 7854 int end1, end2,s=0; 7855 register int cutoff = 20; 7856 7857 /* Code that will find the patches. "Cutoff" will be 7858 the cutoff of the area of the patches that we will be allowing. After 7859 we reach this cutoff length, then we will run the local algorithm on the 7860 remaining faces. 7861 */ 7862 7863 /* For each faces that is left find the largest possible band that we can 7864 have with the remaining faces. Note that we will only be finding patches 7865 consisting of quads. 7866 */ 7867 7868 vn = vert_norms; 7869 vt = vert_texture; 7870 y=1; 7871 *bands = 0; 7872 7873 while ((maximum >= cutoff)) 7874 { 7875 y++; 7876 maximum = -1; 7877 for (x=0; x<numfaces; x++) 7878 { 7879 7880 /* Used to produce the triangle strips */ 7881 7882 /* for each face, get the face */ 7883 pListHead = PolFaces[x]; 7884 temp = (PF_FACES) PeekList(pListHead,LISTHEAD,0); 7885 numverts = temp->nPolSize; 7886 7887 /* we are doing this only for quads */ 7888 if (numverts == 4) 7889 { 7890 /* We want a face that is has not been used yet, 7891 since we know that that face must be part of 7892 a band. Then we will find the largest band that 7893 the face may be contained in 7894 */ 7895 7896 /* Doing the north and the left */ 7897 if ((*(temp->walked) != -1) && (*(temp->walked+3) != -1)) 7898 max1 = Find_Max(temp,x,0,3,&north_length1,&left_length1); 7899 if ((*(temp->walked+1) != -1) && (*(temp->walked+2) != -1)) 7900 max2 = Find_Max(temp,x,2,1,&north_length2,&left_length2); 7901 if ((max1 != (north_length1 * left_length1)) || 7902 (max2 != (north_length2 * left_length2))) 7903 { 7904 printf("Max1 %d, %d %d Max2 %d, %d %d\n", 7905 max1,north_length1,left_length1,max2, 7906 north_length2,left_length2); 7907 exit(0); 7908 } 7909 7910 7911 if ((max1 > max2) && (max1 > maximum)) 7912 { 7913 maximum = max1; 7914 face_id = x; 7915 flag = 1; 7916 last_north = north_length1; 7917 last_left = left_length1; 7918 /* so we know we saved max1 */ 7919 } 7920 else if ((max2 > maximum) ) 7921 { 7922 maximum = max2; 7923 face_id = x; 7924 flag = 2; 7925 last_north = north_length2; 7926 last_left = left_length2; 7927 /* so we know we saved max2 */ 7928 } 7929 } 7930 } 7931 if ((maximum < cutoff) && (*bands == 0)) 7932 return; 7933 pListHead = PolFaces[face_id]; 7934 temp = (PF_FACES) PeekList(pListHead,LISTHEAD,0); 7935 /* There are no patches that we found in this pass */ 7936 if (maximum == -1) 7937 break; 7938 /*printf("The maximum is face %d area %d: lengths %d %d\n",face_id,maximum,last_north,last_left);*/ 7939 7940 if (last_north > last_left) 7941 { 7942 smaller = last_left; 7943 } 7944 else 7945 { 7946 smaller = last_north; 7947 } 7948 7949 7950 if (flag == 1) 7951 { 7952 if (last_north > last_left) /* go north sequentially */ 7953 { 7954 total_tri += Peel_Max(temp,face_id,0,last_north,3,last_left, 7955 color1,color2,color3,TRUE, 7956 &s,norms,texture); 7957 Reset_Max(temp,face_id,0,last_north,3,last_left, 7958 color1,color2,color3,TRUE); 7959 total_swaps += s; 7960 } 7961 else 7962 { 7963 reversed = TRUE; 7964 total_tri += Peel_Max(temp,face_id,3,last_left,0,last_north, 7965 color1,color2,color3,TRUE, 7966 &s,norms,texture); 7967 Reset_Max(temp,face_id,3,last_left,0,last_north, 7968 color1,color2,color3,TRUE); 7969 reversed = FALSE; 7970 total_swaps += s; 7971 } 7972 7973 7974 /* Get the edge that we came out on the last strip of the patch */ 7975 Mark_Face(NULL,0,0,0,TRUE,&end1,&end2,&last_id,norms,texture); 7976 total_tri += Extend_Face(last_id,end1,end2,&s, 7977 color1,color2,color3,vn,norms,vt,texture); 7978 total_swaps += s; 7979 } 7980 else 7981 { 7982 if (last_north > last_left) 7983 { 7984 total_tri += Peel_Max(temp,face_id,2,last_north,1,last_left, 7985 color1,color2,color3,TRUE, 7986 &s,norms,texture); 7987 Reset_Max(temp,face_id,2,last_north,1,last_left, 7988 color1,color2,color3,TRUE); 7989 total_swaps += s; 7990 } 7991 else 7992 { 7993 reversed = TRUE; 7994 total_tri += Peel_Max(temp,face_id,1,last_left,2,last_north, 7995 color1,color2,color3,TRUE, 7996 &s,norms,texture); 7997 Reset_Max(temp,face_id,1,last_left,2,last_north, 7998 color1,color2,color3,TRUE); 7999 reversed = FALSE; 8000 total_swaps += s; 8001 } 8002 8003 /* Get the edge that we came out on on the patch */ 8004 Mark_Face(NULL,0,0,0,TRUE,&end1,&end2,&last_id,norms,texture); 8005 total_tri += Extend_Face(last_id,end1,end2,&s, 8006 color1,color2,color3,vn,norms,vt,texture); 8007 total_swaps += s; 8008 } 8009 8010 /* Now compute the cost of transmitting this band, is equal to 8011 going across the larger portion sequentially, 8012 and swapping 3 times per other dimension 8013 */ 8014 8015 total_tri += (maximum * 2); 8016 *bands = *bands + smaller; 8017 8018 } 8019 8020 /*printf("We transmitted %d triangles,using %d swaps and %d strips\n",total_tri, 8021 total_swaps, *bands); 8022 printf("COST %d\n",total_tri + total_swaps + *bands + *bands);*/ 8023 *cost = total_tri + total_swaps + *bands + *bands; 8024 *tri = total_tri; 8025 added_quad = added_quad * 4; 8026 *swaps = total_swaps; 8027 } 8028 8029 /// Save_Rest: 8030 void CustomStripifier::Save_Rest(int *numfaces) 8031 { 8032 /* Put the polygons that are left into a data structure so that we can run the 8033 stripping code on it. 8034 */ 8035 register int x,y=0,numverts; 8036 ListHead *pListHead; 8037 PF_FACES temp=NULL; 8038 8039 for (x=0; x<*numfaces; x++) 8040 { 8041 /* for each face, get the face */ 8042 pListHead = PolFaces[x]; 8043 temp = (PF_FACES) PeekList(pListHead,LISTHEAD,0); 8044 numverts = temp->nPolSize; 8045 /* If we did not do the face before add it to data structure with new 8046 face id number 8047 */ 8048 if (numverts != 1) 8049 { 8050 CopyFace(temp->pPolygon,numverts,y+1,temp->pNorms); 8051 y++; 8052 } 8053 /* Used it, so remove it */ 8054 else 8055 RemoveList(pListHead,(PLISTINFO) temp); 8056 8057 } 8058 *numfaces = y; 8059 } 8060 8061 /// Save_Walks: 8062 void CustomStripifier::Save_Walks(int numfaces) 8063 { 8064 int x,y,numverts; 8065 int front_walk, back_walk; 8066 ListHead *pListHead; 8067 PF_FACES temp = NULL; 8068 8069 for (x=0; x<numfaces; x++) 8070 { 8071 /* for each face, get the face */ 8072 pListHead = PolFaces[x]; 8073 temp = (PF_FACES) PeekList(pListHead,LISTHEAD,0); 8074 numverts = temp->nPolSize; 8075 front_walk = 0; 8076 back_walk = 0; 8077 8078 /* we are finding patches only for quads */ 8079 if (numverts == 4) 8080 { 8081 /* for each face not seen yet, do North and South together 8082 and East and West together 8083 */ 8084 for (y=0;y<2;y++) 8085 { 8086 /* Check if the opposite sides were seen already from another 8087 starting face, if they were then there is no need to do 8088 the walk again 8089 */ 8090 8091 if ( ((*(temp->walked+y) == -1) && 8092 (*(temp->walked+y+2) == -1) )) 8093 { 8094 /* Find walk for the first edge */ 8095 front_walk = Calculate_Walks(x,y,temp); 8096 /* Find walk in the opposite direction */ 8097 back_walk = Calculate_Walks(x,y+2,temp); 8098 /* Now put into the data structure the numbers that 8099 we have found 8100 */ 8101 Assign_Walk(x,temp,front_walk,y,back_walk); 8102 Assign_Walk(x,temp,back_walk,y+2,front_walk); 8103 } 8104 } 8105 } 8106 } 8107 } 8108 8109 /*/// OpenOutputFile: 8110 FILE * CustomStripifier::OpenOutputFile(char *fname) 8111 { 8112 FILE *bands; 8113 int flength = 0; 8114 char *newfname; 8115 8116 // get the length of the fname. 8117 flength = int(strlen(fname)); 8118 8119 // make a new string in memory one larger than fname. 8120 newfname = (char *) malloc(sizeof(char) * (flength+2)); 8121 8122 // Copy the fname to the newfname. 8123 strcpy(newfname,fname); 8124 8125 // Add an 'f' to the end of it. 8126 newfname[flength] = 'f'; 8127 newfname[flength+1] = '\0'; 8128 8129 printf(" Output file : %s\n",newfname); 8130 8131 // File that will contain the triangle strip data 8132 bands = fopen(newfname,"w"); 8133 // fprintf(bands,"#%s: a triangle strip representation created by STRIPE.\n#This is a .objf file\n#by Francine Evans\n",fname); 8134 8135 return bands; 8136 }*/ 8137 8138 /// AllocateStruct: Reserves memory for structures. 8139 void CustomStripifier::AllocateStruct(int num_faces, 8140 int num_vert, 8141 int num_nvert, 8142 int num_texture) 8143 { 8144 /* Allocate structures for the information */ 8145 Start_Face_Struct(num_faces); 8146 Start_Vertex_Struct(num_vert); 8147 8148 vertices = (struct vert_struct *) 8149 malloc (sizeof (struct vert_struct) * num_vert); 8150 8151 if (num_nvert > 0) 8152 { 8153 nvertices = (struct vert_struct *) 8154 malloc (sizeof (struct vert_struct) * num_nvert); 8155 8156 vert_norms = (int *) 8157 malloc (sizeof (int) * num_vert); 8158 8159 /* Initialize entries to zero, in case there are 2 hits 8160 to the same vertex we will know it - used for determining 8161 the normal difference 8162 */ 8163 init_vert_norms(num_vert); 8164 } 8165 else 8166 nvertices = NULL; 8167 8168 if (num_texture > 0) 8169 { 8170 vert_texture = (int *) malloc (sizeof(int) * num_vert); 8171 8172 init_vert_texture(num_vert); 8173 } 8174 8175 /* Set up the temporary 'p' pointers */ 8176 pvertices = vertices; 8177 pnvertices = nvertices; 8178 8179 } 8180 8181 /// miReadFile: Loads the object in memory. 8182 void CustomStripifier::miReadFile(char *fname, char *file_open, Geometry::SubMesh *geoSubMesh) 8183 { 8184 int face_id = 0; 8185 int vert_count; 8186 int num_vert=0; 8187 int vertex; 8188 int temp[MAX1]; 8189 int i = 0; 8190 int num_buffers = 0; 8191 Geometry::VertexBuffer *geoVertexBuffer = geoSubMesh->mVertexBuffer; 8192 8193 /** 8194 * Faces 8195 */ 8196 for(unsigned int j = 0; j < geoSubMesh->mIndexCount; j = j + 3) 8197 { 8198 8199 // loop on the number of vertices in this line of face data. 8200 vert_count = 0; 8201 8202 // 3 vertices of a triangle. 8203 for(int k = 0;k < 3;k++) 8204 { 8205 // no nvertices. 8206 vertex = geoSubMesh->mIndex[j+k]; 8207 temp[vert_count] = vertex; 8208 8209 vert_count++; 8210 8211 add_vert_id(vertex,vert_count); 8212 } 8213 8214 // Increment the number of faces. 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. 1296 void 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 { 8215 1311 face_id++; 8216 1312 8217 // Add a new face to the list. 8218 AddNewFace(ids,vert_count,face_id,norms); 8219 8220 } 8221 8222 // Done reading in all the information into data structures. 8223 num_faces = face_id; 8224 8225 printf(" Done.\n\n"); 8226 8227 free(vertices); 8228 free(nvertices); 8229 8230 } 8231 8232 /// stripify: Make triangle strips for a given mesh. 8233 int CustomStripifier::stripify (char *fname, 8234 Geometry::Mesh *geoMesh) 8235 { 8236 BOOL quads = FALSE; 8237 BOOL oddStrip; 8238 // FILE *bands; 8239 char *file_open; 8240 int i; 8241 unsigned int j; 8242 int f; 8243 int t; 8244 int tr; 8245 int num_buffers = 0; 8246 int cost = 0; 8247 int num_vert = 0; 8248 int num_faces = 0; 8249 int num_nvert = 0; 8250 int num_texture = 0; 8251 int num_tris = 0; 8252 int totalStripIndices; 8253 8254 Geometry::SubMesh* geoSubMesh; 8255 mi_vector_tipo v_indices; 8256 8257 /* Scan the file once to find out the number of vertices, 8258 vertice normals, and faces so we can set up some memory structures.*/ 8259 f = ASCII; 8260 file_open = "w+"; 8261 tr = 1; 8262 t = 3; 8263 orient = 1; 8264 8265 // Proces OK. 8266 mError = 0; 8267 8268 8269 // Progress bar. 8270 float percent; 8271 percent = float(100.0 / (geoMesh->mSubMeshCount * 10.0)); 8272 //-------------------------- 8273 8274 // For all submeshes. 8275 for(unsigned int k = 0; k < geoMesh->mSubMeshCount; k++) 8276 { 8277 // Leaves submesh doesn't stripify. 8278 if (mSubMeshLeaves != k) 8279 { 8280 v_indices.clear(); 8281 mi_vector.clear(); 8282 mi_vector.push_back(v_indices); 8283 num_tiras = 0; 8284 8285 // Actual submesh. 8286 geoSubMesh = &geoMesh->mSubMesh[k]; 8287 8288 // Mesh type. 8289 geoSubMesh->mType = GEO_TRIANGLE_STRIPS; 8290 8291 num_vert = int(geoSubMesh->mVertexBuffer->mVertexCount); 8292 num_faces = int(geoSubMesh->mIndexCount / 3); 8293 num_tris = num_faces; 8294 8295 // Debug. 8296 //vt = new int[num_vert]; 8297 //vn = new int[num_vert]; 8298 text = 0; 8299 norm = 0; 8300 8301 // 2006-02-14. 8302 // Updtate progress bar. 8303 if (mUPB) 8304 { 8305 mUPB(percent); 8306 } 8307 //----------------------- 8308 8309 // Open the output file. 8310 // bands = OpenOutputFile(fname); 8311 8312 // 2006-02-14. 8313 // Updtate progress bar. 8314 if (mUPB) 8315 { 8316 mUPB(percent); 8317 } 8318 //----------------------- 8319 8320 // Reserve memory for the mesh structure. 8321 AllocateStruct(num_faces,num_vert,num_nvert,num_texture); 8322 8323 // 2006-02-14. 8324 // Updtate progress bar. 8325 if (mUPB) 8326 { 8327 mUPB(percent); 8328 } 8329 //----------------------- 8330 8331 // Load the object into memory. 8332 miReadFile(fname,file_open,geoSubMesh); 8333 8334 // 2006-02-14. 8335 // Updtate progress bar. 8336 if (mUPB) 8337 { 8338 mUPB(percent); 8339 } 8340 //----------------------- 8341 8342 Start_Edge_Struct(num_vert); 8343 Find_Adjacencies(num_faces); 8344 8345 // 2006-02-14. 8346 // Updtate progress bar. 8347 if (mUPB) 8348 { 8349 mUPB(percent); 8350 } 8351 //----------------------- 8352 8353 // If the mesh is not manifold. 8354 if (mError) 8355 { 8356 return 0; 8357 } 8358 8359 // Initialize it. 8360 face_array = NULL; 8361 Init_Table_SGI(num_faces); 8362 8363 // 2006-02-14. 8364 // Updtate progress bar. 8365 if (mUPB) 8366 { 8367 mUPB(percent); 8368 } 8369 //----------------------- 8370 8371 // Build it. 8372 Build_SGI_Table(num_faces); 8373 InitStripTable(); 8374 8375 // 2006-02-14. 8376 // Updtate progress bar. 8377 if (mUPB) 8378 { 8379 mUPB(percent); 8380 } 8381 //----------------------- 8382 8383 SGI_Strip(num_faces,t,tr); 8384 8385 // 2006-02-14. 8386 // Updtate progress bar. 8387 if (mUPB) 8388 { 8389 mUPB(percent); 8390 } 8391 //----------------------- 8392 8393 // Get the total cost. 8394 Output_TriEx(-1,-2,-3,-20,cost); 8395 8396 End_Face_Struct(num_faces); 8397 End_Edge_Struct(num_vert); 8398 8399 // 2006-02-14. 8400 // Updtate progress bar. 8401 if (mUPB) 8402 { 8403 mUPB(percent); 8404 } 8405 //----------------------- 8406 8407 num_vert = num_tiras; 8408 8409 totalStripIndices = 0; 8410 8411 8412 // Asigna el numero de tiras. 8413 geoSubMesh->mStripCount = num_tiras; 8414 8415 // Reserva memoria para el array de punteros al inicio 8416 // de las tiras. 8417 //for(i = 0; i < geoSubMesh->mStripCount; i++) 8418 //{ 8419 geoSubMesh->mStrip = (Index**) malloc( sizeof(Index*) 8420 * 8421 geoSubMesh->mStripCount); 8422 //} 8423 8424 // 2006-02-28. 8425 // La primera sera diferente. 8426 v_indices = mi_vector[1]; 8427 8428 // Number of vertices of a strip odd or even. 8429 if(v_indices.size() % 2) 8430 { 8431 oddStrip = TRUE; 8432 } 8433 else 8434 { 8435 oddStrip = FALSE; 8436 } 8437 8438 // Obtiene el total de indices de la primera strip. 8439 geoSubMesh->mIndexCount = v_indices.size(); 8440 8441 // Calculate the Index Count. 8442 for (i = 2; i <= num_tiras; i++) 8443 { 8444 v_indices = mi_vector[i]; 8445 geoSubMesh->mIndexCount += v_indices.size() + 2; 8446 8447 // Insert a new vertex if the strip es odd. 8448 if(oddStrip) 8449 { 8450 geoSubMesh->mIndexCount++; 8451 } 8452 8453 // Number of vertices of a strip odd or even. 8454 if(v_indices.size() % 2) 8455 { 8456 oddStrip = TRUE; 8457 } 8458 else 8459 { 8460 oddStrip = FALSE; 8461 } 8462 } 8463 8464 // Delete the actual indices. 8465 delete[] geoSubMesh->mIndex; 8466 geoSubMesh->mIndex = new Index[geoSubMesh->mIndexCount]; 8467 //-------------------------------------------- 8468 8469 // La primera sera diferente. 8470 v_indices = mi_vector[1]; 8471 8472 // Obtiene el total de indices de la primera strip. 8473 //geoSubMesh->mIndexCount = v_indices.size(); 8474 8475 // Copia la primera tira en el array de indices. 8476 for(j = 0;j < v_indices.size();j++) 8477 { 8478 geoSubMesh->mIndex[totalStripIndices++] = v_indices[j]; 8479 } 8480 8481 // Asigna el inicio de la primera tira de triangulos. 8482 geoSubMesh->mStrip[0] = &geoSubMesh->mIndex[0]; 8483 8484 // 2006-02-14. 8485 // Updtate progress bar. 8486 if (mUPB) 8487 { 8488 mUPB(percent); 8489 } 8490 //----------------------- 8491 8492 // Number of vertices of a strip odd or even. 8493 if(v_indices.size() % 2) 8494 { 8495 oddStrip = TRUE; 8496 } 8497 else 8498 { 8499 oddStrip = FALSE; 8500 } 8501 8502 // Para todas las tiras menos la primera. 8503 for(i = 2; i <= num_tiras; i++) 8504 { 8505 /* copia en el inicio de la tira el final de la anterior. 8506 triangulos degenerados. */ 8507 geoSubMesh->mIndex[totalStripIndices++] = geoSubMesh-> 8508 mIndex[totalStripIndices-1]; 8509 8510 v_indices = mi_vector[i]; 8511 8512 /* copia el inicio de la tira 2 veces. 8513 triangulos degenerados. 8514 */ 8515 geoSubMesh->mIndex[totalStripIndices++] = v_indices[0]; 8516 8517 // Asigna el inicio de la tira de triangulos. 8518 geoSubMesh->mStrip[i-1] = &geoSubMesh->mIndex[totalStripIndices - 1]; 8519 8520 // Triangulo Degenerado. 8521 geoSubMesh->mIndex[totalStripIndices++] = v_indices[0]; 8522 8523 // Insert a new vertex if the strip es odd. 8524 if(oddStrip) 8525 { 8526 geoSubMesh->mIndex[totalStripIndices++] = v_indices[0]; 8527 } 8528 8529 // Number of vertices of a strip odd or even. 8530 if(v_indices.size() % 2) 8531 { 8532 oddStrip = TRUE; 8533 } 8534 else 8535 { 8536 oddStrip = FALSE; 8537 } 8538 8539 // Copia la tira en curso en el array de indices. 8540 for(j = 1; j < v_indices.size(); j++) 8541 { 8542 geoSubMesh->mIndex[totalStripIndices++] = v_indices[j]; 8543 } 8544 } 8545 } 8546 }// End For. SubMeshes. 8547 8548 // 2006-02-14. 8549 // Updtate progress bar. 8550 if (mUPB) 8551 { 8552 mUPB(100.0); 8553 } 8554 //----------------------- 8555 8556 return 1; 8557 } 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 8558 1330 8559 1331 //------------------------------------------------------------------------- … … 8589 1361 CustomStripifier::~CustomStripifier() 8590 1362 { 1363 printf("Voy a borrar\n"); 8591 1364 delete MeshGlobal; 1365 printf("Borro\n"); 8592 1366 } 8593 1367 … … 8605 1379 int CustomStripifier::Stripify() 8606 1380 { 8607 // Init variables. 8608 resetting = FALSE; 8609 added_quad = 0; 8610 reversed = FALSE; 8611 patch = 0; 8612 out1 = -1; 8613 out2 = -1; 8614 out1Ex = -1; 8615 out2Ex = -1; 1381 // Init variables 8616 1382 last = 0; 8617 1383 8618 1384 // Make Triangle Strips. 8619 return stripify( "out.obj",MeshGlobal);1385 return stripify(MeshGlobal); 8620 1386 } 8621 1387 … … 8649 1415 mSubMeshLeaves = submesh; 8650 1416 } 8651
Note: See TracChangeset
for help on using the changeset viewer.