cbec90699f
- creato il progetto in Visual Studio per compilare come libreria statica - modifiche al codice originale per integrarlo nelle nostre librerie.
634 lines
18 KiB
C++
634 lines
18 KiB
C++
/*****************************************************************************/
|
|
/* */
|
|
/* 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 <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
|
|
/* */
|
|
/* 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
|