cbec90699f
- creato il progetto in Visual Studio per compilare come libreria statica - modifiche al codice originale per integrarlo nelle nostre librerie.
227 lines
7.5 KiB
C++
227 lines
7.5 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 <stdlib.h>
|
|
#include <assert.h>
|
|
|
|
/* */
|
|
/* get my header files */
|
|
/* */
|
|
#include "fpkernel.h"
|
|
#include "martin.h"
|
|
#include "defs.h"
|
|
#include "list.h"
|
|
#include "header.h"
|
|
#include "ipe_io.h"
|
|
|
|
/* */
|
|
/* function prototypes of functions provided in this file */
|
|
/* */
|
|
void WriteIpePolygon(global_struct *all);
|
|
void WriteIpeOutput(global_struct *all);
|
|
|
|
|
|
/* */
|
|
/* this function writes a simply-connected or multiply-connected polygon */
|
|
/* in a format suitable for Ipe */
|
|
/* */
|
|
void WriteIpePolygon(global_struct *all)
|
|
{
|
|
listdef *list = &all->c_list;
|
|
ipe_iodef *ipeio = &all->c_ipe_io;
|
|
|
|
int i;
|
|
FILE *fp;
|
|
void WriteIpeContour(global_struct *all, FILE *fp, list_ind ind1);
|
|
void WriteIpeVertices(global_struct *all, FILE *fp, list_ind ind1);
|
|
|
|
fp = InitIpe(ipeio, all->rt_opt.ipe_file,
|
|
TO_MDOUBLE(all->bb_min.x), TO_MDOUBLE(all->bb_max.x),
|
|
TO_MDOUBLE(all->bb_min.y), TO_MDOUBLE(all->bb_max.y));
|
|
all->ipe_initialized = true;
|
|
|
|
fprintf(fp,"<group layer=\"Polygon\">\n");
|
|
for (i = 0; i < list->num_loops; ++i) {
|
|
WriteIpeContour(all, fp, list->loops[i]);
|
|
}
|
|
fprintf(fp,"</group>\n");
|
|
|
|
fprintf(fp,"<group layer=\"Vertices\">\n");
|
|
for (i = 0; i < list->num_loops; ++i) {
|
|
WriteIpeVertices(all, fp, list->loops[i]);
|
|
}
|
|
fprintf(fp,"</group>\n");
|
|
|
|
fclose(fp);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void WriteIpeContour(global_struct *all, FILE *fp, list_ind ind1)
|
|
{
|
|
listdef *list = &all->c_list;
|
|
datadef *data = &all->c_data;
|
|
ipe_iodef *ipeio = &all->c_ipe_io;
|
|
|
|
int i, index, num_ele;
|
|
|
|
num_ele = CountListElements(list, ind1);
|
|
fprintf(fp,"<path stroke=\"seagreen\" pen=\"fat\">\n");
|
|
|
|
index = GetIndex(list, ind1);
|
|
WriteSegmentFirstPnt(ipeio, fp, TO_MDOUBLE(data->points[index].x),
|
|
TO_MDOUBLE(data->points[index].y));
|
|
|
|
for (i = 1; i < num_ele; ++i) {
|
|
ind1 = GetNextNode(list, ind1);
|
|
index = GetIndex(list, ind1);
|
|
WriteSegmentNextPnt(ipeio, fp, TO_MDOUBLE(data->points[index].x),
|
|
TO_MDOUBLE(data->points[index].y));
|
|
}
|
|
ind1 = GetNextNode(list, ind1);
|
|
index = GetIndex(list, ind1);
|
|
|
|
fprintf(fp,"h\n</path>\n");
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
void WriteIpeVertices(global_struct *all, FILE *fp, list_ind ind1)
|
|
{
|
|
listdef *list = &all->c_list;
|
|
datadef *data = &all->c_data;
|
|
ipe_iodef *ipeio = &all->c_ipe_io;
|
|
|
|
int i, index, num_ele;
|
|
|
|
num_ele = CountListElements(list, ind1);
|
|
|
|
for (i = 0; i < num_ele; ++i) {
|
|
ind1 = GetNextNode(list, ind1);
|
|
index = GetIndex(list, ind1);
|
|
WriteMark(ipeio, fp, 0.0, 0.0, 0.0, 2, 2.0,
|
|
TO_MDOUBLE(data->points[index].x),
|
|
TO_MDOUBLE(data->points[index].y));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
/* */
|
|
/* this function appends the triangulation to the Ipe-file. */
|
|
/* */
|
|
void WriteIpeOutput(global_struct *all)
|
|
{
|
|
vertexdef *vert = &all->c_vertex;
|
|
ipe_iodef *ipeio = &all->c_ipe_io;
|
|
|
|
FILE *fp;
|
|
int e_comp(const void *a, const void *);
|
|
int i, j = 0, num_edges = 0;
|
|
edge *edges;
|
|
|
|
if (!all->ipe_initialized) throw IPE_FILE_NOT_INITIALIZED;
|
|
|
|
fp = OpenFile(all->rt_opt.ipe_file, "a");
|
|
|
|
num_edges = 3 * (GetNumTriangles(vert)+1);
|
|
edges = (edge*) ReallocateArray(vert->memptr, (edge*)NULL,
|
|
num_edges, sizeof(edge),
|
|
"write_ipe: edges");
|
|
|
|
for (i = 0; i < vert->num_triangles; ++i) {
|
|
#ifdef PARTITION_FIST
|
|
if(vert->triangles[i].disabled) continue;
|
|
#endif
|
|
if (vert->triangles[i].v1 < vert->triangles[i].v2) {
|
|
edges[j].v1 = vert->triangles[i].v1;
|
|
edges[j].v2 = vert->triangles[i].v2;
|
|
}
|
|
else {
|
|
edges[j].v2 = vert->triangles[i].v1;
|
|
edges[j].v1 = vert->triangles[i].v2;
|
|
}
|
|
++j;
|
|
if (vert->triangles[i].v1 < vert->triangles[i].v3) {
|
|
edges[j].v1 = vert->triangles[i].v1;
|
|
edges[j].v2 = vert->triangles[i].v3;
|
|
}
|
|
else {
|
|
edges[j].v2 = vert->triangles[i].v1;
|
|
edges[j].v1 = vert->triangles[i].v3;
|
|
}
|
|
++j;
|
|
if (vert->triangles[i].v2 < vert->triangles[i].v3) {
|
|
edges[j].v1 = vert->triangles[i].v2;
|
|
edges[j].v2 = vert->triangles[i].v3;
|
|
}
|
|
else {
|
|
edges[j].v2 = vert->triangles[i].v2;
|
|
edges[j].v1 = vert->triangles[i].v3;
|
|
}
|
|
++j;
|
|
}
|
|
qsort(edges, num_edges, sizeof(edge), &e_comp);
|
|
|
|
i = 0;
|
|
for (j = 1; j < num_edges; ++j) {
|
|
if (e_comp(edges + i, edges + j) != 0) {
|
|
++i;
|
|
edges[i] = edges[j];
|
|
}
|
|
}
|
|
num_edges = i + 1;
|
|
|
|
fprintf(fp,"<group layer=\"Triangulation\">\n");
|
|
for (i = 0; i < num_edges; ++i) {
|
|
fprintf(fp,"<path stroke=\"blue\" pen=\"normal\">\n");
|
|
WriteLineFirstPnt(ipeio,fp,
|
|
TO_MDOUBLE(vert->vertices[edges[i].v1].x),
|
|
TO_MDOUBLE(vert->vertices[edges[i].v1].y));
|
|
WriteLineNextPnt(ipeio,fp,
|
|
TO_MDOUBLE(vert->vertices[edges[i].v2].x),
|
|
TO_MDOUBLE(vert->vertices[edges[i].v2].y));
|
|
fprintf(fp,"</path>\n");
|
|
}
|
|
|
|
FreeMemory(vert->memptr, (void**) &edges, "write_ipe:edges");
|
|
|
|
fprintf(fp,"</group>\n</page>\n</ipe>\n");
|
|
fclose(fp);
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
int e_comp(const void *a, const void *b)
|
|
{
|
|
if (((edge*)a)->v1 < ((edge*)b)->v1) return -1;
|
|
else if (((edge*)a)->v1 > ((edge*)b)->v1) return 1;
|
|
else {
|
|
if (((edge*)a)->v2 < ((edge*)b)->v2) return -1;
|
|
else if (((edge*)a)->v2 > ((edge*)b)->v2) return 1;
|
|
else return 0;
|
|
}
|
|
}
|