Files
fist/io_basic.cpp
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

482 lines
15 KiB
C++

/*****************************************************************************/
/* */
/* F I S T : Fast, Industrial-Strength Triangulation */
/* */
/*****************************************************************************/
/* */
/* (C) Martin Held */
/* (C) Universitaet Salzburg, Salzburg, Austria */
/* */
/* This code is not in the public domain. All rights reserved! Please make */
/* sure to read the full copyright statement contained in api_functions.cpp. */
/* */
/*****************************************************************************/
/* */
/* get standard libraries */
/* */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <float.h>
#include <assert.h>
#include <time.h>
#include <math.h>
/* */
/* get my header files */
/* */
#include "fpkernel.h"
#include "martin.h"
#include "defs.h"
#include "list.h"
#include "basic.h"
#include "header.h"
#ifdef GRAPHICS
#include "graphics.h"
#endif
/* */
/* function prototypes of functions provided in this file */
/* */
void InitIOListDefaults(iolistdef *iolist);
void ResetIOListData(iolistdef *iolist);
void Read2DInputData(global_struct *all);
void StartPoly(global_struct *all);
void CloseCurrentPoly(global_struct *all);
void DXFStartPoly(global_struct *all);
void DXFCloseCurrentPoly(global_struct *all, double bulge);
#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 DXFAddPolyVertex(global_struct *all, double xc1, double yc1, double bulge);
void EnsureClosedPolygon(global_struct *all);
#ifdef EXT_APPL_SITES
int HandlePnt(global_struct *all, double xc1, double yc1, eas_type eas_data);
void HandleSeg(global_struct *all, double xc1, double yc1, double xc2, double yc2,
eas_type eas_data);
void HandleArc(global_struct *all, double xc1, double yc1, double xc2, double yc2,
double xc3, double yc3, int attr, eas_type eas_data);
#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
void InitIOListDefaults(iolistdef *iolist)
{
iolist->new_pnts = 0;
iolist->first_pnt = NIL;
iolist->last_pnt = NIL;
iolist->curr_loop = NIL;
iolist->last_ind = NIL;
iolist->poly_vertex_number = NIL;
return;
}
void ResetIOListData(iolistdef *iolist)
{
iolist->new_pnts = 0;
iolist->first_pnt = NIL;
iolist->last_pnt = NIL;
iolist->last_ind = NIL;
return;
}
void Read2DInputData(global_struct *all)
{
/* */
/* read 2D data from input file */
/* */
if (all->rt_opt.verbose) {
fprintf(stdout, "\n...reading the input data: ");
fflush(stdout);
}
if (all->rt_opt.read_input) {
ReadPolygon(all);
}
else if (all->rt_opt.read_poly) {
ReadPoly(all);
}
else if (all->rt_opt.read_dxf) {
ReadDXFFile(all);
}
else if (all->rt_opt.read_lines) {
ReadPolyLines(all);
}
else {
throw WRONG_INPUT_OPTION;
}
if (all->rt_opt.verbose) {
fprintf(stdout, "done!\n");
fflush(stdout);
}
return;
}
void EnsureClosedPolygon(global_struct *all)
{
/* */
/* make sure that all polygons are closed even when my code is used not */
/* properly. */
/* */
if (all->c_iolist.curr_loop != NIL) CloseCurrentPoly(all);
return;
}
void StartPoly(global_struct *all)
{
iolistdef *iolist = &all->c_iolist;
listdef *list = &all->c_list;
/* */
/* make sure that all polygons are closed even when my code is used not */
/* properly. */
/* */
if ((iolist->curr_loop != NIL)
&& (iolist->poly_vertex_number >= 1)) CloseCurrentPoly(all);
/* */
/* start a new polygon. */
/* */
if (iolist->curr_loop == NIL) iolist->curr_loop = MakeLoopHeader(list);
iolist->first_pnt = NIL;
iolist->last_pnt = NIL;
iolist->last_ind = NIL;
iolist->poly_vertex_number = NIL;
ExtApplFuncStartPoly;
return;
}
void CloseCurrentPoly(global_struct *all)
{
iolistdef *iolist = &all->c_iolist;
listdef *list = &all->c_list;
#ifdef GRAPHICS
redrawdef *redraw = &all->c_redraw;
#endif
list_ind ind;
assert(iolist->curr_loop != NIL);
ExtApplFuncClosePoly_1;
if (iolist->poly_vertex_number < 1) {
/* */
/* polygon with no vertex? let's forget it! */
/* */
DecrementLoops(list);
}
else {
#ifdef GRAPHICS
if (all->rt_opt.graphics)
AddEdgeToBuffer(redraw, iolist->last_pnt, iolist->first_pnt, PolyColor);
#endif
if (iolist->poly_vertex_number == 1) {
/* */
/* polygon with only one vertex? we'll add one dummy vertex. */
/* */
iolist->last_ind = list->loops[iolist->curr_loop];
ind = MakeNode(list, iolist->first_pnt);
InsertAfter(list, iolist->last_ind, ind);
iolist->last_ind = ind;
iolist->last_pnt = iolist->first_pnt;
iolist->poly_vertex_number += 1;
}
if (iolist->poly_vertex_number == 2) {
/* */
/* polygon with only two vertices? we'll add one dummy vertex. */
/* */
ind = GetPrevNode(list, iolist->last_ind);
//i = GetIndex(list, ind);
SetAngle(list, ind, -2);
ind = MakeNode(list, iolist->last_pnt);
InsertAfter(list, iolist->last_ind, ind);
iolist->last_ind = ind;
SetAngle(list, ind, -2);
}
DeleteHook(list, iolist->curr_loop);
}
ExtApplFuncClosePoly_2;
iolist->curr_loop = NIL;
iolist->first_pnt = NIL;
iolist->last_pnt = NIL;
iolist->last_ind = NIL;
iolist->poly_vertex_number = NIL;
return;
}
#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
{
iolistdef *iolist = &all->c_iolist;
listdef *list = &all->c_list;
datadef *data = &all->c_data;
#ifdef GRAPHICS
redrawdef *redraw = &all->c_redraw;
#endif
int j;
list_ind ind;
assert(iolist->curr_loop != NIL);
if (iolist->first_pnt == NIL) {
ExtApplFuncAddPolyVertex_1;
iolist->poly_vertex_number = 1;
#ifdef EXT_APPL_SITES
iolist->first_pnt = StorePnt(data, xc1, yc1, eas_data);
#else
iolist->first_pnt = StorePnt(data, xc1, yc1);
#endif
iolist->last_pnt = iolist->first_pnt;
#ifdef GRAPHICS
if (all->rt_opt.graphics) AddPntToBuffer(redraw, iolist->first_pnt,
PntsColor);
#endif
iolist->last_ind = list->loops[iolist->curr_loop];
ind = MakeNode(list, iolist->first_pnt);
InsertAfter(list, iolist->last_ind, ind);
iolist->last_ind = ind;
if (xc1 < all->bb_min.x) all->bb_min.x = xc1;
if (xc1 > all->bb_max.x) all->bb_max.x = xc1;
if (yc1 < all->bb_min.y) all->bb_min.y = yc1;
if (yc1 > all->bb_max.y) all->bb_max.y = yc1;
ExtApplFuncAddPolyVertex_2;
}
else {
ExtApplFuncAddPolyVertex_3;
iolist->poly_vertex_number += 1;
#ifdef EXT_APPL_SITES
j = StorePnt(data, xc1, yc1, eas_data);
#else
j = StorePnt(data, xc1, yc1);
#endif
#ifdef GRAPHICS
if (all->rt_opt.graphics) {
AddPntToBuffer(redraw, j, PntsColor);
AddEdgeToBuffer(redraw, iolist->last_pnt, j, PolyColor);
}
#endif
iolist->last_pnt = j;
ind = MakeNode(list, j);
InsertAfter(list, iolist->last_ind, ind);
iolist->last_ind = ind;
if (xc1 < all->bb_min.x) all->bb_min.x = xc1;
else if (xc1 > all->bb_max.x) all->bb_max.x = xc1;
if (yc1 < all->bb_min.y) all->bb_min.y = yc1;
else if (yc1 > all->bb_max.y) all->bb_max.y = yc1;
ExtApplFuncAddPolyVertex_4;
}
return;
}
void DXFAddPolyVertex(global_struct *all, double xc1, double yc1, double bulge)
{
if (bulge != C_0_0)
FIST_Warning("DXFAddPolyVertex() - non-zero bulge ignored!\n");
#ifdef EXT_APPL_SITES
AddPolyVertex(all, xc1, yc1, eas_NIL);
#else
AddPolyVertex(all, xc1, yc1);
#endif
return;
}
void DXFCloseCurrentPoly(global_struct *all, double bulge)
{
if (bulge != C_0_0)
FIST_Warning("DXFCloseCurrentPoly() - non-zero bulge ignored!\n");
CloseCurrentPoly(all);
return;
}
void DXFStartPoly(global_struct *all)
{
StartPoly(all);
return;
}
#ifdef EXT_APPL_SITES
int HandlePnt(global_struct *all, double xc1, double yc1, eas_type eas_data)
#else
int HandlePnt(global_struct *all, double xc1, double yc1)
#endif
{
/* */
/* we convert the isolated point into a dummy triangle that consists of */
/* three zero-length edges. */
/* */
StartPoly(all);
#ifdef EXT_APPL_SITES
AddPolyVertex(all, xc1, yc1, eas_data);
#else
AddPolyVertex(all, xc1, yc1);
#endif
CloseCurrentPoly(all);
/* */
/* we don't have/use a return value within FIST, but need it for */
/* compatibility reasons with other codes of mine. */
/* */
return NIL;
}
#ifdef EXT_APPL_SITES
void HandleSeg(global_struct *all, double xc1, double yc1, double xc2, double yc2,
eas_type eas_data)
#else
void HandleSeg(global_struct *all, double xc1, double yc1, double xc2, double yc2)
#endif
{
/* */
/* we convert the line segment into a dummy triangle that consists of the */
/* line segment doubled plus one zero-length edge. */
/* */
StartPoly(all);
#ifdef EXT_APPL_SITES
AddPolyVertex(all, xc1, yc1, eas_data);
AddPolyVertex(all, xc2, yc2, eas_data);
#else
AddPolyVertex(all, xc1, yc1);
AddPolyVertex(all, xc2, yc2);
#endif
CloseCurrentPoly(all);
return;
}
#ifdef EXT_APPL_SITES
void HandleArc(global_struct *all,
double xc1, double yc1, double xc2, double yc2,
double xc3, double yc3, int attr, eas_type eas_data)
#else
void HandleArc(global_struct *all,
double xc1, double yc1, double xc2, double yc2,
double xc3, double yc3, int attr)
#endif
{
machine_double delta_x, delta_y, radius, angle_s, angle_e;
machine_double incr, alpha;
int number;
#ifdef EXT_APPL_SITES
AddPolyVertex(all, xc1, yc1, eas_data);
#else
AddPolyVertex(all, xc1, yc1);
#endif
delta_x = TO_MDOUBLE(xc1) - TO_MDOUBLE(xc3);
delta_y = TO_MDOUBLE(yc1) - TO_MDOUBLE(yc3);
radius = sqrt(delta_x * delta_x + delta_y * delta_y);
delta_x = TO_MDOUBLE(all->bb_max.x) - TO_MDOUBLE(all->bb_min.x);
delta_y = TO_MDOUBLE(all->bb_max.y) - TO_MDOUBLE(all->bb_min.y);
incr = MD_2PI * Max(delta_x, delta_y) / (150.0 * radius * sqrt(radius));
if (incr < (MD_2PI / 100.0)) incr = MD_2PI / 100.0;
if (incr > (MD_PI / 10.0)) incr = MD_PI / 10.0;
if (attr == 1) {
angle_s = atan2(TO_MDOUBLE(yc1) - TO_MDOUBLE(yc3), TO_MDOUBLE(xc1) - TO_MDOUBLE(xc3));
angle_e = atan2(TO_MDOUBLE(yc2) - TO_MDOUBLE(yc3), TO_MDOUBLE(xc2) - TO_MDOUBLE(xc3));
if (angle_s < 0.0) angle_s += MD_2PI;
if (angle_e < 0.0) angle_e += MD_2PI;
if (angle_e < angle_s) angle_e += MD_2PI;
number = (int) ((angle_e - angle_s) / incr);
++number;
incr = (angle_e - angle_s) / number;
angle_e -= incr / 2.0;
alpha = angle_s + incr;
while (alpha < angle_e) {
xc1 = xc3 + radius * cos(alpha);
yc1 = yc3 + radius * sin(alpha);
#ifdef EXT_APPL_SITES
AddPolyVertex(all, xc1, yc1, eas_data);
#else
AddPolyVertex(all, xc1, yc1);
#endif
alpha += incr;
}
}
else if (attr == -1) {
angle_s = atan2(TO_MDOUBLE(yc1) - TO_MDOUBLE(yc3), TO_MDOUBLE(xc1) - TO_MDOUBLE(xc3));
angle_e = atan2(TO_MDOUBLE(yc2) - TO_MDOUBLE(yc3), TO_MDOUBLE(xc2) - TO_MDOUBLE(xc3));
if (angle_s < 0.0) angle_s += MD_2PI;
if (angle_e < 0.0) angle_e += MD_2PI;
if (angle_s < angle_e) angle_s += MD_2PI;
number = (int) ((angle_s - angle_e) / incr);
++number;
incr = (angle_s - angle_e) / number;
angle_e += incr / 2.0;
alpha = angle_s - incr;
while (alpha > angle_e) {
xc1 = xc3 + radius * cos(alpha);
yc1 = yc3 + radius * sin(alpha);
#ifdef EXT_APPL_SITES
AddPolyVertex(all, xc1, yc1, eas_data);
#else
AddPolyVertex(all, xc1, yc1);
#endif
alpha -= incr;
}
}
else {
FIST_Warning("HandleArc() - unknown data format!\n");
}
return;
}