/*****************************************************************************/ /* */ /* F I S T : Fast, Industrial-Strength Triangulation */ /* */ /*****************************************************************************/ /* */ /* (C) Martin Held */ /* (C) Universitaet Salzburg, Salzburg, Austria */ /* */ /* This code is not in the public domain. All rights reserved! Please make */ /* sure to read the full copyright statement contained in api_functions.cpp. */ /* */ /*****************************************************************************/ /* */ /* get standard libraries */ /* */ #include #include #include /* */ /* get my header files */ /* */ #include "fpkernel.h" #include "martin.h" #include "defs.h" #include "header.h" /* */ /* prototypes of functions provided in this file */ /* */ #ifdef EXT_APPL_SITES int StoreVertex(vertexdef *vert, double x, double y, double z, eas_type ext_appl); #else int StoreVertex(vertexdef *vert, double x, double y, double z); #endif void InitVertices(vertexdef *vert, int number); void FreeVertices(vertexdef *vertex); boolean InVertexList(vertexdef *vertex, int index); void StoreTriangle(global_struct *all, int i, int j, int k, int color); void FreeTriangles(vertexdef *vertex); void InitTriangles(vertexdef *vertex, int number); int GetNumTriangles(vertexdef* vert); void StoreQuad(vertexdef *vertex, int i, int j, int k, int l); void FreeQuads(vertexdef *vertex); void InitQuads(vertexdef *vertex, int number); void FreeGroups(vertexdef *vertex); boolean InGroupList(vertexdef *vertex, int index); void InitGroupTriangles(vertexdef *vertex); void StoreGroupNumber(listdef *list, vertexdef *vertex); void StoreGroupData(vertexdef *vertex); void StoreConvexLoop(global_struct *all, list_ind ind); void FreeConvexLoops(vertexdef *vertex); #ifdef NORMALS int StoreV_Normal(vertexdef *vert, double x, double y, double z); void InitV_Normals(vertexdef *vert, int number); void FreeV_Normals(vertexdef *vertex); boolean InV_NormalList(vertexdef *vertex, int index); int StoreT_Vertex(vertexdef *vert, double x, double y, double z); void InitT_Vertices(vertexdef *vert, int number); void FreeT_Vertices(vertexdef *vertex); boolean InT_VertexList(vertexdef *vertex, int index); void FreeI_Triangles(vertexdef *vertex); #endif #define HALF_BLOCK_SIZE 1024 #define BLOCK_SIZE 32768 void InitVertexDef(vertexdef* vert) { #ifdef NORMALS vert->t_vertices = (vertex*)NULL; vert->num_t_vertices = 0; vert->max_num_t_vertices = 0; vert->v_normals = (vertex*)NULL; vert->num_v_normals = 0; vert->max_num_v_normals = 0; vert->i_triangles = (i_triangle*)NULL; vert->num_i_triangles = 0; vert->max_num_i_triangles = 0; #endif vert->vertices = (vertex*)NULL; vert->num_vertices = 0; vert->max_num_vertices = 0; vert->triangles = (triangle*)NULL; vert->num_triangles = 0; vert->max_num_triangles = 0; vert->quads = (quadrangle*)NULL; vert->num_quads = 0; vert->max_num_quads = 0; vert->groups = (int*)NULL; vert->num_groups = 0; vert->max_num_groups = 0; vert->num_group_tris = 0; vert->group_tris = (int*)NULL; vert->group_quads = (int*)NULL; vert->group_loops = (int*)NULL; vert->convex_loops = (loop_list*)NULL; vert->num_convex_loops = 0; vert->num_concave_loops = 0; vert->max_num_convex_loops = 0; } void StoreGroupNumber(listdef *list, vertexdef *vertex) { if (vertex->num_groups >= vertex->max_num_groups) { vertex->max_num_groups += HALF_BLOCK_SIZE; vertex->groups = (int*) ReallocateArray(list->memptr, vertex->groups, vertex->max_num_groups, sizeof(int), "vertex:groups"); } vertex->groups[vertex->num_groups] = list->num_faces; ++vertex->num_groups; return; } void InitGroupTriangles(vertexdef *vertex) { int i; vertex->group_tris = (int*) ReallocateArray(vertex->memptr, vertex->group_tris, vertex->num_groups + 1, sizeof(int), "vertex:group_tris"); vertex->group_quads = (int*) ReallocateArray(vertex->memptr, vertex->group_quads, vertex->num_groups + 1, sizeof(int), "vertex:group_quads"); vertex->group_loops = (int*) ReallocateArray(vertex->memptr, vertex->group_loops, vertex->num_groups + 1, sizeof(int), "vertex:group_loops"); vertex->num_group_tris = 0; for (i = 0; i <= vertex->num_groups; ++ i) { vertex->group_tris[i] = 0; vertex->group_quads[i] = 0; vertex->group_loops[i] = 0; } return; } void StoreGroupData(vertexdef *vertex) { assert(vertex->group_tris != (int*)NULL); assert(vertex->group_quads != (int*)NULL); assert(vertex->group_loops != (int*)NULL); assert(InGroupList(vertex,vertex->num_group_tris)); vertex->group_tris[vertex->num_group_tris] = vertex->num_triangles; vertex->group_quads[vertex->num_group_tris] = vertex->num_quads; vertex->group_loops[vertex->num_group_tris] = vertex->num_convex_loops; ++vertex->num_group_tris; return; } boolean InGroupList(vertexdef *vertex, int index) { return ((index >= 0) && (index < vertex->num_groups)); } void FreeGroups(vertexdef *vertex) { FreeMemory(vertex->memptr, (void**) &vertex->groups, "vertex:groups"); FreeMemory(vertex->memptr, (void**) &vertex->group_tris, "vertex:group_tris"); FreeMemory(vertex->memptr, (void**) &vertex->group_quads, "vertex:group_quads"); FreeMemory(vertex->memptr, (void**) &vertex->group_loops, "vertex:group_loops"); vertex->num_groups = 0; vertex->max_num_groups = 0; vertex->num_group_tris = 0; return; } #ifdef EXT_APPL_SITES int StoreVertex(vertexdef *vert, double x, double y, double z, eas_type ext_appl) #else int StoreVertex(vertexdef *vert, double x, double y, double z) #endif { int i; if (vert->num_vertices >= vert->max_num_vertices) { vert->max_num_vertices += BLOCK_SIZE; vert->vertices = CORE_ReallocateArray(vert->memptr, vert->vertices, vert->max_num_vertices - BLOCK_SIZE, vert->max_num_vertices, vertex, "vertex:vertices"); } vert->vertices[vert->num_vertices].x = x; vert->vertices[vert->num_vertices].y = y; vert->vertices[vert->num_vertices].z = z; #ifdef EXT_APPL_SITES vert->vertices[vert->num_vertices].ext_appl = ext_appl; #endif /* */ /* let the user call some application-specific function */ /* */ ExtApplFuncStoreVertex; i = vert->num_vertices; ++vert->num_vertices; return i; } void InitVertices(vertexdef *vert, int number) { if (number > vert->max_num_vertices) { vert->vertices = CORE_ReallocateArray(vert->memptr, vert->vertices, vert->max_num_vertices, number, vertex, "vertex:vertices"); vert->max_num_vertices = number; } vert->num_vertices = 0; return; } void FreeVertices(vertexdef *vertex) { CORE_FreeMemory(vertex->memptr, &vertex->vertices, "vertex:vertices"); vertex->num_vertices = 0; vertex->max_num_vertices = 0; return; } boolean InVertexList(vertexdef *vertex, int index) { return ((index >= 0) && (index < vertex->num_vertices)); } void StoreTriangle(global_struct *all, int i, int j, int k, int color) { listdef *list = &all->c_list; vertexdef *vertex = &all->c_vertex; triangle *tri; #ifdef EXT_APPL_TRI eat_type ext_appl = eat_NIL; #endif assert(InVertexList(vertex,GetOriginal(list,i))); assert(InVertexList(vertex,GetOriginal(list,j))); assert(InVertexList(vertex,GetOriginal(list,k))); #ifndef PARTITION_FIST if (vertex->num_triangles >= vertex->max_num_triangles) { vertex->max_num_triangles += BLOCK_SIZE; vertex->triangles = (triangle*) ReallocateArray(vertex->memptr, vertex->triangles, vertex->max_num_triangles, sizeof(triangle), "vertex:triangles"); } tri = &vertex->triangles[vertex->num_triangles]; #else tri = &vertex->triangles[j]; #endif #ifdef PARTITION_FIST tri->disabled = false; #endif if (all->ccw_loop) { tri->v1 = GetOriginal(list,i); tri->v2 = GetOriginal(list,j); tri->v3 = GetOriginal(list,k); #ifdef PARTITION_FIST tri->ind1 = i; tri->ind2 = j; tri->ind3 = k; #endif } else { tri->v1 = GetOriginal(list,j); tri->v2 = GetOriginal(list,i); tri->v3 = GetOriginal(list,k); #ifdef PARTITION_FIST tri->ind1 = k; tri->ind2 = j; tri->ind3 = i; #endif } tri->color = color; /* */ /* let the user call some application-specific function */ /* */ ExtApplFuncStoreTri_1; #ifdef EXT_APPL_TRI tri->ext_appl = ext_appl; #endif #ifndef PARTITION_FIST ++vertex->num_triangles; #endif #ifdef NORMALS if (all->c_io3d.tex_norm_data_exists) { if (vertex->num_i_triangles >= vertex->max_num_i_triangles) { vertex->max_num_i_triangles += BLOCK_SIZE; vertex->i_triangles = (i_triangle*) ReallocateArray(vertex->memptr, vertex->i_triangles, vertex->max_num_i_triangles, sizeof(i_triangle), "vertex:i_triangles"); } vertex->i_triangles[vertex->num_i_triangles].i1 = i; vertex->i_triangles[vertex->num_i_triangles].i2 = j; vertex->i_triangles[vertex->num_i_triangles].i3 = k; ++vertex->num_i_triangles; } /* */ /* let the user call some application-specific function */ /* */ ExtApplFuncStoreTri_2; #endif return; } void StoreConvexLoop(global_struct *all, list_ind ind) { vertexdef *vertex = &all->c_vertex; if (vertex->num_convex_loops >= vertex->max_num_convex_loops) { vertex->max_num_convex_loops += HALF_BLOCK_SIZE; vertex->convex_loops = (loop_list*) ReallocateArray(vertex->memptr, vertex->convex_loops, vertex->max_num_convex_loops, sizeof(loop_list), "vertex:convex_loops"); } vertex->convex_loops[vertex->num_convex_loops].ind = ind; vertex->convex_loops[vertex->num_convex_loops].ccw = all->ccw_loop; ++vertex->num_convex_loops; return; } void FreeConvexLoops(vertexdef *vertex) { FreeMemory(vertex->memptr, (void**) &vertex->convex_loops, "vertex:convex_loops"); vertex->num_convex_loops = 0; vertex->max_num_convex_loops = 0; return; } void InitTriangles(vertexdef *vertex, int number) { if (number > vertex->max_num_triangles) { vertex->max_num_triangles = number; vertex->triangles = (triangle*) ReallocateArray(vertex->memptr, vertex->triangles, vertex->max_num_triangles, sizeof(triangle), "vertex:triangles"); } vertex->num_triangles = 0; #ifdef PARTITION_FIST for(int i = 0; i < vertex->max_num_triangles; ++i) { vertex->triangles[i].disabled = true; } #endif return; } void FreeTriangles(vertexdef *vertex) { FreeMemory(vertex->memptr, (void**) &vertex->triangles, "vertex:triangles"); vertex->num_triangles = 0; vertex->max_num_triangles = 0; return; } int GetNumTriangles(vertexdef* vert) { #ifdef PARTITION_FIST int k = 0; for(int i = 0; i < vert->max_num_triangles; ++i) { if(!vert->triangles[i].disabled) ++k; } return k; #else return vert->num_triangles; #endif } #ifdef NORMALS void FreeI_Triangles(vertexdef *vertex) { FreeMemory(vertex->memptr, (void**) &vertex->i_triangles, "vertex:i_triangles"); vertex->num_i_triangles = 0; vertex->max_num_i_triangles = 0; return; } #endif void StoreQuad(vertexdef *vertex, int i, int j, int k, int l) { #ifdef EXT_APPL_TRI eat_type ext_appl = eat_NIL; #endif if (vertex->num_quads >= vertex->max_num_quads) { vertex->max_num_quads += BLOCK_SIZE; vertex->quads = (quadrangle*) ReallocateArray(vertex->memptr, vertex->quads, vertex->max_num_quads, sizeof(quadrangle), "vertex:quads"); } vertex->quads[vertex->num_quads].v1 = i; vertex->quads[vertex->num_quads].v2 = j; vertex->quads[vertex->num_quads].v3 = k; vertex->quads[vertex->num_quads].v4 = l; /* */ /* let the user call some application-specific function */ /* */ ExtApplFuncStoreQuad; #ifdef EXT_APPL_TRI vertex->quads[vertex->num_quads].ext_appl = ext_appl; #endif ++vertex->num_quads; return; } void InitQuads(vertexdef *vertex, int number) { if (number > vertex->max_num_quads) { vertex->max_num_quads = number; vertex->quads = (quadrangle*) ReallocateArray(vertex->memptr, vertex->quads, vertex->max_num_quads, sizeof(quadrangle), "vertex:quads"); } vertex->num_quads = 0; return; } void FreeQuads(vertexdef *vertex) { FreeMemory(vertex->memptr, (void**) &vertex->quads, "vertex:quads"); vertex->num_quads = 0; vertex->max_num_quads = 0; return; } #ifdef NORMALS int StoreV_Normal(vertexdef *vert, double x, double y, double z) { int i; if (vert->num_v_normals >= vert->max_num_v_normals) { vert->max_num_v_normals += BLOCK_SIZE; vert->v_normals = CORE_ReallocateArray(vert->memptr, vert->v_normals, vert->max_num_v_normals - BLOCK_SIZE, vert->max_num_v_normals, vertex, "vertex:v_normals"); } vert->v_normals[vert->num_v_normals].x = x; vert->v_normals[vert->num_v_normals].y = y; vert->v_normals[vert->num_v_normals].z = z; /* */ /* let the user call some application-specific function */ /* */ ExtApplFuncStoreVNormal; i = vert->num_v_normals; ++vert->num_v_normals; return i; } void InitV_Normals(vertexdef *vert, int number) { if (number > vert->max_num_v_normals) { vert->max_num_v_normals = number; vert->v_normals = (vertex*) ReallocateArray(vert->memptr, vert->v_normals, vert->max_num_v_normals, sizeof(vertex), "vertex:v_normals"); } vert->num_v_normals = 0; return; } void FreeV_Normals(vertexdef *vertex) { CORE_FreeMemory(vertex->memptr, &vertex->v_normals, "vertex:v_normals"); vertex->num_v_normals = 0; vertex->max_num_v_normals = 0; return; } boolean InV_NormalList(vertexdef *vertex, int index) { return ((index >= 0) && (index < vertex->num_v_normals)); } int StoreT_Vertex(vertexdef *vert, double x, double y, double z) { int i; if (vert->num_t_vertices >= vert->max_num_t_vertices) { vert->max_num_t_vertices += BLOCK_SIZE; vert->t_vertices = CORE_ReallocateArray(vert->memptr, vert->t_vertices, vert->max_num_t_vertices - BLOCK_SIZE, vert->max_num_t_vertices, vertex, "vertex:t_vertices"); } vert->t_vertices[vert->num_t_vertices].x = x; vert->t_vertices[vert->num_t_vertices].y = y; vert->t_vertices[vert->num_t_vertices].z = z; /* */ /* let the user call some application-specific function */ /* */ ExtApplFuncStoreTVertex; i = vert->num_t_vertices; ++vert->num_t_vertices; return i; } void InitT_Vertices(vertexdef *vert, int number) { if (number > vert->max_num_t_vertices) { vert->max_num_t_vertices = number; vert->t_vertices = (vertex*) ReallocateArray(vert->memptr, vert->t_vertices, vert->max_num_t_vertices, sizeof(vertex), "vertex:t_vertices"); } vert->num_t_vertices = 0; return; } void FreeT_Vertices(vertexdef *vertex) { CORE_FreeMemory(vertex->memptr, &vertex->t_vertices, "vertex:t_vertices"); vertex->num_t_vertices = 0; vertex->max_num_t_vertices = 0; return; } boolean InT_VertexList(vertexdef *vertex, int index) { return ((index >= 0) && (index < vertex->num_t_vertices)); } #endif