- aggiunto FIST 6.8 ( già modificato per integrazione nelle nostre librerie).
This commit is contained in:
SaraP
2025-03-04 16:37:58 +01:00
parent f5f6a9cb47
commit 05ca0d3376
24 changed files with 4148 additions and 0 deletions
+56
View File
@@ -0,0 +1,56 @@
/*****************************************************************************/
/* */
/* 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. */
/* */
/*****************************************************************************/
/* */
/* Note: A polygonal area with a total of N vertices and H holes has exactly */
/* N - 2 + 2 * H */
/* triangles. */
/* */
#include "martin.h"
#include "defs.h"
// MODIF : includo questo file per rendere api_fist l'unico file da includere per utilizzare fist
#include "header.h"
/* api_functions.cpp: */
boolean FIST_HandlePolyhedron(rt_options *rt_opt);
boolean FIST_HandlePolygon(rt_options *rt_opt);
boolean FIST_2D_PolyArray(int num_contours, int num_vertices[],
double (*input_vtx)[2], int *num_triangles,
int (*output_tri)[3]);
boolean FIST_3D_FaceArray(int num_contours, int num_vtx[],
double (*input_vtx)[3], int *num_tri,
int (*output_tri)[3]);
void FIST_TerminateProgram(global_struct *all);
void FIST_HandleError(errordef FistErrorCode);
const char* FIST_GetProgName();
const char* FIST_GetProgVersion();
const char* FIST_GetProgYear();
// funzioni aggiunte per integrazione con le nostre librerie
/* fist_added_functions.cpp : */
void AddLoopInFace( global_struct *all, int nHoles, boolean bFirstLoop, int nPoints) ;
void OptimizeMemoryAllocation( global_struct *all, int nLoops, int nPoints) ;
+310
View File
@@ -0,0 +1,310 @@
/*****************************************************************************/
/* */
/* 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. */
/* */
/*****************************************************************************/
#ifndef _BASIC_H_
#define _BASIC_H_
#ifndef RAND
#define RND_MAX 2147483647
#define UniformRandom(x) \
{\
x = ((machine_double) random()) / RND_MAX; }
#define RandomInteger(var, N) \
(\
assert(N > 0), \
var = random(), \
var - (var / (N)) * (N))
#define InitRandom(seed) \
{\
srandom(seed); }
#else
#ifdef RAND_MAX
#define RND_MAX RAND_MAX
#else
#define RND_MAX 32767
#endif
#define UniformRandom(x) \
{\
x = ((machine_double) rand()) / RND_MAX; }
#define RandomInteger(var, N) \
(\
assert(N > 0), \
var = rand(), \
var - (var / (N)) * (N))
#define InitRandom(seed) \
{\
srand(seed); }
#endif
#define RandomVertex(a) \
{\
UniformRandom((a).x); \
UniformRandom((a).y); \
UniformRandom((a).z); }
#define DetExp(u_x, u_y, u_z, v_x, v_y, v_z, w_x, w_y, w_z) \
((u_x) * ((v_y) * (w_z) - (v_z) * (w_y)) - \
(u_y) * ((v_x) * (w_z) - (v_z) * (w_x)) + \
(u_z) * ((v_x) * (w_y) - (v_y) * (w_x)))
#define Det3D(u, v, w) \
((u).x * ((v).y * (w).z - (v).z * (w).y) - \
(u).y * ((v).x * (w).z - (v).z * (w).x) + \
(u).z * ((v).x * (w).y - (v).y * (w).x))
#define Det2D(u, v, w) \
(((u).x - (v).x) * ((v).y - (w).y) + ((v).y - (u).y) * ((v).x - (w).x))
#define Length2D(u) \
(((u).x * (u).x) + ((u).y * (u).y))
#define Length2(u) \
(((u).x * (u).x) + ((u).y * (u).y) + ((u).z * (u).z))
#define Length_l1(u) \
(Abs((u).x) + Abs((u).y) + Abs((u).z))
#define Length_l2(u) \
sqrt(((u).x * (u).x) + ((u).y * (u).y) + ((u).z * (u).z))
#define DotProduct(u, v) \
(((u).x * (v).x) + ((u).y * (v).y) + ((u).z * (v).z))
#define DotProduct2D(u, v) \
(((u).x * (v).x) + ((u).y * (v).y))
#define DotProduct2DTMD(u, v) \
((TO_MDOUBLE((u).x) * TO_MDOUBLE((v).x)) + (TO_MDOUBLE((u).y) * TO_MDOUBLE((v).y)))
#define VectorProduct(p, q, r) \
{(r).x = (p).y * (q).z - (q).y * (p).z; \
(r).y = (q).x * (p).z - (p).x * (q).z; \
(r).z = (p).x * (q).y - (q).x * (p).y; }
#define VectorAdd(p, q, r) \
{(r).x = (p).x + (q).x; \
(r).y = (p).y + (q).y; \
(r).z = (p).z + (q).z; }
#define LinearComb(p, q, r, t) \
{(r).x = (p).x + (t) * ((q).x - (p).x); \
(r).y = (p).y + (t) * ((q).y - (p).y); \
(r).z = (p).z + (t) * ((q).z - (p).z); }
#define VectorSub(p, q, r) \
{(r).x = (p).x - (q).x; \
(r).y = (p).y - (q).y; \
(r).z = (p).z - (q).z; }
#define VectorAdd2D(p, q, r) \
{(r).x = (p).x + (q).x; \
(r).y = (p).y + (q).y; }
#define VectorSub2D(p, q, r) \
{(r).x = (p).x - (q).x; \
(r).y = (p).y - (q).y; }
#define LinearComb2D(p, q, r, t) \
{(r).x = (p).x + (t) * ((q).x - (p).x); \
(r).y = (p).y + (t) * ((q).y - (p).y); }
#define InvertVector(p) \
{(p).x = -(p).x; \
(p).y = -(p).y; \
(p).z = -(p).z; }
#define MultScalar(scalar, u) \
{(u).x *= scalar; \
(u).y *= scalar; \
(u).z *= scalar; }
#define DivScalar(scalar, u) \
{(u).x /= scalar; \
(u).y /= scalar; \
(u).z /= scalar; }
#define InvertVector2D(p) \
{(p).x = -(p).x; \
(p).y = -(p).y; }
#define MultScalar2D(scalar, u) \
{(u).x *= scalar; \
(u).y *= scalar; }
#define DivScalar2D(scalar, u) \
{(u).x /= scalar; \
(u).y /= scalar; }
#define SignEps(var, x, eps) \
(var = (x), \
((var <= eps) ? ((var < -eps) ? -1 : 0) : 1))
#define MinMax3(a, b, c, min, max) {\
if ((a) < (b)) {\
if ((a) < (c)) {\
min = (a); \
if ((b) < (c)) max = (c); \
else max = (b); \
}\
else { \
min = (c); \
max = (b); \
}\
}\
else { \
if ((a) < (c)) {\
min = (b); \
max = (c); \
} \
else { \
max = (a); \
if ((b) < (c)) min = (b); \
else min = (c); \
} \
}\
}
#define MinMax4(a, b, c, d, min, max) {\
if ((a) < (b)) {\
if ((a) < (c)) {\
min = (a); \
if ((b) < (c)) max = (c); \
else max = (b); \
} \
else { \
min = (c); \
max = (b); \
} \
}\
else { \
if ((a) < (c)) { \
min = (b); \
max = (c); \
} \
else { \
max = (a); \
if ((b) < (c)) min = (b); \
else min = (c); \
}\
} \
if ((d) < min) min = (d); \
else if ((d) > max) max = (d); \
}
#define ScaleX(data,xc) ((xc - data->shift.x) * data->scale_factor)
#define ScaleY(data,yc) ((yc - data->shift.y) * data->scale_factor)
#define UnscaleX(data,xc) (data->shift.x + xc / data->scale_factor)
#define UnscaleY(data,yc) (data->shift.y + yc / data->scale_factor)
#define SortTwoNumbers(a, b, c) {\
if (a > b) { \
c = a; \
a = b; \
b = c; \
} \
}
#define SortThreeNumbers(a, b, c, d) {\
if (a < b) {\
if (a < c) {\
if (b > c) {\
d = b; \
b = c; \
c = d; \
}\
}\
else { \
d = a; \
a = c; \
c = b; \
b = d; \
}\
}\
else { \
if (a < c) { \
d = a; \
a = b; \
b = d; \
} \
else { \
if (b < c) {\
d = a; \
a = b; \
b = c; \
c = d; \
}\
else { \
d = a; \
a = c; \
c = d; \
}\
}\
}\
}
#define MinMax(a, b, min, max) {\
if ((b) < (a)) {\
min = (b); \
max = (a); \
} \
else { \
min = (a); \
max = (b); \
} \
}
#endif
+100
View File
@@ -0,0 +1,100 @@
/*****************************************************************************/
/* */
/* 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. */
/* */
/*****************************************************************************/
#define Pnt_In_BBox(data, bb1, i) \
((((bb1).imax < i) ? false : \
(((bb1).imin > i) ? false : \
(((bb1).ymax < data->points[i].y) ? false : \
(((bb1).ymin > data->points[i].y) ? false : true)))))
#define BBox_Overlap(bb1, bb2) \
((((bb1).imax < (bb2).imin) ? false : \
(((bb1).imin > (bb2).imax) ? false : \
(((bb1).ymax < (bb2).ymin) ? false : \
(((bb1).ymin > (bb2).ymax) ? false : true)))))
#define BBox_Contained(bb1, bb2) \
(((bb1).imin <= (bb2).imin) && ((bb1).imax >= (bb2).imax) && \
((bb1).ymin <= (bb2).ymin) && ((bb1).ymax >= (bb2).ymax))
#define BBox_IdenticalLeaf(bb1, bb2) \
(((bb1).imin == (bb2).imin) && ((bb1).imax == (bb2).imax))
#define BBox_Union(bb1, bb2, bb3) \
{ (bb3).imin = Min((bb1).imin, (bb2).imin); \
(bb3).imax = Max((bb1).imax, (bb2).imax); \
(bb3).ymin = Min((bb1).ymin, (bb2).ymin); \
(bb3).ymax = Max((bb1).ymax, (bb2).ymax); }
#define BBox_Area(data, bb, area) \
{ area = (data->points[(bb).imax].x - data->points[(bb).imin].x) * \
((bb).ymax - (bb).ymin); }
#define BBox_Copy(bb1, bb2) \
{ (bb2).imin = (bb1).imin; \
(bb2).imax = (bb1).imax; \
(bb2).ymin = (bb1).ymin; \
(bb2).ymax = (bb1).ymax; }
#define BBox_CopyInverted(bb1, bb2) \
{ (bb2).imin = (bb1).imax; \
(bb2).imax = (bb1).imin; \
(bb2).ymin = (bb1).ymax; \
(bb2).ymax = (bb1).ymin; }
#define BBox_Enlarge(bb1, bb2) \
{ if ((bb1).imin < (bb2).imin) (bb2).imin = (bb1).imin; \
if ((bb1).imax > (bb2).imax) (bb2).imax = (bb1).imax; \
if ((bb1).ymin < (bb2).ymin) (bb2).ymin = (bb1).ymin; \
if ((bb1).ymax > (bb2).ymax) (bb2).ymax = (bb1).ymax; }
/* */
/* this macro computes the bounding box of a line segment whose end */
/* points i, j are sorted according to x-coordinates. */
/* */
#define BBox(data, i, j, bb) \
{ assert(InPointsList(data,i)); \
assert(InPointsList(data,j)); \
\
MinMax(i, j, (bb).imin, (bb).imax); \
MinMax(data->points[(bb).imin].y, data->points[(bb).imax].y, (bb).ymin, (bb).ymax); }
#define BBox_Overlap_Extended(data, bb1, bb2) \
((((bb1).ymax < (bb2).ymin) ? false : \
(((bb1).ymin > (bb2).ymax) ? false : \
(((bb1).xmax < data->points[(bb2).imin].x) ? false : \
(((bb1).xmin > data->points[(bb2).imax].x) ? false : true)))))
+55
View File
@@ -0,0 +1,55 @@
inline double atan2(const double &y, const double &x)
{
if( fabs(x) >= fabs(y) )
{
// Sector to the right
if( x > 0 )
{
const double phi = y/x;
return atan(phi);
}
// Sector to the left
else if( x < 0 )
{
const double phi = y/x;
if( y >= 0) {
return atan(phi) + M_PI;
} else {
return atan(phi) - M_PI;
}
}
// Hence, x and y are zero
else
{
return 0.0;
}
}
else if( fabs(y) >= fabs(x) )
{
// Sector to the top
if( y > 0 )
{
const double phi = x/y;
return M_PI_2 - atan(phi);
}
// Sector to the bottom
if( y < 0 )
{
const double phi = x/y;
return - M_PI_2 - atan(phi);
}
// Actually, the impossible case, x=y=0. Should be catched above.
else
{
assert(false);
return 0.0;
}
}
// This can only happen, if x or y is NaN.
else
{
return 0.0;
}
}
+25
View File
@@ -0,0 +1,25 @@
/*****************************************************************************/
/* */
/* 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. */
/* */
/*****************************************************************************/
#define SetExtApplPnt(DATA, P, X) \
{\
assert(InPointsList(DATA,P)); \
DATA->points[P].ext_appl = X; \
}
#define GetExtApplPnt(DATA, P) \
(\
assert(InPointsList(DATA, P)), \
DATA->points[P].ext_appl)
+916
View File
@@ -0,0 +1,916 @@
/*****************************************************************************/
/* */
/* 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. */
/* */
/*****************************************************************************/
#ifndef FIST_DEFS_H
#define FIST_DEFS_H
#include <time.h>
#include "martin.h"
#include "ext_appl_defs.h"
#define PROG_NAME "F I S T"
#define PROG_VERSION "6.8"
#define PROG_YEAR "1997-2025"
#define NIL -1
#ifndef DOUBLE_OVERRIDE
#define machine_double double
#define double_global double
#endif
#define machine_long long
#define NEW_TRIANGLE_MIN 5
typedef enum {SEG, /* (input) line segment */
ARC, /* (input) circular arc */
PNT, /* (input) point/vertex */
VDN, /* node of Voronoi diagram */
VDE, /* edge of Voronoi diagram */
DTE, /* edge of Delaunay triangulation */
CCW, /* ccw offset arc */
CW, /* cw offset arc */
UNKNOWN} t_site;
typedef struct {
int imin; /* lexicographically smallest point, determines min-x */
int imax; /* lexicographically largest point, determines max-x */
double ymin; /* minimum y-coordinate */
double ymax; /* maximum y-coordinate */
} bounding_box; /* bounding box */
typedef struct {
int imin; /* lexicographically smallest point, determines min-x */
int imax; /* lexicographically largest point, determines max-x */
double xmin; /* minimum x-coordinate */
double xmax; /* maximum x-coordinate */
double ymin; /* minimum y-coordinate */
double ymax; /* maximum y-coordinate */
} bounding_box_extended;
typedef struct {
double x;
double y;
double z;
#ifdef EXT_APPL_SITES
eas_type ext_appl; /* this field can be set by an application program to */
/* refer to a user-defined entity. */
#endif
} vertex;
typedef struct {
double x;
double y;
#ifdef EXT_APPL_SITES
eas_type ext_appl; /* this field can be set by an application program to */
/* refer to a user-defined entity. */
#endif
} point;
/* This struct is needed for the PntPntDistSqd-Macro. */
typedef struct {
machine_double x;
machine_double y;
} md_point;
typedef int list_ind;
typedef struct {
int v1;
int v2;
int v3;
int color;
#ifdef EXT_APPL_TRI
eat_type ext_appl; /* this field can be set by an application program to */
/* refer to a user-defined entity. */
#endif
#ifdef PARTITION_FIST
list_ind ind1, ind2, ind3;
boolean disabled;
#endif
} triangle;
#ifdef NORMALS
typedef struct {
int i1;
int i2;
int i3;
} i_triangle;
#endif
typedef struct {
int v1;
int v2;
int v3;
int v4;
#ifdef EXT_APPL_TRI
eat_type ext_appl; /* this field can be set by an application program to */
/* refer to a user-defined entity. */
#endif
} quadrangle;
typedef struct {
list_ind ind;
boolean ccw;
} loop_list;
typedef struct {
list_ind ind;
machine_double dist;
} distance;
typedef struct {
int index;
list_ind prev;
list_ind next;
int convex;
int original;
boolean bridge;
#ifdef NORMALS
int t_index;
int n_index;
#endif
#ifdef STAGES
int stage;
#endif
#ifdef PARTITION_FIST
boolean delete_reflex;
#endif
} list_node;
typedef struct {
boolean color_graphics;
boolean graphics;
int step_size;
char input_file[256];
boolean read_input;
boolean read_poly;
boolean read_lines;
boolean read_obj;
boolean read_dxf;
boolean save_poly;
char output_file[256];
boolean write_dxf;
boolean verbose;
boolean quiet;
boolean scale_data;
boolean ears_sorted;
boolean ears_random;
boolean ears_fancy;
boolean ears_top;
boolean do_quads;
boolean keep_quads;
boolean keep_convex;
boolean write_geom;
boolean write_tri;
char tri_file[256];
char ipe_file[256];
boolean write_ipe7;
boolean c2p; /* convert to triangle's .poly format */
char c2p_file[256];
boolean help;
boolean time;
boolean statistics;
boolean copy;
boolean use_colors;
boolean draw_concave;
boolean sgi_output;
boolean draw_groups;
boolean full_screen;
int inputprec;
int mpfr_prec;
} rt_options;
/* needed by memory.x moved globals to this struct *
* call InitXXXXDefaults(*ptr) to get the default initialization */
#define MAX_MEMORY_CURSOR 1024
typedef struct {
void *array_ptr;
size_t size;
unsigned int high;
} memory_dbg;
typedef struct {
unsigned long curr_memory;
unsigned long max_memory;
memory_dbg memory_history[MAX_MEMORY_CURSOR];
int memory_dbg_cursor;
} debug_memdef;
/* needed by list.x moved globals to this struct listdef *
* call InitListDefaults(*list) to get the default initialization */
typedef struct {
list_node *list;
int num_list;
int max_num_list;
list_ind *loops;
int num_loops;
int max_num_loops;
int *faces;
int num_faces;
int max_num_faces;
list_ind first_node;
list_ind *chains;
int num_chains;
int max_num_chains;
debug_memdef *memptr;
} listdef;
/* needed by bridge.x moved globals to this struct *
* call InitXXXXDefaults(*ptr) to get the default initialization */
typedef struct {
list_ind ind;
int index;
} left;
typedef struct {
distance *distances;
int max_num_dist;
left *left_most;
int max_num_left_most;
debug_memdef *memptr;
} bridgedef;
/* needed by vertex.x moved globals to this struct *
* call InitXXXXDefaults(*ptr) to get the default initialization */
typedef struct {
#ifdef NORMALS
vertex *t_vertices;
int num_t_vertices;
int max_num_t_vertices;
vertex *v_normals;
int num_v_normals;
int max_num_v_normals;
i_triangle *i_triangles;
int num_i_triangles;
int max_num_i_triangles;
#endif
vertex *vertices;
int num_vertices;
int max_num_vertices;
triangle *triangles;
int num_triangles;
int max_num_triangles;
quadrangle *quads;
int num_quads;
int max_num_quads;
int *groups;
int num_groups;
int max_num_groups;
int num_group_tris;
int *group_tris;
int *group_quads;
int *group_loops;
loop_list *convex_loops;
int num_convex_loops;
int num_concave_loops;
int max_num_convex_loops;
debug_memdef *memptr;
} vertexdef;
/* needed by data.x moved globals to this struct *
* call InitXXXXDefaults(*ptr) to get the default initialization */
typedef struct {
point *points;
int num_pnts;
int max_num_pnts;
boolean data_scaled;
double scale_factor;
point shift;
machine_double bbox_diagonal_sqd;
debug_memdef *memptr;
} datadef;
/* needed by clean_data.x moved globals to this struct *
* call InitXXXXDef(*ptr) to get the default initialization */
typedef struct {
point p;
list_ind ind;
} sort_record;
typedef struct {
sort_record *p_unsorted;
int max_num_p_unsorted;
debug_memdef *memptr;
} cleandef;
/***************************** grid.x structs ***************************/
typedef int seg_ind;
typedef int pnt_ind;
typedef struct {
int imin; /* lexicographically smaller point, determines min-x */
int imax; /* lexicographically larger point, determines max-x */
double ymin; /* minimum y-coordinate */
double ymax; /* maximum y-coordinate */
boolean checked; /* has this segment already been checked? */
} segment; /* boundary segment i1, i2, with i1 < i2 */
typedef struct {
int seg;
seg_ind next;
} segment_node;
typedef struct {
int pnt;
pnt_ind next;
} pnt_node;
typedef struct {
int ident_cntr;
#ifdef STATISTICS
unsigned machine_long pnt_tri_cntr;
#endif
boolean no_grid_yet;
seg_ind *grid;
int max_num_grid;
pnt_ind *grid2;
int max_num_grid2;
pnt_ind *grid3;
int max_num_grid3;
int N, N_x, N_y;
int N2, N_x2, N_y2;
int N3, N_x3, N_y3;
double_global grid_x, grid_y;
double_global grid_min_x, grid_min_y, grid_max_x, grid_max_y;
double *raster_x;
double *raster_y;
double_global grid_x2, grid_y2;
double_global grid_min_x2, grid_min_y2, grid_max_x2, grid_max_y2;
double *raster_x2;
double *raster_y2;
double_global grid_x3, grid_y3;
double_global grid_min_x3, grid_min_y3, grid_max_x3, grid_max_y3;
double *raster_x3;
double *raster_y3;
int max_num_raster_x;
int max_num_raster_y;
int max_num_raster_x2;
int max_num_raster_y2;
int max_num_raster_x3;
int max_num_raster_y3;
segment *segments;
int num_segments;
int max_num_segments;
segment_node *seg_list;
int num_seg_list;
int max_num_seg_list;
pnt_node *pnt_list;
int num_pnt_list;
int max_num_pnt_list;
pnt_node *vtx_list;
int num_vtx_list;
int max_num_vtx_list;
int *set;
int max_num_set;
int num_set;
double_global step_x, step_y;
double_global delta_x, delta_y;
int num_reflex;
int num_original_reflex;
boolean buckets_initialized;
debug_memdef *memptr;
} griddef;
/************************* END grid.x structs ***************************/
typedef struct {
segment *seg_addr;
int seg_i;
seg_ind ind_seg;
} gridtmp;
/* needed by quads.x moved globals to this struct *
* call InitXXXXDefaults(*ptr) to get the default initialization */
typedef struct {
int v1;
int v2;
int tri;
} edge;
typedef struct {
int v1;
int v2;
int tri;
int next;
} hash_table;
typedef struct {
int num_grouped;
int *heads;
int max_num_heads;
hash_table *table;
hash_table *element;
int num_table;
int max_num_table;
} quaddef;
typedef struct {
machine_double x;
machine_double y;
} coord;
/* needed by io_basic.x moved globals to this struct *
* call InitXXXXDefaults(*ptr) to get the default initialization */
typedef struct {
int first_pnt, last_pnt, new_pnts, curr_loop, poly_vertex_number;
list_ind last_ind;
} iolistdef;
/* needed by io_3D.x moved globals to this struct *
* call InitXXXXDefaults(*ptr) to get the default initialization */
typedef struct {
int r;
int g;
int b;
} rgb;
typedef struct {
boolean draw_concave;
boolean sgi_output;
boolean draw_groups;
rgb color;
#ifdef NORMALS
boolean tex_norm_data_exists;
boolean vertex_normals;
boolean texture_vertices;
#endif
} io_3ddef;
/* needed by redraw.x moved globals to this struct *
* call InitXXXXDefaults(*ptr) to get the default initialization */
typedef struct {
int index;
int color;
} pnt_buffer;
typedef struct {
int index1;
int index2;
int color;
} edge_buffer;
typedef struct {
int index1;
int index2;
int index3;
int color1;
int color2;
} tri_buffer;
typedef struct {
pnt_buffer *pnt_buf;
edge_buffer *edge_buf;
tri_buffer *tri_buf;
int num_pnt_buf, max_num_pnt_buf;
int num_edge_buf, max_num_edge_buf;
int num_tri_buf, max_num_tri_buf;
debug_memdef *memptr;
} redrawdef;
/* needed by ipe_io.x moved globals to this struct *
* call InitXXXXDefaults(*ptr) to get the default initialization */
typedef struct {
machine_double scale;
machine_double ipe_x_min, ipe_x_max, ipe_y_min, ipe_y_max;
machine_double x_min, x_max, y_min, y_max;
boolean ipe7;
} ipe_iodef;
/* needed by predicates.x moved globals to this struct */
#ifdef JRC_PREDICATE
typedef struct {
/* = 2^ceiling(p / 2) + 1. Used to split floats in half. */
double splitter;
double epsilon; /* = 2^(-p). Used to estimate roundoff errors. */
/* A set of coefficients used to calculate maximum roundoff errors. */
double resulterrbound;
double ccwerrboundA, ccwerrboundB, ccwerrboundC;
double o3derrboundA, o3derrboundB, o3derrboundC;
double iccerrboundA, iccerrboundB, iccerrboundC;
double isperrboundA, isperrboundB, isperrboundC;
} predicatesdef;
#endif
/* needed by heap.x moved globals to this struct *
* call InitXXXXDefaults(*ptr) to get the default initialization */
typedef struct hnode {
machine_double ratio;
list_ind index;
list_ind prev;
list_ind next;
} heap_node;
typedef struct {
boolean ears_sorted;
boolean ears_random;
heap_node *heap;
int num_heap;
int max_num_heap;
int num_zero;
boolean deleted;
boolean not_updated;
boolean sorted;
boolean ear_right;
#ifdef PARTITION_FIST
int heap_idx;
#endif
debug_memdef *memptr;
} heapdef;
/* needed by ear_clip.x moved globals to this struct *
* call InitXXXXDefaults(*ptr) to get the default initialization */
typedef struct {
boolean ears_fancy;
boolean ears_top;
boolean use_colors;
int tri_color; /* 0 ... output triangle equals input triangle */
/* 1 ... output triangle belongs to input quad */
/* 2 ... output triangle belongs to convex face */
/* 3 ... output triangle belongs to concave face */
boolean is_convex_polygon;
boolean ears_may_have_changed;
} eardef;
/* needed by macros in numerics.h */
typedef struct {
point numerics_h_p, numerics_h_q, numerics_h_r;
double numerics_h_det, numerics_h_dot;
int numerics_h_ori1, numerics_h_ori2;
} tmp_data_def;
typedef struct {
pnt_ind ind_pnt, ind_pnt1;
list_ind ind_vtx;
} tmp_grid_def;
typedef struct {
#ifdef CUDA
/* not jet used */
#endif
} cudadef;
typedef enum {
SUCCESS,
MEM_ALLOC_FAILED,
FILE_ACCESS_FAILED,
INSUFFICENT_INPUT,
EOF_ENCOUNTERED,
WRONG_INPUT_OPTION,
WRONG_OBJ_FORMAT,
MEM_TRACKING_EXHAUSTED,
MEM_REALLOC_MISMATCH,
MEM_TRACKING_MESSED_UP,
MEM_TYPE_MISMATCH,
MEM_NULL_POINTER,
IPE_FILE_NOT_INITIALIZED,
IPE_FILE_INIT_FAILED,
UNKNOWN_ERROR
} errordef;
/* global_struct for ALL globals */
/* all former globals are packed into this struct */
typedef struct {
rt_options rt_opt; /* run-time options */
iolistdef c_iolist; /* globals from basic.x */
listdef c_list; /* globals from list.x */
bridgedef c_bridge; /* globals from bridge.x */
vertexdef c_vertex; /* globals from vertex.x */
datadef c_data; /* globals from data.x */
cleandef c_clean; /* globals from clean_data.x */
griddef c_grid; /* globals from grid.x */
quaddef c_quad; /* globals from quads.x */
io_3ddef c_io3d; /* globals from io_3D.x */
#ifdef GRAPHICS
redrawdef c_redraw; /* globals from redraw.x */
#endif
ipe_iodef c_ipe_io; /* globals from ipe_io.x */
cudadef c_cuda; /* globals for ./gpu/.x */
#ifdef JRC_PREDICATE
predicatesdef c_pred; /* globals from predicates.x */
#endif
#ifdef DEBUG_MEMORY
debug_memdef c_mem; /* globals from memory.x */
#else
void *c_mem;
#endif
eardef c_ear; /* globals from ear_clip.x */
#ifdef PARTITION_FIST
boolean partition_mode;
int number_of_heaps;
list_ind *corner_nodes;
heapdef *c_heap; /* globals from heap.x */
#else
heapdef c_heap; /* globals from heap.x */
#endif
point bb_min;
point bb_max;
#ifdef GRAPHICS
boolean draw_pnts;
boolean draw_point_idx;
#endif
boolean is_convex_face;
int num_contours;
unsigned machine_long bb_cntr;
unsigned machine_long cell_cntr;
boolean ccw_loop;
boolean isolated_pnts;
int io_flag;
machine_double x_delta, y_delta;
boolean new_input;
boolean done;
boolean reset;
boolean troubles;
boolean written;
machine_double cpu_time;
#ifndef NO_CPUTIME
timeval start, end;
#endif
FILE *dxf_file;
int curr_loop_main; /* main.c's separate curr_loop */
/* from orientation.c */
double *poly_area;
int max_num_poly_area;
#ifdef CPUTIME_IN_MILLISECONDS
unsigned long total_secs;
unsigned long total_usecs;
#else
#ifdef CPUTIME_VIA_CLOCK
clock_t total_cpu_time;
boolean cpu_time_initialized;
#else
long total_cpu_time;
#endif
#endif
/* from write_ipe.c */
boolean ipe_initialized;
#ifdef EXPR_WRAPPER
boolean returncore;
#endif
} global_struct;
/* ------------------------------ END global_struct ------------------------ */
/* */
/* get the definitions for "exterior applications" */
/* */
#include "ext_appl_defs.h"
#define TriTriColor 0 /* 0 ... output triangle equals input triangle */
#define TriQuadColor 1 /* 1 ... output triangle belongs to input quad */
#define TriCvxColor 2 /* 2 ... output triangle belongs to convex face */
#define TriCveColor 3 /* 3 ... output triangle belongs to concave face */
#ifdef DOUBLE_OVERRIDE /* if the CORE library is used */
const double C_0_0 = STRING_TO_REAL("0.0");
const double C_0_1 = STRING_TO_REAL("0.1");
const double C_0_3 = STRING_TO_REAL("0.3");
const double C_1_0 = STRING_TO_REAL("1.0");
const double C_1_1 = STRING_TO_REAL("1.1");
const double C_2_0 = STRING_TO_REAL("2.0");
const double C_m2_0 = STRING_TO_REAL("-2.0");
const double C_3_0 = STRING_TO_REAL("3.0");
const double C_4_0 = STRING_TO_REAL("4.0");
const double C_20_0 = STRING_TO_REAL("20.0");
#else
#define C_0_0 0.0
#define C_0_1 0.1
#define C_0_3 0.3
#define C_1_0 1.0
#define C_1_1 1.1
#define C_2_0 2.0
#define C_m2_0 -2.0
#define C_3_0 3.0
#define C_4_0 4.0
#define C_20_0 20.0
#endif
/* */
/* Some constants are used in expressions that need pure machine_double */
/* constants. So above constants cannot be used in conjunction with */
/* defined(WITH_COREBACKEND). The following constants can be used instead. */
/* */
#define CD_0_0 0.0
#define CD_0_001 0.001
#define CD_0_01 0.01
#define CD_0_05 0.05
#define CD_0_3 0.3
#define CD_1_0 1.0
#define CD_m1_0 -1.0
#define CD_1_5 1.5
#define CD_2_0 2.0
#define CD_2_5 2.5
#define CD_3_0 3.0
#define CD_20_0 20.0
#define CD_1000_0 1000.0
/*
* global precision thresholds
*
* ZERO ... "small" number used for checking whether a value equals zero
* (in order to avoid a division by zero). if set to 0.0 then
* any number other than 0.0 is regarded as a legitimate
* denumerator. please note that this may cause a numerical
* overflow! thus, please think twice prior to changing the
* default value of ZERO!!
*
* EPS ... used for comparisons with zero; if set to 0.0 then grazing
* contacts are likely to be mishandled. however, the code
* should not crash, and a small speed-up can be expected. in
* particular, setting EPS to 0.0 causes the comparison macros
* (lt, le, ... see martin.h) to function like their conventional
* counterparts if such a macro is supplied with EPS as the
* precision threshold to be used. very likely, it is best not
* to change the default value of EPS! the main use of this
* threshold is for the evaluation of 3x3 determinants, i.e.,
* for the computation of the sign of the signed area of a
* triangle defined by three (input) points. (virtually all
* predicates used by FIST boil down to the computation of
* the signed area of a triangle.) three points are considered
* collinear if the absolute value of the area of the
* corresponding triangle is less than or equal to EPS.
* depending on whether or not the run-time option "--scale"
* is used, those areas are computed relative to the original
* coordinates of the input points, or relative to scaled
* copies of the input points. (if requested by the user,
* scaling is performed such that the input data ends up in
* [-1,1]x[-1,1].) note that setting EPS to a non-zero value
* is a must if the compile-time option --DGRAZING is used;
* see Imakefile for an explanation. (what is a good value for
* EPS depends on your data and your intended application; the
* value defined below seems to work for a wide range of data.
* however, it is obvious that there may exist applications for
* which a user might want to be more liberal or more conservative
* in allowing FIST to classify items as degenerate. one way or
* the other, FIST should not crash!)
*/
#ifdef DOUBLE_OVERRIDE
/* In case of using the MPFR backend, EPS and ZERO need to be set according the
* MPFR precision, which is set at runtime. So EPS and ZERO need to be global
* variables.
*/
#if defined(WITH_MPFRBACKEND) || defined (WITH_EXPR_WRAPPER)
extern double EPS;
extern double ZERO;
#define ZERO_D 1.0e-16
#else /* so we are using an exact backend */
const double EPS = STRING_TO_REAL("0.0");
const double ZERO = STRING_TO_REAL("0.0");
#define ZERO_D 0.0
#endif
#else /* DOUBLE OVERRIEDE */
#ifdef THRESHOLD
#define THRES 1.0e-5
#define EPS 1.0e-15
#define ZERO 1.0e-16
#define ZERO_D 1.0e-16
#else /* don't even think about using this else branch! */
#define THRES 0.0
#define EPS 0.0
#define ZERO 0.0
#define ZERO_D 0.0
#endif /* THRESHOLD */
#endif /* DOUBLE OVERRIDE */
#ifdef MEM_COPY
/* */
/* unfortunately, the following stuff is needed in order to make FIST comply */
/* with CORE's memory re-allocation... */
/* */
#include <stdlib.h>
#include <stdio.h>
template <class DATATYPE>
DATATYPE* ReallocateArray_Copy(DATATYPE* old_mem, int old_size, int new_size, size_t size, const char var_name[])
{
DATATYPE* new_mem = NULL;
if (old_mem != NULL)
{
new_mem = new DATATYPE[new_size];
if (new_mem != NULL)
{
for (int i = 0; i < old_size; i++)
new_mem[i] = old_mem[i];
delete []old_mem;
}
else
{
fprintf(stderr, "*** Array `%s' cannot be reallocated! ***\n", var_name);
fprintf(stderr, "*** Cannot get %d elements of %lu bytes... ***\n", new_size, (unsigned long) size);
exit(1);
}
}
else
{
new_mem = new DATATYPE[new_size];
if (new_mem == NULL)
{
fprintf(stderr, "*** Array `%s' cannot be reallocated! ***\n", var_name);
fprintf(stderr, "*** Cannot get %d elements of %lu bytes... ***\n", new_size, (unsigned long) size);
exit(1);
}
}
return new_mem;
}
template <class DATATYPE>
void FreeMemory_Copy(DATATYPE** ptr, const char *)
{
if (*ptr == NULL) return;
delete []*ptr;
*ptr = NULL;
}
#define CORE_ReallocateArray(mem, array, old_size, new_size, type, var_name) \
ReallocateArray_Copy((array), (old_size), \
(new_size), sizeof(type), (var_name))
#define CORE_FreeMemory(mem, array, var_name) FreeMemory_Copy((array), (var_name))
#else /* MEM_COPY */
#define CORE_ReallocateArray(mem, array, old_size, new_size, type, var_name) \
(type *) ReallocateArray((mem), (array), (new_size),\
sizeof(type), (var_name))
#define CORE_FreeMemory(mem, array, var_name) \
FreeMemory((mem), (void**)(array), (var_name))
#endif /* MEM_COPY */
#endif /* FIST_DEFS_H */
+156
View File
@@ -0,0 +1,156 @@
/*****************************************************************************/
/* */
/* 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. */
/* */
/*****************************************************************************/
#ifndef EXT_APPL_DEFS
#define EXT_APPL_DEFS
/* */
/* the following data types are used for user-defined entities that are to */
/* be stored as part of my data structures. you are welcome to redefine them */
/* according to your needs. however, please note that it is your task to */
/* make sure that the functions and macros for I/O operations are modified */
/* accordingly in io_parse.c !! also, you'd need to redefine the constants */
/* eas_NIL, and eat_NIL in the file ext_appl_defs.c to whatever constant */
/* integral value or structure that can be used for initializing the */
/* exterior application structures. see the sample use for eas_... below. */
/* */
#ifdef EXT_APPL_SITES
#define EXT_APPL_PNTS
typedef int eas_type; /* ext. appl. hook for point and vertex */
typedef int eap_type; /* needed for compatibility with VRONI */
#endif
#ifdef EXT_APPL_TRI
typedef int eat_type; /* ext. appl. hook for triangle and quadrangle */
#endif
/*
* sample user-specific eas data:
*
* typedef struct {
* long id;
* char ch[10];
* } eas_type;
*/
#ifdef EXT_APPL_SITES
extern const eas_type eas_NIL;
extern const eap_type eap_NIL;
#endif
#ifdef EXT_APPL_TRI
extern const eat_type eat_NIL;
#endif
/* */
/* macro definitions for application-specific macros */
/* */
#define ExtApplFuncStoreTri_1
#define ExtApplFuncStoreTri_2
#define ExtApplFuncStoreQuad
#define ExtApplFuncStoreVNormal
#define ExtApplFuncStoreTVertex
#define ExtApplFuncStoreVertex
#define ExtApplFuncStorePnt
#define ExtApplFuncNewInput
#define ExtApplFuncDesperate
#define ExtApplFuncReligious
#define ExtApplFuncRestart
#define ExtApplFuncDoneOneChain
#define ExtApplFuncNextChain
#define ExtApplFuncFinished
#define ExtApplFuncTerminateProg
#define ExtApplFuncResetAll
#define ExtApplFuncNewPoly
#define ExtApplFuncNewFace
#define ExtApplFuncBeforeTriangulation
#define ExtApplFuncDesperate3D
#define ExtApplFuncReligious3D
#define ExtApplFuncRestart3D
#define ExtApplFuncDoneOneChain3D
#define ExtApplFuncNextChain3D
#define ExtApplFuncDoneOneFace
#define ExtApplFuncDoneOneGroup
#define ExtApplFuncFinished3D
#define ExtApplFuncStartPoly
#define ExtApplFuncClosePoly_1
#define ExtApplFuncClosePoly_2
#define ExtApplFuncAddPolyVertex_1
#define ExtApplFuncAddPolyVertex_2
#define ExtApplFuncAddPolyVertex_3
#define ExtApplFuncAddPolyVertex_4
#define ExtApplFuncFISTWarning
#define ExtApplFuncStoreIsoPnt
#define ExtApplFuncHandlePolyhedronStart
#define ExtApplFuncHandlePolyhedronEnd
#define ExtApplFuncHandlePolygonEnd
#define ExtApplFuncHandlePolygonStart
#define ExtApplFunc2D_PolyArrayEnd
#define ExtApplFunc2D_PolyArrayStart
#define ExtApplFunc3D_FaceArrayEnd
#define ExtApplFunc3D_FaceArrayStart
#define ExtApplFuncTerminateTriangulation
#define ExtApplFuncFIST_HandleError
#endif /* EXT_APPL_DEFS */
+335
View File
@@ -0,0 +1,335 @@
#ifndef FPKERNEL_H
#define FPKERNEL_H
#include<cfloat>
namespace {
const double fpkernel_DBL_MAX = DBL_MAX;
}
#ifdef WITH_EXPR_WRAPPER
#define DOUBLE_OVERRIDE
typedef double machine_double;
#include <ExprWrapper.h>
#include <formattedIO.h>
#define double ExprWrapper::ExprWrapper
#define double_global ExprWrapper::ExprWrapper
#define REAL_TO_INT(x) (x).intValue()
#define TO_MDOUBLE(x) (x).doubleValue()
#define REAL_TO_FLOAT(x) (x).floatValue()
#define DOUBLE_TO_IOMDOUBLE(x) (x).doubleValue()
#define MDOUBLE_TO_IOMDOUBLE(x) (x)
#define SET_PRECISION(var, prec) var.set_k2precision(prec)
#define SET_CORE_MPFR_KERNEL(var, valk1, valk2, name) var.set_k1k2val(valk1, valk2, name)
#define SET_MPFR_KERNEL_PI(var) var.set_k2pi()
//atof
#define FP_atof double
#define shift a68fe7dac8c32f30ad04d52fab4aa46be1068d82
#elif defined(WITH_COREBACKEND)
/* Set CORE Level to 4. Otherwise all unsigned long no longer work */
#define CORE_LEVEL 4
#include<CORE/CORE.h>
#include <formattedIO.h>
#undef double
#define double Expr
#define double_global Expr
#define double_arg const double &
//This is used to indicate that double gets a different meaning!
#define DOUBLE_OVERRIDE
#define TO_MDOUBLE(x) (x).doubleValue()
inline CORE::BigInt cut_comma(const Expr & x) {
CORE::BigInt v = floor(x);
if(v < 0) {
return v + 1;
} else {
return v;
}
}
#include "coreatan2.h"
inline int intfloor(const Expr & e) {
return floor(e).intValue();
}
inline unsigned int uintceil(const Expr & e) {
return (unsigned)ceil(e).intValue();
}
//REAL_TO_INT behaves like (int)(x)
#define REAL_TO_INT(x) cut_comma(x).intValue()
#define REAL_TO_GLINT(x) cut_comma(x).intValue()
#define REAL_TO_FLOAT(x) (x).floatValue()
#define BIGINT_TO_INT(x) (x).intValue()
#define TO_REAL(x) double(x)
#define STRING_TO_REAL(x) double(x)
#define DOUBLE_TO_IOMDOUBLE(x) (x).doubleValue()
#define MDOUBLE_TO_IOMDOUBLE(x) (x)
//atof
#define FP_atof double
//Definitions for functions undefined in CORE
#define isnan(x) 0
//#define atan2(y,x) atan2local((y),(x))
#define signbit(x) (x < 0 ? 1 : 0)
#define CORE_EXPR_OPS(name, x) { \
std::map<std::string, unsigned int > m; \
(x).rep()->rekCollectOp(m); \
for(std::map<std::string, unsigned int>::iterator it = m.begin(); it != m.end(); ++it) { \
std::cout << it->second << "\t: " << it->first << std::endl; \
}}
#ifdef WITH_CORE_EXPR_WRAPPER
inline void CORE_EXPR_SEQ(std::string name, const Expr & x) {
std::map<unsigned int, std::string > m;
(x).rep()->rekSequen(m);
for (std::map<unsigned int, std::string>::iterator it = m.begin(); it != m.end(); ++it) {
std::cout << it->second << std::endl;
}
}
inline void CORE_EXPR_DEBUG1(std::string name, const Expr & x) {
std::cout << name << " depth: " << (x).rep()->getDepth() << std::endl;
std::cout << name << " elementCount: " << (x).rep()->getElementCount() << std::endl;
CORE_EXPR_SEQ(name, (x));
std::cout << name << " value: " << (x) << std::endl;
}
#endif
// The second argument is the SHA1sum of "shift\n". This avoids a
// conflict with a shift function in CORE - VRONI uses some
// variables named shift
#define shift a68fe7dac8c32f30ad04d52fab4aa46be1068d82
#elif defined(WITH_RABACKEND)
#include<Default_real_algebraic.hpp>
#include <formattedIO.h>
typedef double machine_double;
#undef double
#define double Default_real_algebraic
#define double_global Default_real_algebraic
#define double_arg const double &
//This is used to indicate that double gets a different meaning!
#define DOUBLE_OVERRIDE
inline machine_double TO_MDOUBLE(const double & x) {
x.guarantee_relative_error_two_to(-53);
return x.get_interval().get_median();
}
inline int cut_comma(const double & x) {
return (int)TO_MDOUBLE(x);
}
inline int intfloor(const double & e) {
int cut = cut_comma(e);
if ( e < 0) {
return cut - 1;
} else {
return cut;
}
}
inline double string_to_ra(const char * str) {
machine_double md = atof(str);
return double(md);
}
//inline unsigned int uintceil(const Expr & e) {
// return (unsigned)ceil(e).intValue();
//}
//REAL_TO_INT behaves like (int)(x)
#define REAL_TO_INT(x) cut_comma(x)
#define REAL_TO_GLINT(x) cut_comma(x)
#define REAL_TO_FLOAT(x) TO_MDOUBLE(x)
//#define BIGINT_TO_INT(x) (x).intValue()
#define TO_REAL(x) double(machine_double(x))
#define STRING_TO_REAL(x) string_to_ra(x)
#define DOUBLE_TO_IOMDOUBLE(x) TO_MDOUBLE(x)
#define MDOUBLE_TO_IOMDOUBLE(x) (x)
//atof
#define FP_atof STRING_TO_REAL
//Definitions for functions undefined in CORE
#define isnan(x) 0
//#define atan2(y,x) atan2local((y),(x))
#define signbit(x) (x < 0 ? 1 : 0)
// The second argument is the SHA1sum of "shift\n". This avoids a
// conflict with a shift function in CORE - VRONI uses some
// variables named shift
#define shift a68fe7dac8c32f30ad04d52fab4aa46be1068d82
#elif defined(WITH_MPFRBACKEND)
#include <mpfr_class.h>
typedef double machine_double;
#undef double
#ifdef WITH_EXPR_WRAPPER
#define WITH_MPFR_DOUBLE
#include<ExprWrapper.h>
#define double ExprWrapper::ExprWrapper
#define double_global ExprWrapper::ExprWrapper
#else
#define double Mpfr_class
#define double_global Mpfr_class_global
#endif /* WITH_EXPR_WRAPPER */
#define double_arg const double &
//This is used to indicate that double gets a different meaning!
#define DOUBLE_OVERRIDE
#define TO_MDOUBLE(x) (x).doubleValue()
#define REAL_TO_INT(x) (x).intValue()
#define REAL_TO_GLINT(x) (x).intValue()
#define REAL_TO_FLOAT(x) (x).floatValue()
#define TO_REAL(x) double(x)
#define STRING_TO_REAL(x) double(x)
#ifdef EXPR_WRAPPER
#define DOUBLE_TO_IOMDOUBLE(x) (x).odoubleValue()
#define MDOUBLE_TO_IOMDOUBLE(x) (x).doubleValue()
#else
#define DOUBLE_TO_IOMDOUBLE(x) (x).doubleValue()
#define MDOUBLE_TO_IOMDOUBLE(x) (x)
#endif
//atof
#define FP_atof double
#define SET_PRECISION(var, prec) var.set_precision(prec)
#define SET_CORE_MPFR_KERNEL(var, valk1, valk2, name) var = (valk2)
#define SET_MPFR_KERNEL_PI(var) var.set_pi()
#define SET_CORE_KERNEL(var,val)
inline void CORE_EXPR_DEBUG1(std::string , const double & ) {}
inline long intfloor(const double & e) {
#ifdef WITH_EXPR_WRAPPER
return (int)floor(e);
#else
return floor(e).intValue();
#endif
}
inline unsigned long uintceil(const double & e) {
#ifdef WITH_EXPR_WRAPPER
return (int)floor(e);
#else
return ceil(e).intValue();
#endif
}
//Definitions for functions undefined in CORE
#if WITH_EXPR_WRAPPER
#define is_nan(x) 0
#define sign_bit(x) (x < 0 ? 1 : 0)
#endif
#include <formattedIO.h>
#else /* no object-based numeric backend */
#include <math.h>
#define TO_MDOUBLE(x) (x)
#define DOUBLE_TO_IOMDOUBLE(x) (x)
#define MDOUBLE_TO_IOMDOUBLE(x) (x)
#define TO_MFLOAT(x) (x)
#define REAL_TO_INT(x) (int)(x)
#define REAL_TO_GLINT(x) (GLint)(x)
#define REAL_TO_FLOAT(x) (float)(x)
#define BIGINT_TO_INT(x) (x)
#define TO_REAL(x) (x)
//atof
#define FP_atof atof
#define machine_double double
#define double_global double
#define double_arg double
#ifdef __cplusplus
inline int intfloor(const double e) {
return (int)(floor(e));
}
inline unsigned int uintceil(const double e) {
return (unsigned)ceil(e);
}
#endif
#define CORE_EXPR_DEBUG1(x,y)
#define is_nan(x) isnan(x)
#define sign_bit(x) signbit(x)
#ifdef DOUBLE_OVERRIDE
#error "DOUBLE_OVERRIDE should not be defined here!"
#endif
#endif /* WITH_COREBACKEND */
/* Definitions that are equal among all numeric object backends */
#ifdef DOUBLE_OVERRIDE
//formattedIO
#define FP_printf formattedIO::fmc_printf
#define FP_fprintf formattedIO::fmc_fprintf
inline const double * FP_PRNTARG(const double & x) { return &x; }
//[sf]scanf methods
#define FP_fscanf formattedIO::cfscanf
#define FP_sscanf formattedIO::csscanf
#else /* DOUBLE_OVERRIDE */
//IO
#define FP_printf printf
#define FP_fprintf fprintf
#define FP_PRNTARG(x) (x)
//[sf]scanf methods
#define FP_fscanf fscanf
#define FP_sscanf sscanf
#endif
#endif /* FPKERNEL_H */
+44
View File
@@ -0,0 +1,44 @@
/*****************************************************************************/
/* */
/* 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. */
/* */
/*****************************************************************************/
#ifndef FIST_GRAPHICS_H
#define FIST_GRAPHICS_H
/* */
/* colors for OpenGL drawing */
/* */
#define NumColors 10
#define NoColor 0
#define Black 0
#define Green 1
#define ZeroColor 1
#define Blue 2
#define PntsColor 2
#define White 3
#define SplitColor 3
#define Red 4
#define TriColor 4
#define BridgeColor 4
#define Cyan 5
#define ConvexColor 5
#define Yellow 6
#define PolyColor 6
#define IsoPntsColor 6
#define Orange 7
#define TangentColor 7
#define Magenta 8
#define EarColor 8
#define Gray 9
#define TriFillColor 9
#endif /* FIST_GRAPHICS_H */
+485
View File
@@ -0,0 +1,485 @@
/*****************************************************************************/
/* */
/* 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. */
/* */
/*****************************************************************************/
#ifndef FIST_GRID_H
#define FIST_GRID_H
boolean InGrid3(griddef *grid, int cell);
#ifdef EXPR_WRAPPER
const ExprMD FUDGE = 1.0e-12;
#else
#define FUDGE 1.0e-12 /* purely for convenience purposes ;-) */
#endif
#define BLOCK_SIZE 32768
#define N_BUCKET CD_1_5
#define N_GRID CD_2_5
#define N_REFLEX 30
#define STR(x) #x
#define pragma_omp_critical_start(x) \
_Pragma( STR( omp critical (x) ) )
/* */
/* computes the bounding box of segments[low,..,high]. */
/* */
#define BBox_Compute(grid, tmp, low, high, bb) \
{ assert(InSegments(grid,low)); \
assert(InSegments(grid,high)); \
\
tmp.seg_addr = &(grid->segments[low]); \
BBox_Copy(*tmp.seg_addr, bb); \
for (tmp.seg_i = low+1; tmp.seg_i <= high; ++tmp.seg_i) { \
seg_addr = &(grid->segments[seg_i]); \
BBox_Enlarge(*tmp.seg_addr, bb); \
} \
}
#define ResetSet(grid, tmp) \
{ for (tmp.seg_i = 0; tmp.seg_i < grid->num_set; ++tmp.seg_i) { \
grid->segments[grid->set[tmp.seg_i]].checked = false; \
} \
grid->num_set = 0; \
}
#define AddToSet(grid, ind) \
{ if (grid->num_set >= grid->max_num_set) { \
grid->max_num_set += BLOCK_SIZE; \
grid->set = (int*) ReallocateArray(grid->memptr, grid->set, grid->max_num_set, sizeof(int), \
"grid:set"); \
}\
grid->set[grid->num_set] = ind; \
grid->segments[ind].checked = true; \
++grid->num_set; \
}
#define StoreSegment(data, grid, tmp, i1, i2) \
{ assert(InPointsList(data, i1)); \
assert(InPointsList(data, i2)); \
if (grid->num_segments >= grid->max_num_segments) { \
grid->max_num_segments += BLOCK_SIZE; \
grid->segments = CORE_ReallocateArray(grid->memptr, grid->segments, grid->max_num_segments - BLOCK_SIZE, \
grid->max_num_segments, segment, \
"grid:segments"); \
} \
tmp.seg_addr = &(grid->segments[grid->num_segments]); \
BBox(data, i1, i2, *tmp.seg_addr); \
tmp.seg_addr->checked = false; \
++grid->num_segments; \
}
#define InsertAfterSeg(grid, k, iseg) \
{ assert(InGrid(grid, k)); \
assert(InSegments(grid, iseg)); \
\
if (grid->num_seg_list >= grid->max_num_seg_list) { \
grid->max_num_seg_list += BLOCK_SIZE; \
grid->seg_list = (segment_node*) ReallocateArray(grid->memptr, grid->seg_list, grid->max_num_seg_list, \
sizeof(segment_node), \
"grid:seg_list"); \
} \
grid->seg_list[grid->num_seg_list].seg = iseg; \
grid->seg_list[grid->num_seg_list].next = grid->grid[k]; \
grid->grid[k] = grid->num_seg_list; \
++grid->num_seg_list; \
}
#define InsertAfterPnt(list, grid, data, k, ipnt) \
{ assert(InGrid2(grid, k)); \
assert(InPointsList(data, ipnt)); \
\
if (grid->num_pnt_list >= grid->max_num_pnt_list) { \
grid->max_num_pnt_list += BLOCK_SIZE; \
grid->pnt_list = (pnt_node*) ReallocateArray(grid->memptr, grid->pnt_list, grid->max_num_pnt_list, \
sizeof(pnt_node), \
"grid:pnt_list"); \
} \
\
grid->pnt_list[grid->num_pnt_list].pnt = ipnt; \
grid->pnt_list[grid->num_pnt_list].next = grid->grid2[k]; \
grid->grid2[k] = grid->num_pnt_list; \
++grid->num_pnt_list; \
}
#define InsertAfterVtx(list, grid, k, ivtx) \
{ assert(InGrid3(grid, k)); \
assert(InPolyList(list, ivtx)); \
\
if (grid->num_vtx_list >= grid->max_num_vtx_list) { \
grid->max_num_vtx_list += BLOCK_SIZE; \
grid->vtx_list = (pnt_node*) ReallocateArray(grid->memptr, grid->vtx_list, grid->max_num_vtx_list, \
sizeof(pnt_node), \
"grid:vtx_list"); \
} \
\
grid->vtx_list[grid->num_vtx_list].pnt = ivtx; \
grid->vtx_list[grid->num_vtx_list].next = grid->grid3[k]; \
grid->grid3[k] = grid->num_vtx_list; \
++grid->num_vtx_list; \
++grid->num_reflex; \
}
#define InsertAfterVtxCells(list, grid, k, ivtx, full_cells) \
{ assert(InGrid3(grid,k)); \
assert(InPolyList(list,ivtx)); \
\
if (grid->num_vtx_list >= grid->max_num_vtx_list) { \
grid->max_num_vtx_list += BLOCK_SIZE; \
grid->vtx_list = (pnt_node*) ReallocateArray(grid->memptr, grid->vtx_list, grid->max_num_vtx_list, \
sizeof(pnt_node), \
"grid:vtx_list"); \
} \
\
if (grid->grid3[k] == NIL) ++full_cells; \
grid->vtx_list[grid->num_vtx_list].pnt = ivtx; \
grid->vtx_list[grid->num_vtx_list].next = grid->grid3[k]; \
grid->grid3[k] = grid->num_vtx_list; \
++grid->num_vtx_list; \
++grid->num_reflex; \
}
#define DetermineCell(grid, x, y, i, j, ii, jj) \
{ \
assert(x > grid->grid_min_x); \
i = REAL_TO_INT(((x - grid->grid_min_x) / grid->grid_x)); \
if (x < grid->raster_x[i]) { \
ii = i; \
--i; \
} \
else if (x > grid->raster_x[i+1]) { \
ii = i; \
++i; \
} \
else { \
if (le(x - grid->raster_x[i], EPS)) ii = i - 1; \
else if (le(grid->raster_x[i+1] - x, EPS)) ii = i + 1; \
else ii = i; \
} \
assert((i >= 0) && (i < grid->N_x)); \
assert((ii >= 0) && (ii < grid->N_x)); \
\
assert(y > grid->grid_min_y); \
j = REAL_TO_INT(((y - grid->grid_min_y) / grid->grid_y)); \
if (y < grid->raster_y[j]) { \
jj = j; \
--j; \
} \
else if (y > grid->raster_y[j+1]) { \
jj = j; \
++j; \
} \
else { \
if (le(y - grid->raster_y[j], EPS)) jj = j - 1; \
else if (le(grid->raster_y[j+1] - y, EPS)) jj = j + 1; \
else jj = j; \
} \
assert((j >= 0) && (j < grid->N_y)); \
assert((jj >= 0) && (jj < grid->N_y)); \
}
#define DetermineCellStrict(grid, x, y, i, j) \
{ \
assert(x > grid->grid_min_x); \
i = REAL_TO_INT(((x - grid->grid_min_x) / grid->grid_x)); \
if (x < grid->raster_x[i]) { \
--i; \
} \
else if (x > grid->raster_x[i+1]) { \
++i; \
} \
assert((i >= 0) && (i < grid->N_x)); \
\
assert(y > grid->grid_min_y); \
j = REAL_TO_INT(((y - grid->grid_min_y) / grid->grid_y)); \
if (y < grid->raster_y[j]) { \
--j; \
} \
else if (y > grid->raster_y[j+1]) { \
++j; \
} \
assert((j >= 0) && (j < grid->N_y)); \
}
#define Convert(grid, i, j, k) \
{ k = i * grid->N_y + j; }
#define Convert2(grid, i, j, k) \
{ k = i * grid->N_y2 + j; }
#define Convert3(grid, i, j, k) \
{ k = i * grid->N_y3 + j; }
#define DetermineCell2(grid, x, y, i, j, ii, jj) \
{ \
assert(x > grid->grid_min_x2); \
i = REAL_TO_INT(((x - grid->grid_min_x2) / grid->grid_x2)); \
if (x < grid->raster_x2[i]) { \
ii = i; \
--i; \
} \
else if (x > grid->raster_x2[i+1]) { \
ii = i; \
++i; \
} \
else { \
if (x <= (grid->raster_x2[i] + grid->step_x)) ii = i - 1; \
else if (x >= (grid->raster_x2[i+1] - grid->step_x)) ii = i + 1; \
else ii = i; \
} \
assert((i >= 0) && (i < grid->N_x2)); \
if (ii < 0) ii = i; \
else if (ii >= grid->N_x2) ii = i; \
\
assert(y > grid->grid_min_y2); \
j = REAL_TO_INT(((y - grid->grid_min_y2) / grid->grid_y2)); \
if (y < grid->raster_y2[j]) { \
jj = j; \
--j; \
} \
else if (y > grid->raster_y2[j+1]) { \
jj = j; \
++j; \
} \
else { \
if (y <= (grid->raster_y2[j] + grid->step_y)) jj = j - 1; \
else if (y >= (grid->raster_y2[j+1] - grid->step_y)) jj = j + 1; \
else jj = j; \
} \
assert((j >= 0) && (j < grid->N_y2)); \
if (jj < 0) jj = j; \
else if (jj >= grid->N_y2) jj = j; \
}
#define DetermineCell3(grid, x, y, i, j, ii, jj) \
{ \
assert(x > grid->grid_min_x3); \
i = REAL_TO_INT((x - grid->grid_min_x3) / grid->grid_x3); \
if (x < grid->raster_x3[i]) { \
ii = i; \
--i; \
} \
else if (x > grid->raster_x3[i+1]) { \
ii = i; \
++i; \
} \
else { \
if (le(x - grid->raster_x3[i], EPS)) ii = i - 1; \
else if (le(grid->raster_x3[i+1] - x, EPS)) ii = i + 1; \
else ii = i; \
} \
assert((i >= 0) && (i < grid->N_x3)); \
if (ii < 0) ii = i; \
else if (ii >= grid->N_x3) ii = i; \
\
assert(y > grid->grid_min_y3); \
j = REAL_TO_INT((y - grid->grid_min_y3) / grid->grid_y3); \
if (y < grid->raster_y3[j]) { \
jj = j; \
--j; \
} \
else if (y > grid->raster_y3[j+1]) { \
jj = j; \
++j; \
} \
else { \
if (le(y - grid->raster_y3[j], EPS)) jj = j - 1; \
else if (le(grid->raster_y3[j+1] - y, EPS)) jj = j + 1; \
else jj = j; \
} \
assert((j >= 0) && (j < grid->N_y3)); \
if (jj < 0) jj = j; \
else if (jj >= grid->N_y3) jj = j; \
}
#define DetermineCell4(grid, x, y, i, j) \
{ \
assert(x > grid->grid_min_x3); \
i = REAL_TO_INT((x - grid->grid_min_x3) / grid->grid_x3); \
if (x < grid->raster_x3[i]) { \
--i; \
} \
else if (x > grid->raster_x3[i+1]) { \
++i; \
} \
assert((i >= 0) && (i < grid->N_x3)); \
\
assert(y > grid->grid_min_y3); \
j = REAL_TO_INT((y - grid->grid_min_y3) / grid->grid_y3); \
if (y < grid->raster_y3[j]) { \
--j; \
} \
else if (y > grid->raster_y3[j+1]) { \
++j; \
} \
assert((j >= 0) && (j < grid->N_y3)); \
}
#define Invert(grid, k, i, j) \
{ \
i = k / grid->N_y; \
assert((0 <= i) && (i < grid->N_x)); \
j = k - i * grid->N_y; \
assert((0 <= j) && (j < grid->N_y)); \
}
#ifdef PARTITION_FIST
#define DeleteFromCell(grid, tmp, k, i) \
{ \
tmp.ind_pnt = grid->grid3[k]; \
if(tmp.ind_pnt != NIL) {\
assert(InVtxList(grid,tmp.ind_pnt)); \
tmp.ind_vtx = grid->vtx_list[tmp.ind_pnt].pnt; \
if (tmp.ind_vtx == i) { \
pragma_omp_critical_start(DFC) {\
grid->grid3[k] = grid->vtx_list[tmp.ind_pnt].next; \
--grid->num_reflex; \
} \
} \
else { \
tmp.ind_pnt1 = grid->vtx_list[tmp.ind_pnt].next; \
while (tmp.ind_pnt1 != NIL) { \
assert(InVtxList(grid,tmp.ind_pnt1)); \
tmp.ind_vtx = grid->vtx_list[tmp.ind_pnt1].pnt; \
if (tmp.ind_vtx == i) { \
pragma_omp_critical_start(DFC) {\
grid->vtx_list[tmp.ind_pnt].next = grid->vtx_list[tmp.ind_pnt1].next; \
--grid->num_reflex; \
} \
tmp.ind_pnt1 = NIL; \
} \
else { \
tmp.ind_pnt = tmp.ind_pnt1; \
tmp.ind_pnt1 = grid->vtx_list[tmp.ind_pnt].next; \
} \
} \
} \
} \
}
#else
#define DeleteFromCell(grid, tmp, k, i) \
{ \
tmp.ind_pnt = grid->grid3[k]; \
if(tmp.ind_pnt != NIL) {\
assert(InVtxList(grid,tmp.ind_pnt)); \
tmp.ind_vtx = grid->vtx_list[tmp.ind_pnt].pnt; \
if (tmp.ind_vtx == i) { \
grid->grid3[k] = grid->vtx_list[tmp.ind_pnt].next; \
--grid->num_reflex; \
} \
else { \
tmp.ind_pnt1 = grid->vtx_list[tmp.ind_pnt].next; \
while (tmp.ind_pnt1 != NIL) { \
assert(InVtxList(grid,tmp.ind_pnt1)); \
tmp.ind_vtx = grid->vtx_list[tmp.ind_pnt1].pnt; \
if (tmp.ind_vtx == i) { \
grid->vtx_list[tmp.ind_pnt].next = grid->vtx_list[tmp.ind_pnt1].next; \
--grid->num_reflex; \
tmp.ind_pnt1 = NIL; \
} \
else { \
tmp.ind_pnt = tmp.ind_pnt1; \
tmp.ind_pnt1 = grid->vtx_list[tmp.ind_pnt].next; \
} \
} \
} \
} \
}
#endif
#define Deter2D(u, v, w) \
((u).x * ((v).y - (w).y) - (u).y * ((v).x - (w).x))
#ifdef GRAZING
#define ScanBridgeBucketCell(list, data, grid, k, i0, i1, ind1, ind_pnt, \
distances, num_dist, base, x_start) \
{ \
ind_pnt = grid->grid3[k]; \
while (ind_pnt != NIL) { \
assert(InVtxList(grid,ind_pnt)); \
ind1 = grid->vtx_list[ind_pnt].pnt; \
assert(InPolyList(list, ind1)); \
i1 = GetIndex(list, ind1); \
if (data->points[i1].x <= x_start) { \
PntPntDistSqd(data->points[i0], data->points[i1], base, \
distances[*num_dist].dist); \
distances[*num_dist].ind = ind1; \
++(*num_dist); \
} \
ind_pnt = grid->vtx_list[ind_pnt].next; \
} \
}
#else
#define ScanBridgeBucketCell(list, data, grid, k, i0, i1, ind1, ind_pnt, \
distances, num_dist, base) \
{ \
ind_pnt = grid->grid3[k]; \
while (ind_pnt != NIL) { \
assert(InVtxList(grid, ind_pnt)); \
ind1 = grid->vtx_list[ind_pnt].pnt; \
assert(InPolyList(list, ind1)); \
i1 = GetIndex(list, ind1); \
if (i1 <= i0) { \
if (i1 < i0) { \
PntPntDistSqd(data->points[i0], data->points[i1], base, distances[*num_dist].dist); \
} \
else { \
distances[*num_dist].dist = CD_0_0; \
} \
distances[*num_dist].ind = ind1; \
++(*num_dist); \
} \
ind_pnt = grid->vtx_list[ind_pnt].next; \
} \
}
#endif
#endif /* FIST_GRID_H */
+743
View File
@@ -0,0 +1,743 @@
/*****************************************************************************/
/* */
/* 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. */
/* */
/*****************************************************************************/
/* compute.cpp: */
#ifdef __cplusplus
extern "C" {
#endif
void Compute(global_struct *all);
#ifdef __cplusplus
}
#endif
void StatisticsFIST(global_struct *all);
#ifdef __cplusplus
extern "C" {
#endif
void ResetAll(global_struct *all);
#ifdef __cplusplus
}
#endif
/* memory.cpp: */
void *ReallocateArray(debug_memdef *mem, void *old_ptr, int number, size_t size,
const char var_name[]);
void FreeMemory(debug_memdef *mem, void **ptr, const char var_name[]);
void InitDebugMemDefaults(debug_memdef *mem);
unsigned machine_long ReportMaxNumberBytes(debug_memdef *mem);
unsigned machine_long ReportCurrNumberBytes(debug_memdef *mem);
boolean AllMemoryFreed(debug_memdef *mem);
void FreeMemory(debug_memdef *mem, void **ptr, const char var_name[]);
#ifdef DEBUG_MEMORY
boolean IndexOutOfBounds(debug_memdef *mem, void *array_ptr,
char var_name[], size_t size, int index);
#endif
/* data.cpp: */
void InitGlobalStruct(global_struct *all, rt_options *rt_opt,
boolean stand_alone);
void InitDataDefaults(datadef *data);
void ScaleData(global_struct *all);
#ifdef EXT_APPL_SITES
int StorePnt(datadef *data, double x, double y, eas_type ext_appl);
#else
int StorePnt(datadef *data, double x, double y);
#endif
void InitPnts(datadef *data, int number);
void FreePnts(datadef *data);
void DecrementPoints(datadef *data);
void SetBoundingBox(datadef *data, point *bb_min, point *bb_max);
void ComputeBoundingBox(datadef *data, listdef *list, list_ind ind, point *bb_min, point *bb_max);
boolean InPointsList(datadef *data, int index);
void InitStoragePnts(datadef *data, int number);
/* redraw.cpp: */
#ifdef GRAPHICS
void FreeGraphics(void);
void InitRedrawDefaults(redrawdef *redraw);
void ResetBufferData(redrawdef *redraw);
void Redraw(global_struct *all);
void AddPntToBuffer(redrawdef *redraw, int index, int color);
void AddEdgeToBuffer(redrawdef *redraw, int index1, int index2, int color);
void AddTriToBuffer(redrawdef *redraw, int index1, int index2, int index3,
int color1, int color2);
void DecrementPntBuffer(redrawdef *redraw);
void DecrementEdgeBuffer(redrawdef *redraw);
void FreeDrawingBuffer(redrawdef *redraw);
void ResetTriBuffer(redrawdef *redraw);
void UpdatePntEdgeBuffers(global_struct *all);
#ifdef PARTITION_FIST
void UpdateTriBuffer(global_struct *all);
#endif
#endif
/* graphics.cpp: */
#ifdef GRAPHICS
void UpdateScaleData(void);
void InitializeGraphics(int argc, char *argv[], global_struct *all);
void ProcessGraphicsEvents(void);
void DrawTri(point pnt1, point pnt2, point pnt3, int color1, int color);
void DrawSeg(point pnt1, point pnt2, int color);
void DrawPnt(point pnt, int color);
void ResetGraphicsData(void);
void DrawText(point pnt, int color, char* text);
#endif
/* io_parse.cpp: */
boolean ReadOptionalNumber(FILE *input, int *data);
boolean ReadOptionalCoord(FILE *input, double *xy);
boolean ReadNumber(FILE *input, int *data);
boolean ReadVectorData(FILE *input, double *xc, double *yc);
#ifdef EXT_APPL_SITES
boolean ReadPntData(FILE *input, double *xc, double *yc, eas_type *eas_data);
#else
boolean ReadPntData(FILE *input, double *xc, double *yc);
#endif
#ifdef EXT_APPL_SITES
void WritePntData(FILE *output, machine_double xc, machine_double yc,
eas_type *eas_data);
#else
void WritePntData(FILE *output, machine_double xc, machine_double yc);
#endif
void WriteNumber(FILE *output, int number);
void WriteVectorData(FILE *output, machine_double xc, machine_double yc);
/* io_basic.cpp: */
void InitIOListDefaults(iolistdef* iolist);
void ResetIOListData(iolistdef* iolist);
void Read2DInputData(global_struct *all);
void StartPoly(global_struct *all);
#ifdef EXT_APPL_SITES
void AddPolyVertex(global_struct *all, double xc1, double yc1, eas_type eas_data);
#else
void AddPolyVertex(global_struct *all, double xc1, double yc1);
#endif
void CloseCurrentPoly(global_struct *all);
void DXFStartPoly(global_struct *all);
void DXFAddPolyVertex(global_struct *all, double xc1, double yc1, double bulge);
void DXFCloseCurrentPoly(global_struct *all, double bulge);
void EnsureClosedPolygon(global_struct *all);
#ifdef EXT_APPL_SITES
int HandlePnt(global_struct *all,
double xc1, double yc1, eas_type ext_appl);
void HandleSeg(global_struct *all,
double xc1, double yc1, double xc2, double yc2,
eas_type ext_appl);
void HandleArc(global_struct *all,
double xc1, double yc1, double xc2, double yc2,
double xc3, double yc3, int attr, eas_type ext_appl);
#else
int HandlePnt(global_struct *all, double xc1, double yc1);
void HandleSeg(global_struct *all, double xc1, double yc1, double xc2, double yc2);
void HandleArc(global_struct *all,
double xc1, double yc1, double xc2, double yc2,
double xc3, double yc3, int attr);
#endif
/* io_dxf.cpp: */
void ReadDXFFile(global_struct *all);
void WriteDXFLWPoly_Vertex(global_struct *all, machine_double xc1, machine_double yc1,
machine_double bulge);
void WriteDXFLWPoly_Start(global_struct *all, boolean closed, int color);
void WriteDXFPoly_Vertex(global_struct *all, machine_double xc1, machine_double yc1,
machine_double bulge);
void WriteDXFPoly_Start(global_struct *all, boolean closed, int color);
void WriteDXFArc(global_struct *all,
machine_double xc1, machine_double yc1,
machine_double xc2, machine_double yc2,
machine_double xc3, machine_double yc3,
boolean ccw_flag, int color);
void WriteDXFCircle(global_struct *all,
machine_double xc1, machine_double yc1,
machine_double radius, int color);
void WriteDXFPoint(global_struct *all,
machine_double xc1, machine_double yc1, int color);
void WriteDXFLine(global_struct *all,
machine_double xc1, machine_double yc1,
machine_double xc2, machine_double yc2, int color);
void StartDXFFile(global_struct *all, char *file_name);
void FinishDXFFile(global_struct *all);
void WriteDXFPoly_End(global_struct *all);
/* io_misc.cpp: */
void CopyOutputData(vertexdef *vert, int *num_tri, int (*output_tri)[3]);
void CopyInputData2D(global_struct *all, int num_contours, int *num_vtx, double (*input_vtx)[2]);
void CopyInputData3D(global_struct *all, int num_contours, int *num_vtx, double (*input_vtx)[3]);
#ifdef __cplusplus
extern "C" {
#endif
void Help(void);
#ifdef __cplusplus
}
#endif
FILE *OpenFile(const char *file_name, const char *access);
void FIST_Warning(const char string[]);
void Copyright(void);
/* io_2D.cpp: */
void ReadPolygon(global_struct *all);
void ReadPoly(global_struct *all);
void ReadPolyLines(global_struct *all);
void WritePolygon(global_struct *all, char output_file[]);
void WriteFacesDXF(global_struct *all, char output_file[]);
void WritePolyFormat(global_struct *all);
/* io_3D.cpp: */
void Init3dDefaults(io_3ddef *io3d);
void WriteGeomOutput(global_struct *all);
void WriteFaces(global_struct *all, char output_file[]);
void ReadPolyhedron(global_struct *all, char input_file[]);
/* arg_eval.cpp: */
void InitDefaults(rt_options *rt_opt);
boolean ArgEval(int argc, char *argv[], rt_options *rt_opt);
#ifdef __cplusplus
extern "C" {
#endif
void EvalError(void);
#ifdef __cplusplus
}
#endif
/* list.cpp: */
void InitListDefaults(listdef* list);
void RemoveZeroEdges(listdef* list, list_ind *ind);
boolean GetBridgeNode(listdef* list, list_ind ind);
void SetBridgeNodePair(listdef* list, list_ind ind1, list_ind ind2);
int GetNumList(listdef* list);
void InitStorageList(listdef* list, int number);
void InitStorageLoops(listdef* list, int number);
void StoreChain(listdef* list, list_ind ind);
list_ind GetNextChain(listdef* list, boolean *done);
void ResetListData(listdef* list);
void RotateLinks(listdef* list, list_ind ind1, list_ind ind2);
void SplitSplice(listdef* list, list_ind ind1, list_ind ind2, list_ind ind3, list_ind ind4);
int GetOriginal(listdef* list, list_ind ind);
#ifdef NORMALS
void SetTexNormData(listdef* list, list_ind ind, int index1, int index2);
int GetNormalIndex(listdef* list, list_ind ind);
int GetTextureIndex(listdef* list, list_ind ind);
#endif
void SetOriginal(listdef* list, list_ind ind, int original);
void DeleteLinks(listdef* list, list_ind ind);
void InsertAfter(listdef* list, list_ind ind1, list_ind ind2);
list_ind MakeNode(listdef* list, int index);
#ifdef __cplusplus
extern "C" {
#endif
int MakeLoopHeader(listdef* list);
#ifdef __cplusplus
}
#endif
list_ind MakeHook(listdef* list);
void FreeList(listdef* list);
void DeleteHook(listdef* list, int curr_loop);
int CountListElements(listdef* list, list_ind ind1);
void DecrementLoops(listdef* list);
void UpdateIndex(listdef* list, list_ind ind, int index);
void SwapLinks(listdef* list, list_ind ind1);
boolean InPolyList(listdef* list, list_ind ind);
boolean InLoopList(listdef* list, int loop);
void ResetPolyList(listdef* list, list_ind ind);
list_ind GetNode(listdef* list);
void InitFace(listdef* list, int number);
void DecrementFaces(listdef* list);
#ifdef PARTITION_FIST
boolean isCorner(global_struct *all, int current_partition, list_ind ind);
#endif
/* clean_data.cpp: */
void InitCleanDefaults(cleandef *clean);
void CleanPolygon(global_struct *all, int *removed);
void CleanPolyhedralFace(global_struct *all, int loop_min, int loop_max, int *removed);
void FreeUnsorted(cleandef *clean);
/* numerics.cpp: */
#if defined(WITH_MPFRBACKEND) || defined(WITH_EXPR_WRAPPER)
void set_mpfrbackend_prec(mpfr_prec_t mpfr_prec, boolean verbose);
#endif
#ifdef JRC_PREDICATE
void exactinit();
#endif
boolean PntInTri(datadef *data, int i1, int i2, int i3, int i4, double *area);
boolean PntInTriClass(datadef *data, int i1, int i2, int i3, int i4, double *area,
int *pnt_on_edge);
double Angle(point p, point p1, point p2);
boolean InCone(int i, int j, int k, int l, boolean convex);
boolean SegIntersect(global_struct *all, int i1, int i2, int i3, int i4, int i5);
boolean SegIntersection(global_struct *all, int i1, int i2, int i3, int i4, int i5);
machine_double GetRatio(datadef *data, int i, int j, int k);
machine_double GetDoubleRatio(datadef *data, int i, int j, int k, int m);
double det2D(int i, int j, int k);
int orientation(int i, int j, int k);
void InitConstants(global_struct *all);
int SpikeAngle(listdef *list, datadef *data, int i, int j, int k, list_ind ind);
boolean PointInTriangle(int i1, int i2, int i3, int i4);
/* orientation.cpp: */
void AdjustOrientation(global_struct *all, int i1, int i2);
void DetermineOrientation(global_struct *all, list_ind ind);
double PolygonArea(global_struct *all, list_ind ind);
void FreeOrientation(global_struct *all);
/* ear_clip.cpp: */
void InitEarDefaults(eardef *ear);
boolean IsEar(global_struct *all, heapdef *hp, list_ind ind2, list_ind *ind1,
list_ind *ind3, machine_double *ratio);
void ClassifyEars(global_struct *all, list_ind ind);
void ClassifyAngles(global_struct *all, list_ind ind, int *num_reflex);
boolean ClipEar(global_struct *all, heapdef *hp, boolean *done);
void SetConvexityStatus(eardef *ear, boolean status);
void SetTangentNumber(int number);
void ResetEarStatus(eardef *ear);
/* heap.cpp: */
void InitHeapDefaults(heapdef *hp);
void FreeHeap(heapdef *hp);
void DumpOnHeap(heapdef *hp, machine_double ratio, list_ind ind, list_ind prev,
list_ind next);
void InsertIntoHeap(heapdef *hp, machine_double ratio, list_ind ind, list_ind prev,
list_ind next);
boolean DeleteFromHeap(heapdef *hp, list_ind *ind, list_ind *prev, list_ind *next);
void InitHeap(heapdef *hp, datadef *data);
#ifdef PARTITION_FIST
void InitPartitionedHeap(global_struct *all);
#endif
void MakeHeap(heapdef *hp);
/* vertex.cpp: */
void InitVertexDef(vertexdef* vert);
boolean InVertexList(vertexdef *vertex, int index);
void FreeVertices(vertexdef *verte);
void InitVertices(vertexdef *vert, int number);
#ifdef EXT_APPL_SITES
int StoreVertex(vertexdef *vert, double x, double y, double z, eas_type eas_data);
#else
int StoreVertex(vertexdef *vert, double x, double y, double z);
#endif
void FreeTriangles(vertexdef *vertex);
void StoreTriangle(global_struct *all, int i, int j, int k, int color);
int GetNumTriangles(vertexdef* vert);
void InitTriangles(vertexdef *vertex, int number);
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
/* misc.cpp: */
void Fake3D(global_struct *all);
/* desperate.cpp: */
boolean Desperate(global_struct *all, heapdef *hp, list_ind ind, int i, boolean *splitted);
boolean LetsHope(global_struct *all, heapdef *hp, list_ind ind);
void FreeDistances(bridgedef *bridge);
int WindingNumber(global_struct *all, list_ind ind, point p);
/* bridge.cpp: */
void InitBridgeDefaults(bridgedef* bridge);
void FindLeftMostVertex(listdef* list, list_ind ind, list_ind *left_ind, int *left_i);
void ConstructBridges(global_struct* all, int i1, int i2);
boolean FindBridge(global_struct *all, list_ind ind, int i, int start, list_ind *ind1, int *i1);
void InsertBridge(global_struct *all, list_ind ind1, int i1, list_ind ind3, int i3);
int d_comp();
void FreeBridges(bridgedef* bridge);
/* project.cpp: */
void ProjectFace(global_struct *all, int loop_min, int loop_max);
/* triangulate.cpp: */
void Triangulate(global_struct *all);
/* write_ipe.cpp: */
void WriteIpePolygon(global_struct *all);
void WriteIpeOutput(global_struct *all);
/* simple.cpp: */
boolean SimpleFace(global_struct *all, list_ind ind1, boolean ears_fancy);
boolean TrivialPolygon(global_struct *all, list_ind ind1);
/* elapsed.cpp: */
machine_double elapsed(global_struct *all);
/* grid.cpp: */
void InitGridDefaults(griddef *grid);
#ifdef GRAZING
void ScanBridgeBuckets(global_struct *all,
int i0, int grid_offset, distance *distances,
int *num_dist, boolean *grid_exhausted,
double x_start);
#else
void ScanBridgeBuckets(global_struct *all,
int i0, int grid_offset, distance *distances,
int *num_dist, boolean *grid_exhausted);
#endif
void ResetGrid(griddef *grid);
void InitBuckets(global_struct *all);
void InsertPntIntoBridgeBuckets(global_struct *all, list_ind ind1);
void BuildBridgeBuckets(global_struct *all, list_ind ind0, boolean init_grid);
boolean GridIntersectionExists(global_struct *all, bounding_box bb,
int i1, int i2,list_ind ind5, int i5);
void InsertSegmentIntoGrid(datadef *data, griddef *grid,
bounding_box bb);
void BuildGrid(global_struct *all, int loop_min, int loop_max);
void FreeGrid(griddef *grid);
machine_double TopQualityGrid(global_struct *all, int i1, int i2);
void BuildPntsGrid(global_struct *all, int loop_ind);
void BuildBuckets(global_struct *all, list_ind ind);
boolean BucketIntersectionExists(global_struct *all,
int i1, list_ind ind1, int i2, int i3,
bounding_box bb, int *i_close,
boolean check_close);
void SetReflexNumber(global_struct *all,int number);
void DeleteReflexVertex(global_struct *all, list_ind ind);
/* bottleneck.cpp: */
boolean CheckBottleNeck(global_struct *all, int i1, int i2, int i3, list_ind ind4);
/* quads.cpp: */
void InitQuadsDefaults(quaddef *quad);
void DetermineQuads(global_struct *all);
/* degenerate.cpp: */
boolean HandleDegeneracies(global_struct *all, int i1, list_ind ind1, int i2,
int i3, int i4,list_ind ind4);
/* thin.cpp: */
void Thin(char output_file[], boolean save_polygon, boolean new_input,
int keep_pnts, boolean time, double *cpu_time);
+28
View File
@@ -0,0 +1,28 @@
/*****************************************************************************/
/* */
/* 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. */
/* */
/*****************************************************************************/
/* */
/* I'm not sure whether those are indeed the colors used in DXF files. */
/* Unfortunately, I do not seem to be able to get my hands on a decent */
/* specification of DXF... */
/* */
#define DXF_NO_COLOR -1
#define DXF_RED 1
#define DXF_YELLOW 2
#define DXF_GREEN 2
#define DXF_CYAN 4
#define DXF_BLUE 5
#define DXF_MAGENTA 6
#define DXF_WHITE 7
+119
View File
@@ -0,0 +1,119 @@
/*****************************************************************************/
/* */
/* 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. */
/* */
/*****************************************************************************/
#ifndef DOUBLE_OVERRIDE
#define machine_double double
#define double_global double
#endif
#include "defs.h"
FILE *InitIpe(ipe_iodef *ipeio, const char *file_name,
machine_double xl, machine_double xr,
machine_double yl, machine_double yr);
void CloseIpeFile(FILE *ipe_file);
void WriteBeginGroup(FILE *ipe_file);
void WriteEndGroup(FILE *ipe_file);
void WriteEnd(FILE *ipe_file);
void WriteLineBegin(FILE *ipe_file, int dashed, machine_double width,
int no_vertices);
void WriteSegmentBegin(FILE *ipe_file, int dashed, machine_double width,
int no_vertices);
void WriteArcBegin(FILE *ipe_file, int dashed, machine_double width);
void WriteObjStroke(FILE *ipe_file,
machine_double r, machine_double g, machine_double b);
void WriteObjFill(FILE *ipe_file,
machine_double r, machine_double g, machine_double b);
void WriteArcCCW(ipe_iodef *ipeio, FILE *ipe_file, machine_double xc, machine_double yc,
machine_double r,
machine_double alpha, machine_double beta);
void WriteArcCW(ipe_iodef *ipeio, FILE *ipe_file, machine_double xc, machine_double yc,
machine_double r,
machine_double alpha, machine_double beta);
void WriteMark(ipe_iodef *ipeio, FILE *ipe_file,
machine_double r, machine_double g, machine_double b, int type,
machine_double size, machine_double x, machine_double y);
void WriteLineFirstPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y);
void WriteLineNextPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y);
void WriteSegmentFirstPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y);
void WriteSegmentNextPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y);
void WriteSegmentEndPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y);
void WriteSegmentClosePnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y);
void WriteSplineBegin(FILE *ipe_file, int dashed, machine_double width, int
no_vertices);
void WriteSplineFirstPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y);
void WriteSplineLastPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y);
void WriteSplineSecondPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y);
void WriteSplineNextPnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y);
void SetIpeDimensions(ipe_iodef *ipeio,
machine_double xmin, machine_double xmax,
machine_double ymin, machine_double ymax);
void SetWorldDimensions(ipe_iodef *ipeio,
machine_double xmin, machine_double xmax,
machine_double ymin, machine_double ymax);
void SetScaleFactor(ipe_iodef *ipeio);
void WritePnt(ipe_iodef *ipeio, FILE *ipe_file, machine_double x, machine_double y);
void InitIpeDimensions(ipe_iodef *ipeio,
machine_double xmin, machine_double ymin,
machine_double xmax, machine_double ymax,
machine_double ixmin, machine_double iymin,
machine_double ixmax, machine_double iymax);
void WriteLineSegment(ipe_iodef *ipeio, FILE *ipe_file,
machine_double r, machine_double g, machine_double b,
machine_double width, int dashed,
machine_double x1, machine_double y1,
machine_double x2, machine_double y2);
void WriteCircularArc(ipe_iodef *ipeio, FILE *ipe_file,
machine_double r, machine_double g, machine_double b,
machine_double width, int dashed,
machine_double xc, machine_double yc,
machine_double x1, machine_double y1,
machine_double x2, machine_double y2, boolean ccw);
void WriteDiscretizedCircularArc(ipe_iodef *ipeio, FILE *ipe_file,
machine_double xc, machine_double yc,
machine_double x1, machine_double y1,
machine_double x2, machine_double y2,
boolean ccw, machine_double delta,
int *num_segs);
+71
View File
@@ -0,0 +1,71 @@
/*****************************************************************************/
/* */
/* 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. */
/* */
/*****************************************************************************/
/* */
/* obtains the interior angle associated with IND */
/* */
#define GetAngle(LIST,IND) \
(\
assert(InPolyList(LIST,IND)), \
LIST->list[IND].convex)
#define SetAngle(LIST,IND, ANGLE ) \
{\
assert(InPolyList(LIST,IND)); \
LIST->list[IND].convex = ANGLE ; \
}
/* */
/* obtains the vertex index associated with IND */
/* */
#define GetIndex(LIST,IND) \
(\
assert(InPolyList(LIST,IND)), \
LIST->list[IND].index)
/* */
/* returns pointer to the successor of IND in the circular list of nodes */
/* */
#define GetNextNode(LIST,IND) \
(\
assert(InPolyList(LIST,IND)), \
LIST->list[IND].next)
/* */
/* returns pointer to the predecessor of IND in the circular list of nodes */
/* */
#define GetPrevNode(LIST,IND) \
(\
assert(InPolyList(LIST,IND)), \
LIST->list[IND].prev)
#ifdef STAGES
#define SetStage(LIST,IND, S) \
{\
assert(InPolyList(LIST,IND)); \
LIST->list[IND].stage = S; \
}
#define GetStage(LIST,IND) \
(\
assert(InPolyList(LIST,IND)), \
LIST->list[IND].stage)
#endif
+155
View File
@@ -0,0 +1,155 @@
/*****************************************************************************/
/* */
/* 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. */
/* */
/*****************************************************************************/
#ifndef _MARTIN_H_
#define _MARTIN_H_
#include "mydefs.h"
/* */
/* defines my boolean data type */
/* */
#ifdef BOOL_DEFINED
typedef bool boolean;
#else
#define false 0
#define true (!false)
typedef unsigned char boolean;
#endif
/* */
/* some useful constants; some of them might be defined in math.h... */
/* we initialize them differently depending on whether or not this code is */
/* to be used with the NYU's Core Library "CORE". */
/* */
#ifdef DOUBLE_OVERRIDE
#ifdef M_PI
#undef M_PI
#endif
#ifdef M_2PI
#undef M_2PI
#endif
#ifdef M_PI_180
#undef M_PI_180
#endif
#if (defined(WITH_COREBACKEND) || defined(WITH_RABACKEND)) && !defined(WITH_MPFRBACKEND)
const double M_PI = STRING_TO_REAL("3.14159265358979323846");
const double M_2PI = STRING_TO_REAL("6.28318530717958647693");
const double M_PI_180 = STRING_TO_REAL("0.01745329251994329576");
#else
extern double M_PI;
extern double M_2PI;
extern double M_PI_180;
#endif
#else
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef M_2PI
#define M_2PI 6.28318530717958647693
#endif
#ifndef M_PI_180
#define M_PI_180 0.01745329251994329576
#endif
#endif
/* */
/* Some constants are used in expressions that need pure machine_double */
/* constants. So above constants cannot be used in case */
/* defined(WITH_COREBACKEND). The following constants can be used instead: */
/* */
#ifndef MD_2PI
#define MD_2PI 6.28318530717958647693
#endif
#ifndef MD_PI
#define MD_PI 3.14159265358979323846
#endif
/* */
/* these macros are convenient... */
/* */
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Max(a, b) ((b) < (a) ? (a) : (b))
#define Min3(a, b, c) (((a) < (b)) ? \
(((a) < (c)) ? \
(a) : (c)) \
: \
(((b) < (c)) ? \
(b) : (c)))
#define Max3(a, b, c) (((a) < (b)) ? \
(((b) < (c)) ? \
(c) : (b)) \
: \
(((a) < (c)) ? \
(c) : (a)))
#define Min4(a, b, c, d) (((a) < (b)) ? \
(((a) < (c)) ? \
(((a) < (d)) ?\
(a) : (d)) \
: \
(((c) < (d)) ? \
(c) : (d))) \
: \
(((b) < (c)) ? \
(((b) < (d)) ? \
(b) : (d)) \
: \
(((c) < (d)) ? \
(c) : (d))))
#define Max4(a, b, c, d) (((a) < (b)) ? \
(((b) < (c)) ? \
(((c) < (d)) ?\
(d) : (c)) \
: \
(((b) < (d)) ? \
(d) : (b))) \
: \
(((a) < (c)) ? \
(((c) < (d)) ? \
(d) : (c)) \
: \
(((a) < (d)) ? \
(d) : (a))))
#define Sign(var,x) \
(var = x, \
((var > 0.0) ? 1 : ((var < 0.0) ? -1 : 0)))
#define Abs(x) (((x) >= 0.0) ? (x) : -(x))
#define Square(x) ((x) * (x))
/* #define xor(a, b) (!(a) ^ !(b)) */
#define Odd(x) ((x) % 2 == 1)
#define Even(x) (! Odd(x))
#define Swap(i1, i2, i) \
{i = i1; \
i1 = i2; \
i2 = i; }
#define Ceiling(x) \
(((x) == ((double) ((int) (x)))) ? ((int) (x)) : (1 + (int) (x)))
/* */
/* some macros for epsilon-based comparisons with respect to zero... */
/* */
#define lt(a, eps) ( ((a) < -eps) )
#define ge(a, eps) (! ((a) < -eps) )
#define le(a, eps) ( ((a) <= eps) )
#define gt(a, eps) (! ((a) <= eps) )
#define eq(a, eps) ( (((a) <= eps) && !((a) < -eps)) )
#define ne(a, eps) ( !((a) <= eps) || ((a) < -eps) )
#endif
+9
View File
@@ -0,0 +1,9 @@
#pragma once
// preprocessor definitions da usare per compilare correttamente
#define NO_CPUTIME
#define BOOL_DEFINED
#define RAND
#define THRESHOLD
#define GRAZING
+490
View File
@@ -0,0 +1,490 @@
/*****************************************************************************/
/* */
/* 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. */
/* */
/*****************************************************************************/
#define BaseLength(u, v, base, delta) { \
(base).x = (v).x - (u).x; \
(base).y = (v).y - (u).y; \
delta = Abs(TO_MDOUBLE((base).x)) + Abs(TO_MDOUBLE((base).y)); }
#define SideLength(u, v, base, delta) { \
(base).x = (v).x - (u).x; \
(base).y = (v).y - (u).y; \
delta = (base).x * (base).x + (base).y * (base).y; }
#define PntPntDist(u, v, base, delta) { \
(base).x = (v).x - (u).x; \
(base).y = (v).y - (u).y; \
delta = sqrt((base).x * (base).x + (base).y * (base).y); }
#define PntPntDistSqd(u, v, base, delta) { \
(base).x = TO_MDOUBLE((v).x) - TO_MDOUBLE((u).x); \
(base).y = TO_MDOUBLE((v).y) - TO_MDOUBLE((u).y); \
delta = (base).x * (base).x + (base).y * (base).y; }
/* */
/* this macro checks whether i3, which is collinear with i1, i2, is */
/* between i1, i2. note that we rely on the lexicographic sorting of the */
/* points! */
/* */
#define InBetween(i1, i2, i3) \
((i1 <= i3) && (i3 <= i2))
#define StrictlyInBetween(i1, i2, i3) \
((i1 < i3) && (i3 < i2))
/* */
/* this macro checks whether i3, which is collinear with i1, i2, is */
/* between i1, i2. note that we do _not_ rely on the lexicographic sorting */
/* of the points! */
/* */
#define InBetweenEps(data, i1, i2, i3) \
(((Min(data->points[i1].x, data->points[i2].x) - EPS) <= data->points[i3].x) && \
((Min(data->points[i1].y, data->points[i2].y) - EPS) <= data->points[i3].y) && \
((Max(data->points[i1].x, data->points[i2].x) + EPS) >= data->points[i3].x) && \
((Max(data->points[i1].y, data->points[i2].y) + EPS) >= data->points[i3].y))
/* */
/* this macro computes the determinant det(points[i],points[j],points[k]) */
/* in a consistent way. */
/* */
#ifdef JRC_PREDICATE
double orient2dfast(point pa, point pb, point pc);
double orient2d(point pa, point pb, point pc);
#define StableDet2D(i, j, k, det) \
{ assert(InPointsList(i)); \
assert(InPointsList(j)); \
assert(InPointsList(k)); \
\
if ((i == j) || (i == k) || (j == k)) { \
det = C_0_0; \
} \
else { \
det = orient2d(points[i], points[j], points[k]); \
} \
}
#else
#define StableDet2D(data, tmp, i, j, k, det) \
{ assert(InPointsList(data,i)); \
assert(InPointsList(data,j)); \
assert(InPointsList(data,k)); \
\
if ((i == j) || (i == k) || (j == k)) { \
det = C_0_0; \
} \
else { \
tmp.numerics_h_p = data->points[i]; \
tmp.numerics_h_q = data->points[j]; \
tmp.numerics_h_r = data->points[k]; \
\
if (i < j) { \
if (j < k) /* i < j < k */ \
det = Det2D(tmp.numerics_h_p, tmp.numerics_h_q, tmp.numerics_h_r); \
else if (i < k) /* i < k < j */ \
det = -Det2D(tmp.numerics_h_p, tmp.numerics_h_r, tmp.numerics_h_q); \
else /* k < i < j */ \
det = Det2D(tmp.numerics_h_r, tmp.numerics_h_p, tmp.numerics_h_q); \
} \
else { \
if (i < k) /* j < i < k */ \
det = -Det2D(tmp.numerics_h_q, tmp.numerics_h_p, tmp.numerics_h_r); \
else if (j < k) /* j < k < i */ \
det = Det2D(tmp.numerics_h_q, tmp.numerics_h_r, tmp.numerics_h_p); \
else /* k < j < i */ \
det = -Det2D(tmp.numerics_h_r, tmp.numerics_h_q, tmp.numerics_h_p); \
} \
} \
}
#endif
/* */
/* this macro sets ori to +1 if the points i, j, k are given in CCW order, */
/* -1 if the points i, j, k are given in CW order, */
/* 0 if the points i, j, k are collinear. */
/* */
#define Orientation(data, tmp, i, j, k, ori) \
{ StableDet2D(data, tmp, i, j, k, tmp.numerics_h_det); \
\
if (lt(tmp.numerics_h_det, EPS)) ori = -1; \
else if (gt(tmp.numerics_h_det, EPS)) ori = 1; \
else ori = 0; \
}
/* */
/* this macro sets ori to +1 if the points i, j, k are given in CCW order, */
/* -1 if the points i, j, k are given in CW order, */
/* 0 if the points i, j, k are collinear. */
/* */
#define OrientationThres(data, tmp, i, j, k, ori, thres) \
{ StableDet2D(data, tmp, i, j, k, tmp.numerics_h_det); \
\
if (lt(tmp.numerics_h_det, thres)) ori = -1; \
else if (gt(tmp.numerics_h_det, thres)) ori = 1; \
else ori = 0; \
}
/* */
/* this macro checks whether l is in the cone defined by i, j and j, k */
/* */
#define IsInConeStrict(data, tmp, i, j, k, l, convex, flag, thres) \
{ assert(InPointsList(data, i)); \
assert(InPointsList(data, j)); \
assert(InPointsList(data, k)); \
assert(InPointsList(data, l)); \
\
flag = true; \
if (convex) { \
if ((l != i) && (i != j)) { \
OrientationThres(data, tmp, i, j, l, tmp.numerics_h_ori1, thres); \
if (tmp.numerics_h_ori1 <= 0) flag = false; \
} \
if ((l != k) && (j != k) && (flag == true)) { \
OrientationThres(data, tmp, j, k, l, tmp.numerics_h_ori2, thres); \
if (tmp.numerics_h_ori2 <= 0) flag = false; \
} \
} \
else { \
OrientationThres(data, tmp, i, j, l, tmp.numerics_h_ori1, thres); \
if (tmp.numerics_h_ori1 <= 0) { \
OrientationThres(data, tmp, j, k, l, tmp.numerics_h_ori2, thres); \
if (tmp.numerics_h_ori2 <= 0) flag = false; \
} \
} \
}
/* */
/* this macro checks whether l is in the cone defined by i, j and j, k */
/* */
#define IsInCone(data, tmp, i, j, k, l, convex, flag) \
{ assert(InPointsList(data, i)); \
assert(InPointsList(data, j)); \
assert(InPointsList(data, k)); \
assert(InPointsList(data, l)); \
\
flag = true; \
if (convex) { \
if ((l != i) && (i != j)) { \
Orientation(data, tmp, i, j, l, tmp.numerics_h_ori1); \
if (tmp.numerics_h_ori1 < 0) flag = false; \
else if (tmp.numerics_h_ori1 == 0) { \
if (i < j) { \
if (!InBetween(i, j, l)) flag = false; \
} \
else { \
if (!InBetween(j, i, l)) flag = false; \
} \
} \
} \
if ((l != k) && (j != k) && (flag == true)) { \
Orientation(data, tmp, j, k, l, tmp.numerics_h_ori2); \
if (tmp.numerics_h_ori2 < 0) flag = false; \
else if (tmp.numerics_h_ori2 == 0) { \
if (j < k) { \
if (!InBetween(j, k, l)) flag = false; \
} \
else { \
if (!InBetween(k, j, l)) flag = false; \
} \
} \
} \
} \
else { \
Orientation(data, tmp, i, j, l, tmp.numerics_h_ori1); \
if (tmp.numerics_h_ori1 <= 0) { \
Orientation(data, tmp, j, k, l, tmp.numerics_h_ori2); \
if (tmp.numerics_h_ori2 <= 0) { \
if (tmp.numerics_h_ori1 == 0) { \
if (!InBetween(i, j, l)) flag = false; \
} \
else if (tmp.numerics_h_ori2 == 0) { \
if (!InBetween(j, k, l)) flag = false; \
} \
else flag = false; \
} \
} \
} \
}
/* */
/* this macro checks whether l is in the cone defined by i, j and j, k */
/* */
#define IsInConeEps(data, tmp, i, j, k, l, convex, flag) \
{ assert(InPointsList(data, i)); \
assert(InPointsList(data, j)); \
assert(InPointsList(data, k)); \
assert(InPointsList(data, l)); \
\
flag = true; \
if (convex) { \
if ((l != i) && (i != j)) { \
Orientation(data, tmp, i, j, l, tmp.numerics_h_ori1); \
if (tmp.numerics_h_ori1 < 0) flag = false; \
else if (tmp.numerics_h_ori1 == 0) { \
if (!InBetweenEps(data, i, j, l)) flag = false; \
} \
} \
if ((l != k) && (j != k) && (flag == true)) { \
Orientation(data, tmp, j, k, l, tmp.numerics_h_ori2); \
if (tmp.numerics_h_ori2 < 0) flag = false; \
else if (tmp.numerics_h_ori2 == 0) { \
if (!InBetweenEps(data, j, k, l)) flag = false; \
} \
} \
} \
else { \
Orientation(data, tmp, i, j, l, tmp.numerics_h_ori1); \
if (tmp.numerics_h_ori1 <= 0) { \
Orientation(data, tmp, j, k, l, tmp.numerics_h_ori2); \
if (tmp.numerics_h_ori2 <= 0) { \
if (tmp.numerics_h_ori1 == 0) { \
if (!InBetweenEps(data, i, j, l)) flag = false; \
} \
else if (tmp.numerics_h_ori2 == 0) { \
if (!InBetweenEps(data, j, k, l)) flag = false; \
} \
else flag = false; \
} \
} \
} \
}
/* */
/* this macro checks whether the diagonal j, l is in the cone defined by */
/* i, j and j, k. if left then j, k, l forms the ear to be tested. */
/* otherwise, i, j, k forms the ear to be tested. */
/* */
#define DiagIsInConeEps(data, tmp, i, j, k, l, convex, left, flag) \
{ assert(InPointsList(data, i)); \
assert(InPointsList(data, j)); \
assert(InPointsList(data, k)); \
assert(InPointsList(data, l)); \
\
flag = true; \
if (convex) { \
if (left) { \
if ((l != i) && (i != j)) { \
Orientation(data, tmp, i, j, l, tmp.numerics_h_ori1); \
if (tmp.numerics_h_ori1 < 0) flag = false; \
else if (tmp.numerics_h_ori1 == 0) { \
if (InBetweenEps(data, j, l, i)) flag = false; \
} \
} \
} \
else { \
if ((l != k) && (j != k)) { \
Orientation(data, tmp, j, k, l, tmp.numerics_h_ori2); \
if (tmp.numerics_h_ori2 < 0) flag = false; \
else if (tmp.numerics_h_ori2 == 0) { \
if (InBetweenEps(data, j, l, k)) flag = false; \
} \
} \
} \
} \
}
#define DiagIsInCone(data, tmp, i, j, k, l, convex, left, flag) \
{ assert(InPointsList(data, i)); \
assert(InPointsList(data, j)); \
assert(InPointsList(data, k)); \
assert(InPointsList(data, l)); \
\
flag = true; \
if (convex) { \
if (left) { \
if ((l != i) && (i != j)) { \
Orientation(data, tmp, i, j, l, tmp.numerics_h_ori1); \
if (tmp.numerics_h_ori1 < 0) flag = false; \
else if (tmp.numerics_h_ori1 == 0) { \
if (InBetween(j, l, i)) flag = false; \
} \
} \
} \
else { \
if ((l != k) && (j != k)) { \
Orientation(data, tmp, j, k, l, tmp.numerics_h_ori2); \
if (tmp.numerics_h_ori2 < 0) flag = false; \
else if (tmp.numerics_h_ori2 == 0) { \
if (InBetween(j, l, k)) flag = false; \
} \
} \
} \
} \
}
/* */
/* returns */
/* -2 ... if angle is 360 degrees */
/* -1 ... if angle between 180 and 360 degrees */
/* 0 ... if angle is 180 degrees */
/* 1 ... if angle between 0 and 180 degrees */
/* 2 ... if angle is 0 degrees */
/* 3 ... if angle is about 180 degrees and triangle is very small */
/* */
inline int IsConvexAngle(listdef *list, datadef *data, int i, int j, int k,
list_ind ind) {
assert(InPointsList(data, i));
assert(InPointsList(data, j));
assert(InPointsList(data, k));
tmp_data_def tmp;
if (i == j) {
if (j == k) {
/* */
/* all three vertices are identical. we set the angle to -2. */
/* using -2 means to err on the safe side, as all the */
/* incarnations of this vertex will be clipped right at the */
/* start of the ear-clipping algorithm. thus, eventually there */
/* will be no other duplicates at this vertex position, and the */
/* regular classification of angles will yield the correct */
/* answer for j. */
/* */
return -2;
}
else {
/* */
/* two of the three vertices are identical; we set the angle to */
/* to 2 order to enable clipping of j. */
/* */
return 2;
}
}
else if (j == k) {
/* */
/* two vertices are identical. we could either determine the angle */
/* by means of yet another lengthy analysis, or simply set the */
/* angle to -1. using -1 means to err on the safe side, as all the */
/* incarnations of this vertex will be clipped right at the start */
/* of the ear-clipping algorithm. thus, eventually there will be no */
/* other duplicates at this vertex position, and the regular */
/* classification of angles will yield the correct answer for j. */
/* */
return -1;
} else {
StableDet2D(data, tmp, i, j, k, tmp.numerics_h_det);
if (gt(tmp.numerics_h_det, EPS)) {
return 1;
}
else if (lt(tmp.numerics_h_det, EPS)) {
return -1;
}
else {
/* */
/* 0, 180, or 360 degrees. */
/* */
VectorSub2D(data->points[i], data->points[j], tmp.numerics_h_p);
VectorSub2D(data->points[k], data->points[j], tmp.numerics_h_q);
tmp.numerics_h_dot = DotProduct2D(tmp.numerics_h_p, tmp.numerics_h_q);
if (tmp.numerics_h_dot < C_0_0) {
/* */
/* 180 degrees. */
/* */
/*data->numerics_h_dot = sqrt(Length2D(data->numerics_h_p)); */
/*data->numerics_h_dot += sqrt(Length2D(data->numerics_h_q)); */
if (tmp.numerics_h_det > C_0_0) return 1;
else return 0;
}
else {
/* */
/* 0 or 360 degrees? this cannot be judged locally, and more */
/* work is needed. */
/* */
return SpikeAngle(list, data, i, j, k, ind);
}
}
}
}
/* */
/* this macro checks whether point i4 is inside of or on the boundary */
/* of the triangle i1, i2, i3 */
/* */
#define PntInTriangle(data, tmp, i1, i2, i3, i4, inside) \
{ \
inside = false; \
Orientation(data, tmp, i2, i3, i4, tmp.numerics_h_ori1); \
if (tmp.numerics_h_ori1 >= 0) { \
Orientation(data, tmp, i1, i2, i4, tmp.numerics_h_ori1); \
if (tmp.numerics_h_ori1 >= 0) { \
Orientation(data, tmp, i3, i1, i4, tmp.numerics_h_ori1); \
if (tmp.numerics_h_ori1 >= 0) inside = true; \
} \
} \
}
/* */
/* this macro checks whether point i4 is inside of or on the boundary */
/* of the triangle i1, i2, i3. it also returns a classification if i4 is */
/* on the boundary of the triangle (except for the edge i2, i3). */
/* */
#define VtxInTriangle(data, tmp, i1, i2, i3, i4, inside, classifier) \
{ \
inside = false; \
Orientation(data, tmp, i2, i3, i4, tmp.numerics_h_ori1); \
if (tmp.numerics_h_ori1 >= 0) { \
Orientation(data, tmp, i1, i2, i4, tmp.numerics_h_ori1); \
if (tmp.numerics_h_ori1 > 0) { \
Orientation(data, tmp, i3, i1, i4, tmp.numerics_h_ori1); \
if (tmp.numerics_h_ori1 > 0) { \
inside = true; \
classifier = 0; \
} \
else if (tmp.numerics_h_ori1 == 0) { \
inside = true; \
classifier = 1; \
} \
} \
else if (tmp.numerics_h_ori1 == 0) { \
Orientation(data, tmp, i3, i1, i4, tmp.numerics_h_ori1); \
if (tmp.numerics_h_ori1 > 0) { \
inside = true; \
classifier = 2; \
} \
else if (tmp.numerics_h_ori1 == 0) { \
inside = true; \
classifier = 3; \
} \
} \
} \
}
#define ComputeRatio(A, B, C, RATIO) \
{ \
if (Min(B, C) <= ZERO) { \
RATIO = Min(B, C); \
} \
else { \
RATIO = CD_1_0 + (A - B - C) / (CD_2_0 * sqrt(B * C)); \
} \
}
+22
View File
@@ -0,0 +1,22 @@
/*****************************************************************************/
/* */
/* 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. */
/* */
/*****************************************************************************/
void WriteFileMagic(FILE *fp);
void WriteFileEnd(FILE *outf);
void WriteObjType(FILE *outf, int num_tri);
void WriteSgiTri(FILE *fp, float sgi_tri[3][3]);
+29
View File
@@ -0,0 +1,29 @@
/*****************************************************************************/
/* */
/* 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. */
/* */
/*****************************************************************************/
#ifdef EXT_APPL_SITES
#define SetExtApplVtx(V, X) \
{\
assert(InVertexList(vert, V)); \
vert->vertices[V].ext_appl = X; \
}
#define GetExtApplVtx(V) \
(\
assert(InVertexList(vert, V)), \
vert->vertices[V].ext_appl)
#endif
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.