/*

 *  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