cbec90699f
- creato il progetto in Visual Studio per compilare come libreria statica - modifiche al codice originale per integrarlo nelle nostre librerie.
405 lines
12 KiB
C++
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;
|
|
}
|