/*
* GeometryReader.h
* PAB
*
* Created by XXXXXXX on 4/1/07.
* Copyright 2007 __MyCompanyName__. All rights reserved.
*
*/
#include <gts.h>
/* surface */
GtsSurface *s;
/* tree */
GNode *tree;
/* bounding box */
GtsBBox * geom_bbox;
/*
* GeometryReader.c
* PAB
*
* Created by XXXXXXXXXXX on 4/1/07.
* Copyright 2007 __MyCompanyName__. All rights reserved.
*
*/
#include “GeometryReader.h”
#ifdef __WITH_GTS__
static void build_list (gpointer data, GSList ** list)
{
/* always use O(1) g_slist_prepend instead of O(n) g_slist_append */
*list = g_slist_prepend (*list, data);
}
static void build_list1 (gpointer data, GList ** list)
{
/* always use O(1) g_list_prepend instead of O(n) g_list_append */
*list = g_list_prepend (*list, data);
}
static void edge_cleanup (GtsSurface *surface)
{
GSList * edges = NULL;
GSList * i;
int j;
// g_return_if_fail (surface != NULL);
/* build list of edges */
gts_surface_foreach_edge (surface, (GtsFunc) build_list, &edges);
/* We want to control manually the destruction of edges */
gts_allow_floating_edges = TRUE;
i = edges;
j = 0;
while (i) {
j++;
GtsEdge * e = i->data;
GtsEdge * duplicate;
if (GTS_SEGMENT (e)->v1 == GTS_SEGMENT (e)->v2) /* edge is degenerate */
/* destroy e */
gts_object_destroy (GTS_OBJECT (e));
else if ((duplicate = gts_edge_is_duplicate (e))) {
/* replace e with its duplicate */
gts_edge_replace (e, duplicate);
/* destroy e */
gts_object_destroy (GTS_OBJECT (e));
}
i = i->next;
}
/* don’t forget to reset to default */
gts_allow_floating_edges = FALSE;
/* free list of edges */
g_slist_free (edges);
}
static void triangle_cleanup (GtsSurface * s)
{
GSList * triangles = NULL;
GSList * i;
//g_return_if_fail (s != NULL);
/* build list of triangles */
gts_surface_foreach_face (s, (GtsFunc) build_list, &triangles);
/* remove duplicate triangles */
i = triangles;
while (i) {
GtsTriangle * t = i->data;
if (gts_triangle_is_duplicate (t))
/* destroy t, its edges (if not used
* by any other triangle)
* and its corners (if not
* used by any other edge) */
gts_object_destroy (GTS_OBJECT (t));
i = i->next;
}
/* free list of triangles */
g_slist_free (triangles);
}
void GeometryReadGTSFile(char * filename)
{
GtsFile * fp;
GList *vtx = NULL;
FILE * file;
gboolean (* check) (GtsVertex *, GtsVertex *) = NULL;
gboolean is_closed;
gboolean is_orientable;
file = fopen(filename,“r”);
s = gts_surface_new(gts_surface_class(),
gts_face_class(),
gts_edge_class(),
gts_vertex_class());
fp = gts_file_new(file);
if(gts_surface_read(s,fp)){
printf(“GTS file could not be read\n”);
}
fclose(file);
/* Merge vertices that are too close together */
gts_surface_foreach_vertex (s, (GtsFunc) build_list1, &vtx);
vtx = gts_vertices_merge (vtx, (gdouble)1e-6, check);
g_list_free (vtx);
printf(“# Merged vertices closer than 1e-6\n”);
/* Remove duplicate edges */
edge_cleanup (s);
printf(“# Removed degenerate and duplicate edges\n”);
/* eliminate duplicate triangles */
triangle_cleanup (s);
printf(“# Removed degenerate and duplicate triangles\n”);
/* Check that the surface has no boundary */
/* print some nice statistics */
gts_surface_print_stats(s,stdout);
/* Check that the surface is closed and orientable (required for bb_tree */
is_closed = gts_surface_is_closed(s);
is_orientable = gts_surface_is_orientable(s);
if(is_closed && is_orientable)
printf(“# Surface is closed, connected, and orientable\n”);
/* construct the tree for fast triangle search */
tree = gts_bb_tree_surface(s);
geom_bbox = gts_bbox_bboxes(gts_bbox_class(),s);
printf(“# Built fast Kd tree for triangle lookup\n”);
geom_bbox = gts_bbox_surface (gts_bbox_class (), s);
return;
}
void GeometryReaderFinalize()
{
/* Destroy the surface and the tree */
gts_object_destroy(GTS_OBJECT (s));
g_node_destroy(tree);
/* finalize GTS library and free all memory */
gts_finalize();
}
/* check if a point lies inside the body */
int GeometryReaderIsPointInside(double fx, double fy, double fz)
{
GtsPoint *p;
gboolean is_inside;
gdouble x,y,z;
x = (gdouble)fx;
y = (gdouble)fy;
z = (gdouble)fz;
p = gts_point_new(gts_point_class(),x,y,z);
is_inside = gts_point_is_inside_surface(p,tree,FALSE);
gts_object_destroy(GTS_OBJECT(p));
if(is_inside){
return 1;
} else {
return 0;
}
}
#endif