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

405 lines
12 KiB
C++

/*****************************************************************************/
/* */
/* F I S T : Fast, Industrial-Strength Triangulation */
/* */
/*****************************************************************************/
/* */
/* (C) Martin Held */
/* (C) Universitaet Salzburg, Salzburg, Austria */
/* */
/* This code is not in the public domain. All rights reserved! Please make */
/* sure to read the full copyright statement contained in api_functions.cpp. */
/* */
/*****************************************************************************/
/* */
/* get standard libraries */
/* */
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
/* */
/* get my header files */
/* */
#include "fpkernel.h"
#include "martin.h"
#include "defs.h"
#include "header.h"
#include "list.h"
#ifdef PARTITION_FIST
#ifdef __APPLE__
#define omp_get_max_threads() (4)
#else
#include <omp.h>
#endif
#endif
#define BLOCK_SIZE 65536
/* */
/* prototypes of functions provided in this file */
/* */
void InitGlobalStruct(global_struct *all, rt_options *rt_opt,
boolean stand_alone);
void InitDataDefaults(datadef *data);
#ifdef EXT_APPL_SITES
int StorePnt(datadef *data, double x, double y, eas_type eas_data);
#else
int StorePnt(datadef *data, double x, double y);
#endif
void DecrementPoints(datadef *data);
void InitPnts(datadef *data,int number);
void FreePnts(datadef *data);
void SetBoundingBox(datadef *data, point *bb_min, point *bb_max);
boolean InPointsList(datadef *data, int index);
void InitStoragePnts(datadef *data, int number);
void ScaleData(global_struct *all);
/* */
/* Initialize the default values for FIST's structures and options */
/* */
void InitGlobalStruct(global_struct *all, rt_options *rt_opt,
boolean stand_alone)
{
#ifdef PARTITION_FIST
heapdef *hp;
#endif
if (rt_opt == (rt_options*)NULL) {
InitDefaults(&all->rt_opt);
}
else {
all->rt_opt = *rt_opt;
}
InitListDefaults(&all->c_list);
InitBridgeDefaults(&all->c_bridge);
InitVertexDef(&all->c_vertex);
InitDataDefaults(&all->c_data);
InitCleanDefaults(&all->c_clean);
InitGridDefaults(&all->c_grid);
InitQuadsDefaults(&all->c_quad);
InitIOListDefaults(&all->c_iolist);
Init3dDefaults(&all->c_io3d);
#ifdef GRAPHICS
InitRedrawDefaults(&all->c_redraw);
#endif
#ifdef DEBUG_MEMORY
InitDebugMemDefaults(&all->c_mem);
#endif
InitEarDefaults(&all->c_ear);
#ifdef PARTITION_FIST
all->number_of_heaps = omp_get_max_threads();
all->partition_mode = true;
InitPartitionedHeap(all);
for(int i = 0; i < all->number_of_heaps; ++i) {
hp = &all->c_heap[i];
#ifdef DEBUG_MEMORY
hp->memptr = &all->c_mem;
#endif
InitHeapDefaults(hp);
hp->sorted = hp->ears_sorted = all->rt_opt.ears_sorted;
hp->ears_random = all->rt_opt.ears_random;
}
#else
InitHeapDefaults(&all->c_heap);
all->c_heap.sorted = all->c_heap.ears_sorted = all->rt_opt.ears_sorted;
all->c_heap.ears_random = all->rt_opt.ears_random;
#ifdef DEBUG_MEMORY
all->c_heap.memptr = &all->c_mem;
#endif
#endif
#ifdef DEBUG_MEMORY
#ifdef GRAPHICS
all->c_redraw.memptr = &all->c_mem;
#endif
all->c_data.memptr = &all->c_mem;
all->c_list.memptr = &all->c_mem;
all->c_clean.memptr = &all->c_mem;
all->c_bridge.memptr = &all->c_mem;
all->c_vertex.memptr = &all->c_mem;
all->c_grid.memptr = &all->c_mem;
#endif
all->poly_area = (double*)NULL;
all->max_num_poly_area = 0;
#ifdef GRAPHICS
all->draw_pnts = true;
all->draw_point_idx = false;
#endif
all->ccw_loop = true;
all->new_input = false;
all->cpu_time = 0.0;
all->curr_loop_main = 0;
all->dxf_file = (FILE*)NULL;
all->ipe_initialized = false;
all->c_ipe_io.ipe7 = all->rt_opt.write_ipe7;
all->done = false;
all->reset = false;
all->troubles = false;
all->written = false;
if (!stand_alone) {
/* */
/* make sure that FIST does its job silently, without graphics. */
/* */
all->rt_opt.quiet = true;
all->rt_opt.graphics = false;
}
all->c_ear.ears_fancy = all->rt_opt.ears_fancy;
all->c_ear.ears_top = all->rt_opt.ears_top;
all->c_ear.use_colors = all->rt_opt.use_colors;
#ifdef CPUTIME_VIA_CLOCK
all->cpu_time_initialized = false;
#endif
#ifdef CPUTIME_IN_MILLISECONDS
all->total_secs = 0;
all->total_usecs = 0;
#endif
#ifdef EXPR_WRAPPER
all->returncore = false;
#endif
return;
}
void InitDataDefaults(datadef *data)
{
data->points = (point*)NULL;
data->num_pnts = 0;
data->max_num_pnts = 0;
return;
}
#ifdef EXT_APPL_SITES
int StorePnt(datadef *data, double x, double y, eas_type eas_data)
#else
int StorePnt(datadef *data, double x, double y)
#endif
{
int i;
if (data->num_pnts >= data->max_num_pnts) {
data->max_num_pnts += BLOCK_SIZE;
data->points = CORE_ReallocateArray(data->memptr, data->points, data->max_num_pnts - BLOCK_SIZE,
data->max_num_pnts, point, "data:points");
}
data->points[data->num_pnts].x = x;
data->points[data->num_pnts].y = y;
#ifdef EXT_APPL_SITES
data->points[data->num_pnts].ext_appl = eas_data;
#endif
/* */
/* let the user call some application-specific function */
/* */
ExtApplFuncStorePnt;
i = data->num_pnts;
++data->num_pnts;
return i;
}
void DecrementPoints(datadef *data)
{
--data->num_pnts;
return;
}
void InitPnts(datadef *data, int number)
{
if (data->max_num_pnts < number) {
data->points = CORE_ReallocateArray(data->memptr, data->points, data->max_num_pnts,
number, point, "data:points");
data->max_num_pnts = number;
}
data->num_pnts = 0;
data->data_scaled = false;
data->scale_factor = C_1_0;
data->shift.x = C_0_0;
data->shift.y = C_0_0;
return;
}
void InitStoragePnts(datadef *data, int number)
{
if (data->max_num_pnts < number) {
data->points = CORE_ReallocateArray(data->memptr, data->points, data->max_num_pnts,
number, point, "data:points");
data->max_num_pnts = number;
}
return;
}
void FreePnts(datadef *data)
{
CORE_FreeMemory(data->memptr, &data->points, "data:points");
data->max_num_pnts = 0;
data->num_pnts = 0;
return;
}
/* */
/* this routine returns the bounding box of the sorted entries of "points" */
/* */
void SetBoundingBox(datadef *data, point *bb_min, point *bb_max)
{
int i;
machine_double x_ext, y_ext;
if (data->num_pnts > 0) {
bb_min->x = data->points[0].x;
bb_max->x = data->points[data->num_pnts-1].x;
bb_min->y = data->points[0].y;
bb_max->y = bb_min->y;
for (i = 1; i < data->num_pnts; ++i) {
if (data->points[i].y < bb_min->y)
bb_min->y = data->points[i].y;
else if (data->points[i].y > bb_max->y)
bb_max->y = data->points[i].y;
}
x_ext = TO_MDOUBLE(bb_max->x) - TO_MDOUBLE(bb_min->x);
y_ext = TO_MDOUBLE(bb_max->y) - TO_MDOUBLE(bb_min->y);
data->bbox_diagonal_sqd = x_ext * x_ext + y_ext * y_ext;
}
return;
}
void ComputeBoundingBox(datadef *data, listdef *list, list_ind ind,
point *bb_min, point *bb_max)
{
int i;
list_ind ind1;
machine_double x_ext, y_ext;
ind1 = ind;
i = GetIndex(list,ind1);
bb_min->x = data->points[i].x;
bb_max->x = data->points[i].x;
bb_min->y = data->points[i].y;
bb_max->y = data->points[i].y;
do {
i = GetIndex(list,ind1);
if (data->points[i].x < bb_min->x) bb_min->x = data->points[i].x;
else if (data->points[i].x > bb_max->x) bb_max->x = data->points[i].x;
if (data->points[i].y < bb_min->y) bb_min->y = data->points[i].y;
else if (data->points[i].y > bb_max->y) bb_max->y = data->points[i].y;
ind1 = GetNextNode(list,ind1);
} while (ind1 != ind);
x_ext = TO_MDOUBLE(bb_max->x) - TO_MDOUBLE(bb_min->x);
y_ext = TO_MDOUBLE(bb_max->y) - TO_MDOUBLE(bb_min->y);
data->bbox_diagonal_sqd = x_ext * x_ext + y_ext * y_ext;
return;
}
boolean InPointsList(datadef *data, int index)
{
return ((index >= 0) && (index < data->num_pnts) &&
(data->num_pnts <= data->max_num_pnts));
}
/* */
/* scale the data if necessary. */
/* */
void ScaleData(global_struct *all)
{
datadef *data = &all->c_data;
int i;
machine_double xy, x_ext, y_ext;
x_ext = TO_MDOUBLE(all->bb_max.x) - TO_MDOUBLE(all->bb_min.x);
y_ext = TO_MDOUBLE(all->bb_max.y) - TO_MDOUBLE(all->bb_min.y);
xy = Max(x_ext, y_ext);
xy = Max(xy, ZERO_D);
data->scale_factor = 1.0;
if (xy > CD_3_0) {
do {
data->scale_factor /= C_2_0;
} while ((xy * data->scale_factor) > C_3_0);
data->data_scaled = true;
}
else if (xy < CD_0_3) {
do {
data->scale_factor *= C_2_0;
} while ((xy * data->scale_factor) < C_0_3);
data->data_scaled = true;
}
else if ((all->bb_max.x > C_2_0) || (all->bb_max.y > C_2_0) ||
(all->bb_min.x < C_m2_0) || (all->bb_min.y < C_m2_0)) {
data->data_scaled = true;
}
if (data->data_scaled) {
data->shift.x = (all->bb_min.x + all->bb_max.x) / C_2_0;
data->shift.y = (all->bb_min.y + all->bb_max.y) / C_2_0;
for (i = 0; i < data->num_pnts; ++i) {
data->points[i].x = (data->points[i].x - data->shift.x) * data->scale_factor;
data->points[i].y = (data->points[i].y - data->shift.y) * data->scale_factor;
}
all->bb_max.x = (all->bb_max.x - data->shift.x) * data->scale_factor;
all->bb_max.y = (all->bb_max.y - data->shift.y) * data->scale_factor;
all->bb_min.x = (all->bb_min.x - data->shift.x) * data->scale_factor;
all->bb_min.y = (all->bb_min.y - data->shift.y) * data->scale_factor;
}
else {
data->shift.x = C_0_0;
data->shift.y = C_0_0;
data->scale_factor = C_1_0;
}
x_ext = TO_MDOUBLE(all->bb_max.x) - TO_MDOUBLE(all->bb_min.x);
y_ext = TO_MDOUBLE(all->bb_max.y) - TO_MDOUBLE(all->bb_min.y);
data->bbox_diagonal_sqd = x_ext * x_ext + y_ext * y_ext;
return;
}