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

703 lines
25 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 <assert.h>
#include <ctype.h>
#include <math.h>
#include <float.h>
/* */
/* get my header files */
/* */
#include "fpkernel.h"
#include "martin.h"
#include "defs.h"
#include "header.h"
#include "ext_appl_defs.h"
#include "io_dxf.h"
/* */
/* function prototypes of functions provided in this file */
/* */
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);
#define LINE_LENGTH 1024
#define NEWLINE '\n'
#define CARRIAGE '\r'
#define InitBBox(all) \
{\
all->bb_min.x = all->bb_min.y = fpkernel_DBL_MAX; \
all->bb_max.x = all->bb_max.y = - fpkernel_DBL_MAX; \
}
#define IsSpace(x)\
((x == ' ') || (x == '\t') || (x == '\r') || (x == '\n') || (x == '\f'))
#define SkipUntilDXFCode(input, code, string, dxf_code) \
{ \
do { \
if (!ReadNewDXFPair_fist(input, code, string, LINE_LENGTH)) \
throw EOF_ENCOUNTERED; \
} while (atoi(code) != dxf_code); \
}
#define SkipUntilDXFString(input, code, string, dxf_string) \
{ \
do { \
if (!ReadNewDXFPair_fist(input, code, string, LINE_LENGTH)) \
throw EOF_ENCOUNTERED; \
} while (strcmp(string, dxf_string)); \
if (!ReadNewDXFPair_fist(input, code, string, LINE_LENGTH)) \
throw EOF_ENCOUNTERED; \
}
boolean ReadNewLine_fist(FILE *input, char *line, int size, boolean read_string)
{
char *s;
int i;
do {
s = fgets(line, size, input);
if (s == (char*)NULL) return false;
i = strlen(s) - 1;
while((i >= 0) && IsSpace(s[i])) {
s[i]='\0';
i--;
}
if (i >= 0) {
while (IsSpace(s[0])) ++s;
line = strcpy(line, s);
}
else if (read_string) {
i = 0;
}
} while (i < 0);
if (i < 0) return false;
else return true;
}
boolean ReadNewDXFPair_fist(FILE *input, char *code, char *string, int size)
{
if (!ReadNewLine_fist(input, code, size, false)) return false;
if (!ReadNewLine_fist(input, string, size, true)) return false;
return true;
}
/* */
/* This is a >>VERY<< rudimentary interface for reading AutoCAD DXF files. */
/* Note that this interface is not as general as it ought to be. That is, */
/* likely it will cough on lots of DXF files. Currently, it supports POINT, */
/* LINE, ARC, CIRCLE, POLYLINE and LWPOLYLINE entities, including "closed" */
/* flags and bulge factors for the latter two entities. It does not handle */
/* BLOCKs or INSERTs or LAYERs, or any other codes that turn objects on or */
/* off, or that move or resize them. Also, this routine does not care about */
/* z-coordinates, and it does not support binary files. Of course, only */
/* strictly polygonal data that forms closed contours is interpreted */
/* correctly by FIST. */
/* */
void ReadDXFFile(global_struct *all)
{
FILE *input;
char code[LINE_LENGTH+1];
char string[LINE_LENGTH+1];
int dxf_code, i, i1;
double xc1 = C_0_0, yc1 = C_0_0, xc2 = C_0_0, yc2 = C_0_0;
double rad = C_0_0, bulge = C_0_0, old_bulge = C_0_0, s_a = C_0_0, e_a = C_0_0;
boolean xc1_set, yc1_set, xc2_set, yc2_set;
boolean rad_set, s_a_set, e_a_set;
boolean pnt_read, seg_read, arc_read, cir_read, poly_closed = false;
boolean poly_started = false;;
all->new_input = false;
all->isolated_pnts = false;
InitBBox(all);
input = OpenFile(all->rt_opt.input_file, "r");
if (!ReadNewDXFPair_fist(input, code, string, LINE_LENGTH)) return;
while (strcmp(string, "EOF")) {
if ((!strcmp(string, "POINT")) ||
(!strcmp(string, "LINE")) ||
(!strcmp(string, "CIRCLE")) ||
(!strcmp(string, "ARC"))) {
/* */
/* input point, line segment, circle or circular arc. */
/* */
xc1_set = yc1_set = false;
xc2_set = yc2_set = false;
rad_set = s_a_set = e_a_set = false;
pnt_read = seg_read = arc_read = cir_read = false;
if (!strcmp(string, "POINT")) pnt_read = true;
if (!strcmp(string, "LINE")) seg_read = true;
if (!strcmp(string, "ARC")) arc_read = true;
if (!strcmp(string, "CIRCLE")) cir_read = true;
do {
if (!ReadNewDXFPair_fist(input, code, string, LINE_LENGTH))
throw EOF_ENCOUNTERED;
dxf_code = atoi(code);
switch(dxf_code) {
case 10:
xc1 = FP_atof(string);
xc1_set = true;
break;
case 20:
yc1 = FP_atof(string);
yc1_set = true;
break;
case 11:
xc2 = FP_atof(string);
xc2_set = true;
break;
case 21:
yc2 = FP_atof(string);
yc2_set = true;
break;
case 40:
rad = FP_atof(string);
rad_set = true;
break;
case 50:
s_a = FP_atof(string);
s_a_set = true;
break;
case 51:
e_a = FP_atof(string);
e_a_set = true;
break;
default:
break;
}
} while (dxf_code != 0);
if (xc1_set && yc1_set) {
all->new_input = true;
if (seg_read && xc2_set && yc2_set) {
#ifdef EXT_APPL_SITES
HandleSeg(all, xc1, yc1, xc2, yc2, eas_NIL);
#else
HandleSeg(all, xc1, yc1, xc2, yc2);
#endif
}
else if (arc_read && rad_set && s_a_set && e_a_set){
s_a *= M_PI_180;
e_a *= M_PI_180;
#ifdef EXT_APPL_SITES
HandleArc(all, xc1 + rad * cos(s_a), yc1 + rad * sin(s_a),
xc1 + rad * cos(e_a), yc1 + rad * sin(e_a),
xc1, yc1, ARC, eas_NIL);
#else
HandleArc(all, xc1 + rad * cos(TO_MDOUBLE(s_a)), yc1 + rad * sin(TO_MDOUBLE(s_a)),
xc1 + rad * cos(TO_MDOUBLE(e_a)), yc1 + rad * sin(TO_MDOUBLE(e_a)),
xc1, yc1, ARC);
#endif
}
else if (cir_read && rad_set) {
#ifdef EXT_APPL_SITES
HandleArc(all, xc1 + rad, yc1, xc1 - rad, yc1, xc1, yc1,
ARC, eas_NIL);
HandleArc(all, xc1 - rad, yc1, xc1 + rad, yc1, xc1, yc1,
ARC, eas_NIL);
#else
HandleArc(all, xc1 + rad, yc1, xc1 - rad, yc1, xc1, yc1,
ARC);
HandleArc(all, xc1 - rad, yc1, xc1 + rad, yc1, xc1, yc1,
ARC);
#endif
}
else if (pnt_read) {
#ifdef EXT_APPL_PNTS
i1 = HandlePnt(all, xc1, yc1, eap_NIL);
#else
i1 = HandlePnt(all, xc1, yc1);
#endif
all->isolated_pnts = true;
}
}
}
else if (!strcmp(string, "LWPOLYLINE")) {
/* */
/* "light-weight" polygonal curve. */
/* */
DXFStartPoly(all);
xc1_set = false;
yc1_set = false;
bulge = C_0_0;
poly_closed = false;
do {
if (!ReadNewDXFPair_fist(input, code, string, LINE_LENGTH))
throw EOF_ENCOUNTERED;
dxf_code = atoi(code);
switch(dxf_code) {
case 10:
case 20:
if (dxf_code == 10) {
xc1 = FP_atof(string);
xc1_set = true;
}
else {
yc1 = FP_atof(string);
yc1_set = true;
}
if (xc1_set && yc1_set) {
all->new_input = true;
DXFAddPolyVertex(all, xc1, yc1, bulge);
xc1_set = false;
yc1_set = false;
bulge = C_0_0;
}
break;
case 42:
bulge = atof(string);
break;
case 70:
poly_closed = (boolean) (1&atoi(string));
break;
default:
break;
}
} while (dxf_code != 0);
if (poly_closed) {
DXFCloseCurrentPoly(all, bulge);
bulge = C_0_0;
}
}
else if (!strcmp(string, "POLYLINE")) {
/* */
/* polygonal curve. */
/* */
poly_closed = false;
do {
if (!ReadNewDXFPair_fist(input, code, string, LINE_LENGTH))
throw EOF_ENCOUNTERED;
dxf_code = atoi(code);
switch(dxf_code) {
case 70:
poly_closed = (boolean) (1&atoi(string));
break;
default:
break;
}
} while (dxf_code != 0);
if (strcmp(string, "VERTEX"))
SkipUntilDXFString(input, code, string, "VERTEX");
DXFStartPoly(all);
poly_started = true;
old_bulge = C_0_0;
}
else if (!strcmp(string, "VERTEX")) {
/* */
/* vertex of a polygon. */
/* */
xc1_set = false;
yc1_set = false;
bulge = C_0_0;
do {
if (!ReadNewDXFPair_fist(input, code, string, LINE_LENGTH))
throw EOF_ENCOUNTERED;
dxf_code = atoi(code);
switch(dxf_code) {
case 10:
xc1 = FP_atof(string);
xc1_set = true;
break;
case 20:
yc1 = FP_atof(string);
yc1_set = true;
break;
case 42:
bulge = FP_atof(string);
break;
default:
break;
}
} while (dxf_code != 0);
if (poly_started && xc1_set && yc1_set) {
all->new_input = true;
DXFAddPolyVertex(all, xc1, yc1, old_bulge);
old_bulge = bulge;
}
xc1_set = false;
yc1_set = false;
}
else if (!strcmp(string, "SEQEND")) {
if (poly_closed) DXFCloseCurrentPoly(all, old_bulge);
poly_started = false;
if (!ReadNewDXFPair_fist(input, code, string, LINE_LENGTH))
throw EOF_ENCOUNTERED;
}
else if (string[0] == '$') {
/* */
/* some initialization stuff. we don't care about it. */
/* */
if (!ReadNewDXFPair_fist(input, code, string, LINE_LENGTH))
throw EOF_ENCOUNTERED;
}
else if (string[0] == '{') {
/* */
/* some application-specific stuff. we don't care about it. */
/* */
i = strlen(string) - 1;
if (string[i] != '}') {
SkipUntilDXFString(input, code, string, "}");
}
else {
if (!ReadNewDXFPair_fist(input, code, string, LINE_LENGTH))
throw EOF_ENCOUNTERED;
}
}
else if (!strcmp(string, "LAYER")) {
/* */
/* information on a layer. we skip it. */
/* */
SkipUntilDXFCode(input, code, string, 0);
}
else if (!strcmp(string, "BLOCK")) {
/* */
/* information on a block. we skip it. */
/* */
SkipUntilDXFString(input, code, string, "ENDBLK");
}
else if (!strcmp(string, "INSERT")) {
/* */
/* information on inserting a block. we skip it. */
/* */
SkipUntilDXFCode(input, code, string, 0);
}
else if (!strcmp(string, "SPLINE")) {
/* */
/* information on a spline. we skip it. */
/* */
SkipUntilDXFCode(input, code, string, 0);
}
else if (!strcmp(string, "ELLIPSE")) {
/* */
/* information on an ellipse. we skip it. */
/* */
SkipUntilDXFCode(input, code, string, 0);
}
else if (!strcmp(string, "TEXT")) {
/* */
/* text. we skip it. */
/* */
SkipUntilDXFCode(input, code, string, 0);
}
else if (!strcmp(string, "DIMENSION")) {
/* */
/* dimensons. we skip it. */
/* */
SkipUntilDXFCode(input, code, string, 0);
}
else if (!strcmp(string, "HATCH")) {
/* */
/* information on hatching. we skip it. */
/* */
SkipUntilDXFCode(input, code, string, 0);
}
else {
/* */
/* some dxf code that we don't care about. */
/* */
if (!ReadNewDXFPair_fist(input, code, string, LINE_LENGTH))
throw EOF_ENCOUNTERED;
}
}
i = i1;
fclose(input);
return;
}
/* */
/* this routines opens a file and writes the standard start-up DXF lines. */
/* */
void StartDXFFile(global_struct *all, char *file_name)
{
if ((all->dxf_file = fopen(file_name, "w")) != NULL) {
fprintf(all->dxf_file, " 0\nSECTION\n 2\nENTITIES\n");
}
else {
throw FILE_ACCESS_FAILED;
}
return;
}
/* */
/* this routines closes a file and writes the standard finishing DXF lines. */
/* */
void FinishDXFFile(global_struct *all)
{
if (all->dxf_file != (FILE*)NULL) {
fprintf(all->dxf_file, " 0\nENDSEC\n 0\nEOF\n");
fclose(all->dxf_file);
all->dxf_file = (FILE*)NULL;
}
else {
throw FILE_ACCESS_FAILED;
}
return;
}
/* */
/* output a 2D line segment in DXF format. */
/* */
void WriteDXFLine(global_struct *all, machine_double xc1, machine_double yc1,
machine_double xc2, machine_double yc2, int color)
{
if (all->dxf_file != (FILE*)NULL) {
fprintf(all->dxf_file, " 0\nLINE\n");
if (color >= 0) fprintf(all->dxf_file, " 62\n%3d\n", color);
fprintf(all->dxf_file, " 10\n%f\n 20\n%f\n 30\n0.0\n", xc1, yc1);
fprintf(all->dxf_file, " 11\n%f\n 21\n%f\n 31\n0.0\n", xc2, yc2);
}
else {
throw FILE_ACCESS_FAILED;
}
return;
}
/* */
/* output a 2D point in DXF format. */
/* */
void WriteDXFPoint(global_struct *all, machine_double xc1, machine_double yc1,
int color)
{
if (all->dxf_file != (FILE*)NULL) {
fprintf(all->dxf_file, " 0\nPOINT\n");
if (color >= 0) fprintf(all->dxf_file, " 62\n%3d\n", color);
fprintf(all->dxf_file, " 10\n%f\n 20\n%f\n 30\n0.0\n", xc1, yc1);
}
else {
throw FILE_ACCESS_FAILED;
}
return;
}
/* */
/* output a 2D circle in DXF format. */
/* */
void WriteDXFCircle(global_struct *all, machine_double xc1, machine_double yc1, machine_double radius, int color)
{
if (all->dxf_file != (FILE*)NULL) {
fprintf(all->dxf_file, " 0\nCIRCLE\n");
if (color >= 0) fprintf(all->dxf_file, " 62\n%3d\n", color);
fprintf(all->dxf_file, " 10\n%f\n 20\n%f\n 30\n0.0\n", xc1, yc1);
fprintf(all->dxf_file, " 40\n%f\n", radius);
}
else {
throw FILE_ACCESS_FAILED;
}
return;
}
#define M180_PI 57.2957795130823208767
/* */
/* output a 2D circular arc in DXF format. */
/* */
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)
{
machine_double s_a, s_e;
if (all->dxf_file != (FILE*)NULL) {
fprintf(all->dxf_file, " 0\nARC\n");
if (color >= 0) fprintf(all->dxf_file, " 62\n%3d\n", color);
fprintf(all->dxf_file, " 10\n%f\n 20\n%f\n 30\n0.0\n", xc3, yc3);
s_a = atan2(yc1 - yc3, xc1 - xc3) * M180_PI;
s_e = atan2(yc2 - yc3, xc2 - xc3) * M180_PI;
if (s_a < 0.0) s_a += 360.0;
if (s_e < 0.0) s_e += 360.0;
if (ccw_flag)
fprintf(all->dxf_file, " 50\n%f\n 51%f\n", s_a, s_e);
else
fprintf(all->dxf_file, " 50\n%f\n 51%f\n", s_e, s_e);
}
else {
throw FILE_ACCESS_FAILED;
}
return;
}
/* */
/* output the start code for "LWPOLYLINE" in DXF format. */
/* */
void WriteDXFLWPoly_Start(global_struct *all, boolean closed, int color)
{
if (all->dxf_file != (FILE*)NULL) {
fprintf(all->dxf_file, " 0\nLWPOLYLINE\n");
if (closed) fprintf(all->dxf_file, " 70\n 1\n");
else fprintf(all->dxf_file, " 70\n 0\n");
if (color >= 0) fprintf(all->dxf_file, " 62\n%3d\n", color);
fprintf(all->dxf_file, " 8\nFIST\n");
fprintf(all->dxf_file, " 6\nCONTINUOUS\n");
}
else {
throw FILE_ACCESS_FAILED;
}
return;
}
/* */
/* output the start code for "POLYLINE" in DXF format. */
/* */
void WriteDXFPoly_Start(global_struct *all, boolean closed, int color)
{
if (all->dxf_file != (FILE*)NULL) {
fprintf(all->dxf_file, " 0\nPOLYLINE\n");
if (closed) fprintf(all->dxf_file, " 70\n 1\n");
else fprintf(all->dxf_file, " 70\n 0\n");
if (color >= 0) fprintf(all->dxf_file, " 62\n%3d\n", color);
}
else {
throw FILE_ACCESS_FAILED;
}
return;
}
/* */
/* output the end code for "POLYLINE" in DXF format. */
/* */
void WriteDXFPoly_End(global_struct *all)
{
if (all->dxf_file != (FILE*)NULL) {
fprintf(all->dxf_file, " 0\nSEQEND\n");
}
else {
throw FILE_ACCESS_FAILED;
}
return;
}
/* */
/* output one vertex of a "LWPOLYLINE" in DXF format. */
/* */
void WriteDXFLWPoly_Vertex(global_struct *all,
machine_double xc1, machine_double yc1,
machine_double bulge)
{
if (all->dxf_file != (FILE*)NULL) {
fprintf(all->dxf_file, " 10\n%f\n 20\n%f\n 30\n0.0\n", xc1, yc1);
if (bulge != 0.0) fprintf(all->dxf_file, " 42\n%f\n", bulge);
}
else {
throw FILE_ACCESS_FAILED;
}
return;
}
/* */
/* output one vertex of a "POLYLINE" in DXF format. */
/* */
void WriteDXFPoly_Vertex(global_struct *all, machine_double xc1, machine_double yc1,
machine_double bulge)
{
if (all->dxf_file != (FILE*)NULL) {
fprintf(all->dxf_file, " 0\nVERTEX\n");
fprintf(all->dxf_file, " 10\n%f\n 20\n%f\n 30\n0.0\n", xc1, yc1);
if (bulge != 0.0) fprintf(all->dxf_file, " 42\n%f\n", bulge);
}
else {
throw FILE_ACCESS_FAILED;
}
return;
}