Files
SaraP cbec90699f FIST 6.8 :
- creato il progetto in Visual Studio per compilare come libreria statica
- modifiche al codice originale per integrarlo nelle nostre librerie.
2025-03-04 16:19:35 +01:00

280 lines
12 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 <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
/* */
/* get my header files */
/* */
#include "fpkernel.h"
#include "martin.h"
#include "defs.h"
#include "list.h"
#include "header.h"
#include "basic.h"
#include "numerics.h"
#ifdef GRAPHICS
#include "graphics.h"
#endif
/* */
/* function prototypes of functions provided in this file */
/* */
boolean SimpleFace(global_struct *all, list_ind ind1, boolean ears_fancy);
boolean TrivialPolygon(global_struct *all, list_ind ind1);
/* */
/* handle a triangle or a quadrangle in a simple and efficient way. if the */
/* face is more complex than false is returned. */
/* */
/* if `keep_quads' is true then faces with four vertices will be stored as */
/* pairs of triangles in the array `quads'; any subsequent grouping of */
/* triangles into quads (if `do_quads' is true) will not effect those pairs */
/* of triangles! */
/* */
/* warning: the correctness of this function depends upon the fact that */
/* `CleanPolyhedralFace' has not yet been executed; i.e., the */
/* vertex indices have not been changed since the execution of */
/* `CleanPolyhedron'! (otherwise, we would have to get the original */
/* indices via calls to `GetOriginal'...) */
/* */
boolean SimpleFace(global_struct *all, list_ind ind1, boolean ears_fancy)
{
listdef *list = &all->c_list;
vertexdef *vert = &all->c_vertex;
datadef *data = &all->c_data;
tmp_data_def tmp_data;
list_ind ind0, ind2, ind3, ind4;
int i1, i2, i3, i4;
vertex pq, pr, nr;
double x, y, z;
int ori1, ori2, ori3, ori4;
ind0 = GetPrevNode(list, ind1);
if (ind0 == ind1) {
/* */
/* this polygon has only one vertex! nothing to triangulate... */
/* */
FIST_Warning("Polygon with only one vertex?!");
return true;
}
ind2 = GetNextNode(list, ind1);
i2 = GetIndex(list, ind2);
if (ind0 == ind2) {
/* */
/* this polygon has only two vertices! nothing to triangulate... */
/* */
FIST_Warning("Polygon with only two vertices?!");
return true;
}
ind3 = GetNextNode(list, ind2);
i3 = GetIndex(list, ind3);
if (ind0 == ind3) {
/* */
/* this polygon is a triangle! let's triangulate it! ;-) */
/* */
i1 = GetIndex(list, ind1);
StoreTriangle(all, ind1, ind2, ind3, TriTriColor);
return true;
}
ind4 = GetNextNode(list, ind3);
i4 = GetIndex(list, ind4);
if (ind0 == ind4) {
if (ears_fancy) return false; /* need to generate "nice" triangles */
/* */
/* this polygon is a quadrangle! not too hard to triangulate it... */
/* we project the corners of the quadrangle onto one of the coordinate */
/* planes */
/* */
InitPnts(data, 5);
i1 = GetIndex(list, ind1);
VectorSub(vert->vertices[i1], vert->vertices[i2], pq);
VectorSub(vert->vertices[i3], vert->vertices[i2], pr);
VectorProduct(pq, pr, nr);
x = Abs(nr.x);
y = Abs(nr.y);
z = Abs(nr.z);
if ((z >= x) && (z >= y)) {
data->points[1].x = vert->vertices[i1].x;
data->points[1].y = vert->vertices[i1].y;
data->points[2].x = vert->vertices[i2].x;
data->points[2].y = vert->vertices[i2].y;
data->points[3].x = vert->vertices[i3].x;
data->points[3].y = vert->vertices[i3].y;
data->points[4].x = vert->vertices[i4].x;
data->points[4].y = vert->vertices[i4].y;
}
else if ((x >= y) && (x >= z)) {
data->points[1].x = vert->vertices[i1].z;
data->points[1].y = vert->vertices[i1].y;
data->points[2].x = vert->vertices[i2].z;
data->points[2].y = vert->vertices[i2].y;
data->points[3].x = vert->vertices[i3].z;
data->points[3].y = vert->vertices[i3].y;
data->points[4].x = vert->vertices[i4].z;
data->points[4].y = vert->vertices[i4].y;
}
else {
data->points[1].x = vert->vertices[i1].x;
data->points[1].y = vert->vertices[i1].z;
data->points[2].x = vert->vertices[i2].x;
data->points[2].y = vert->vertices[i2].z;
data->points[3].x = vert->vertices[i3].x;
data->points[3].y = vert->vertices[i3].z;
data->points[4].x = vert->vertices[i4].x;
data->points[4].y = vert->vertices[i4].z;
}
data->num_pnts = 5;
/* */
/* find a valid diagonal */
/* */
Orientation(data, tmp_data, 1, 2, 3, ori2);
Orientation(data, tmp_data, 1, 3, 4, ori4);
if (((ori2 > 0) && (ori4 > 0)) ||
((ori2 < 0) && (ori4 < 0))) {
/* */
/* i1, i3 is a valid diagonal; */
/* */
if (all->rt_opt.keep_convex) {
Orientation(data, tmp_data, 2, 3, 4, ori3);
Orientation(data, tmp_data, 2, 4, 1, ori1);
if (((ori1 > 0) && (ori3 > 0)) ||
((ori1 < 0) && (ori3 < 0))) {
/* */
/* i2, i4 is a valid diagonal, too ---> convex quad. */
/* the triangles are (1, 2, 3) and (1, 3, 4). */
/* */
StoreQuad(vert, i1, i2, i3, i4);
}
else {
/* */
/* oops, this quad does seem to be non-convex. */
/* */
StoreTriangle(all, ind1, ind2, ind3, TriCveColor);
StoreTriangle(all, ind1, ind3, ind4, TriCveColor);
++vert->num_concave_loops;
}
}
else if (all->rt_opt.keep_quads) {
/* */
/* the triangles are (1, 2, 3) and (1, 3, 4). */
/* */
StoreQuad(vert, i1, i2, i3, i4);
}
else {
StoreTriangle(all, ind1, ind2, ind3, TriQuadColor);
StoreTriangle(all, ind1, ind3, ind4, TriQuadColor);
}
}
else {
/* */
/* i2, i4 has to be a valid diagonal. (if this is no valid */
/* diagonal then the corners of the quad form a figure of eight; */
/* shall we apply any heuristics in order to guess which diagonal */
/* is more likely to be the better choice? alternatively, we could */
/* return false and subject it to the standard triangulation */
/* algorithm. well, let's see how this brute-force solution works.) */
/* */
++vert->num_concave_loops;
if (all->rt_opt.keep_quads && !all->rt_opt.keep_convex)
/* */
/* the triangles are (1, 2, 4) and (2, 3, 4). */
/* */
StoreQuad(vert, i2, i3, i4, i1);
else {
StoreTriangle(all, ind2, ind3, ind4, TriCveColor);
StoreTriangle(all, ind2, ind4, ind1, TriCveColor);
}
}
return true;
}
return false;
}
boolean TrivialPolygon(global_struct *all, list_ind ind1)
{
listdef *list = &all->c_list;
#ifdef GRAPHICS
datadef *data = &all->c_data;
redrawdef *redraw = &all->c_redraw;
int i1, i2, i3;
#endif
list_ind ind2, ind3, ind0;
ind0 = GetPrevNode(list, ind1);
if (ind0 == ind1) {
/* */
/* this polygon has only one vertex! nothing to triangulate... */
/* */
FIST_Warning("Polygon with only one vertex?!");
return true;
}
ind2 = GetNextNode(list, ind1);
if (ind0 == ind2) {
/* */
/* this polygon has only two vertices! nothing to triangulate... */
/* */
FIST_Warning("Polygon with only two vertices?!");
return true;
}
ind3 = GetNextNode(list, ind2);
if (ind0 == ind3) {
/* */
/* this polygon is a triangle! let's triangulate it! ;-) */
/* */
StoreTriangle(all, ind1, ind2, ind3, TriTriColor);
/* */
/* insert the ear into the drawing buffer */
/* */
#ifdef GRAPHICS
if (all->rt_opt.graphics) {
i1 = GetIndex(list, ind1);
i2 = GetIndex(list, ind2);
i3 = GetIndex(list, ind3);
AddTriToBuffer(redraw, i1, i2, i3, TriColor, TriFillColor);
DrawTri(data->points[i1], data->points[i2], data->points[i3],
TriColor, TriFillColor);
}
#endif
return true;
}
return false;
}