/** * gts_graph_partition_print_stats: * @partition: a list of @GtsGraph representing a partition. * @fp: a file pointer. * * Writes to @fp a summary of the properties of @partition. */ void gts_graph_partition_print_stats (GSList * partition, FILE * fp) { GtsRange weight; GSList * i; g_return_if_fail (partition != NULL); g_return_if_fail (fp != NULL); gts_range_init (&weight); i = partition; while (i) { gts_range_add_value (&weight, gts_graph_weight (i->data)); i = i->next; } gts_range_update (&weight); fprintf (fp, "# parts: %d\n" "# edge cuts: %5d edge cuts weight: %5g\n" "# weight: ", g_slist_length (partition), gts_graph_partition_edges_cut (partition), gts_graph_partition_edges_cut_weight (partition)); gts_range_print (&weight, fp); fputc ('\n', fp); }
/** * gts_bb_tree_triangle_distance: * @tree: a bounding box tree. * @t: a #GtsTriangle. * @distance: a #GtsBBoxDistFunc. * @delta: spatial scale of the sampling to be used. * @range: a #GtsRange to be filled with the results. * * Given a triangle @t, points are sampled regularly on its surface * using @delta as increment. The distance from each of these points * to the closest object of @tree is computed using @distance and the * gts_bb_tree_point_distance() function. The fields of @range are * filled with the number of points sampled, the minimum, average and * maximum value and the standard deviation. */ void gts_bb_tree_triangle_distance (GNode * tree, GtsTriangle * t, GtsBBoxDistFunc distance, gdouble delta, GtsRange * range) { GtsPoint * p1, * p2, * p3, * p; GtsVector p1p2, p1p3; gdouble l1, t1, dt1; guint i, n1; g_return_if_fail (tree != NULL); g_return_if_fail (t != NULL); g_return_if_fail (distance != NULL); g_return_if_fail (delta > 0.); g_return_if_fail (range != NULL); gts_triangle_vertices (t, (GtsVertex **) &p1, (GtsVertex **) &p2, (GtsVertex **) &p3); gts_vector_init (p1p2, p1, p2); gts_vector_init (p1p3, p1, p3); gts_range_init (range); p = GTS_POINT (gts_object_new (GTS_OBJECT_CLASS (gts_point_class ()))); l1 = sqrt (gts_vector_scalar (p1p2, p1p2)); n1 = l1/delta + 1; dt1 = 1.0/(gdouble) n1; t1 = 0.0; for (i = 0; i <= n1; i++, t1 += dt1) { gdouble t2 = 1. - t1; gdouble x = t2*p1p3[0]; gdouble y = t2*p1p3[1]; gdouble z = t2*p1p3[2]; gdouble l2 = sqrt (x*x + y*y + z*z); guint j, n2 = (guint) (l2/delta + 1); gdouble dt2 = t2/(gdouble) n2; x = t2*p1->x + t1*p2->x; y = t2*p1->y + t1*p2->y; z = t2*p1->z + t1*p2->z; t2 = 0.0; for (j = 0; j <= n2; j++, t2 += dt2) { p->x = x + t2*p1p3[0]; p->y = y + t2*p1p3[1]; p->z = z + t2*p1p3[2]; gts_range_add_value (range, gts_bb_tree_point_distance (tree, p, distance, NULL)); } } gts_object_destroy (GTS_OBJECT (p)); gts_range_update (range); }
/** * gts_bb_tree_segment_distance: * @tree: a bounding box tree. * @s: a #GtsSegment. * @distance: a #GtsBBoxDistFunc. * @delta: spatial scale of the sampling to be used. * @range: a #GtsRange to be filled with the results. * * Given a segment @s, points are sampled regularly on its length * using @delta as increment. The distance from each of these points * to the closest object of @tree is computed using @distance and the * gts_bb_tree_point_distance() function. The fields of @range are * filled with the number of points sampled, the minimum, average and * maximum value and the standard deviation. */ void gts_bb_tree_segment_distance (GNode * tree, GtsSegment * s, gdouble (*distance) (GtsPoint *, gpointer), gdouble delta, GtsRange * range) { GtsPoint * p1, * p2, * p; GtsVector p1p2; gdouble l, t, dt; guint i, n; g_return_if_fail (tree != NULL); g_return_if_fail (s != NULL); g_return_if_fail (distance != NULL); g_return_if_fail (delta > 0.); g_return_if_fail (range != NULL); p1 = GTS_POINT (s->v1); p2 = GTS_POINT (s->v2); gts_vector_init (p1p2, p1, p2); gts_range_init (range); p = GTS_POINT (gts_object_new (GTS_OBJECT_CLASS (gts_point_class()))); l = sqrt (gts_vector_scalar (p1p2, p1p2)); n = (guint) (l/delta + 1); dt = 1.0/(gdouble) n; t = 0.0; for (i = 0; i <= n; i++, t += dt) { p->x = p1->x + t*p1p2[0]; p->y = p1->y + t*p1p2[1]; p->z = p1->z + t*p1p2[2]; gts_range_add_value (range, gts_bb_tree_point_distance (tree, p, distance, NULL)); } gts_object_destroy (GTS_OBJECT (p)); gts_range_update (range); }
/** * gts_bb_tree_surface_boundary_distance: * @tree: a bounding box tree. * @s: a #GtsSurface. * @distance: a #GtsBBoxDistFunc. * @delta: a sampling increment defined as the percentage of the diagonal * of the root bounding box of @tree. * @range: a #GtsRange to be filled with the results. * * Calls gts_bb_tree_segment_distance() for each edge boundary of @s. * The fields of @range are filled with the minimum, maximum and * average distance. The average distance is defined as the sum of the * average distances for each boundary edge weighthed by their length * and divided by the total length of the boundaries. The standard * deviation is defined accordingly. The @n field of @range is filled * with the number of sampled points used. */ void gts_bb_tree_surface_boundary_distance (GNode * tree, GtsSurface * s, gdouble (*distance) (GtsPoint *, gpointer), gdouble delta, GtsRange * range) { gpointer data[5]; gdouble total_length = 0.; g_return_if_fail (tree != NULL); g_return_if_fail (s != NULL); g_return_if_fail (delta > 0. && delta < 1.); g_return_if_fail (range != NULL); gts_range_init (range); delta *= sqrt (gts_bbox_diagonal2 (tree->data)); data[0] = tree; data[1] = δ data[2] = range; data[3] = &total_length; data[4] = distance; gts_surface_foreach_edge (s, (GtsFunc) surface_distance_foreach_boundary, data); if (total_length > 0.) { if (range->sum2 - range->sum*range->sum/total_length >= 0.) range->stddev = sqrt ((range->sum2 - range->sum*range->sum/total_length) /total_length); else range->stddev = 0.; range->mean = range->sum/total_length; } else range->min = range->max = range->mean = range->stddev = 0.; }
/** * gts_bb_tree_surface_distance: * @tree: a bounding box tree. * @s: a #GtsSurface. * @distance: a #GtsBBoxDistFunc. * @delta: a sampling increment defined as the percentage of the diagonal * of the root bounding box of @tree. * @range: a #GtsRange to be filled with the results. * * Calls gts_bb_tree_triangle_distance() for each face of @s. The * fields of @range are filled with the minimum, maximum and average * distance. The average distance is defined as the sum of the average * distances for each triangle weighthed by their area and divided by * the total area of the surface. The standard deviation is defined * accordingly. The @n field of @range is filled with the number of * sampled points used. */ void gts_bb_tree_surface_distance (GNode * tree, GtsSurface * s, GtsBBoxDistFunc distance, gdouble delta, GtsRange * range) { gpointer data[5]; gdouble total_area = 0.; g_return_if_fail (tree != NULL); g_return_if_fail (s != NULL); g_return_if_fail (delta > 0. && delta < 1.); g_return_if_fail (range != NULL); gts_range_init (range); delta *= sqrt (gts_bbox_diagonal2 (tree->data)); data[0] = tree; data[1] = δ data[2] = range; data[3] = &total_area; data[4] = distance; gts_surface_foreach_face (s, (GtsFunc) surface_distance_foreach_triangle, data); if (total_area > 0.) { if (range->sum2 - range->sum*range->sum/total_area >= 0.) range->stddev = sqrt ((range->sum2 - range->sum*range->sum/total_area) /total_area); else range->stddev = 0.; range->mean = range->sum/total_area; } else range->min = range->max = range->mean = range->stddev = 0.; }
/* stripe - Turns the input surface into triangle strips and outputs a Geomview representation of the result. */ int main (int argc, char * argv[]) { GtsSurface * s; GSList * strips = NULL, * i; gboolean verbose = FALSE; int c = 0; GtsFile * fp; /* parse options using getopt */ while (c != EOF) { #ifdef HAVE_GETOPT_LONG static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"verbose", no_argument, NULL, 'v'} }; int option_index = 0; switch ((c = getopt_long (argc, argv, "hv", long_options, &option_index))) { #else /* not HAVE_GETOPT_LONG */ switch ((c = getopt (argc, argv, "hv"))) { #endif /* not HAVE_GETOPT_LONG */ case 'v': /* verbose */ verbose = TRUE; break; case 'h': /* help */ fprintf (stderr, "Usage: stripe [OPTION] < FILE\n" "Turns the input surface into triangle strips and outputs a\n" "Geomview representation of the result.\n" "\n" " -v --verbose print statistics about the surface and strips\n" " -h --help display this help and exit\n" "\n" "Report bugs to %s\n", GTS_MAINTAINER); return 0; /* success */ break; case '?': /* wrong options */ fprintf (stderr, "Try `stripe --help' for more information.\n"); return 1; /* failure */ } } /* read surface in */ s = gts_surface_new (gts_surface_class (), gts_face_class (), gts_edge_class (), gts_vertex_class ()); fp = gts_file_new (stdin); if (gts_surface_read (s, fp)) { fputs ("stripe: file on standard input is not a valid GTS file\n", stderr); fprintf (stderr, "stdin:%d:%d: %s\n", fp->line, fp->pos, fp->error); return 1; /* failure */ } gts_file_destroy (fp); if (verbose) gts_surface_print_stats (s, stderr); strips = gts_surface_strip (s); /* if verbose on print stats */ if (verbose) { GtsRange l; gts_range_init (&l); i = strips; while (i) { gts_range_add_value (&l, g_slist_length (i->data)); i = i->next; } gts_range_update (&l); fprintf (stderr, "# Strips: %d\n# length : ", l.n); gts_range_print (&l, stderr); fputc ('\n', stderr); } puts ("LIST {\n"); i = strips; while (i) { GList * j = i->data; GtsTriangle * oldt = NULL; GtsColor c; c.r = rand ()/(gdouble) RAND_MAX; c.g = rand ()/(gdouble) RAND_MAX; c.b = rand ()/(gdouble) RAND_MAX; while (j) { GtsTriangle * t = j->data; GtsPoint * p1 = GTS_POINT (GTS_SEGMENT (t->e1)->v1), * p2 = GTS_POINT (GTS_SEGMENT (t->e1)->v2), * p3 = GTS_POINT (gts_triangle_vertex (t)); printf ("OFF 3 1 3\n%g %g %g\n%g %g %g\n%g %g %g\n3 0 1 2 %g %g %g\n", p1->x, p1->y, p1->z, p2->x, p2->y, p2->z, p3->x, p3->y, p3->z, c.r, c.g, c.b); if (oldt) { GtsSegment * cs = GTS_SEGMENT (gts_triangles_common_edge (t, oldt)); GtsPoint * op1 = GTS_POINT (GTS_SEGMENT (oldt->e1)->v1), * op2 = GTS_POINT (GTS_SEGMENT (oldt->e1)->v2), * op3 = GTS_POINT (gts_triangle_vertex (oldt)); printf ("VECT 1 3 0 3 0 %g %g %g %g %g %g %g %g %g\n", (op1->x + op2->x + op3->x)/3., (op1->y + op2->y + op3->y)/3., (op1->z + op2->z + op3->z)/3., (GTS_POINT (cs->v1)->x + GTS_POINT (cs->v2)->x)/2., (GTS_POINT (cs->v1)->y + GTS_POINT (cs->v2)->y)/2., (GTS_POINT (cs->v1)->z + GTS_POINT (cs->v2)->z)/2., (p1->x + p2->x + p3->x)/3., (p1->y + p2->y + p3->y)/3., (p1->z + p2->z + p3->z)/3.); } oldt = t; j = j->next; } i = i->next; } puts ("}\n"); return 0; /* success */ }
int main (int argc, char * argv[]) { GtsSurface * s; gboolean verbose = FALSE; gdouble threshold; int c = 0; GtsFile * fp; GtsRange angle; if (!setlocale (LC_ALL, "POSIX")) g_warning ("cannot set locale to POSIX"); /* parse options using getopt */ while (c != EOF) { #ifdef HAVE_GETOPT_LONG static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"verbose", no_argument, NULL, 'v'}, { NULL } }; int option_index = 0; switch ((c = getopt_long (argc, argv, "hv", long_options, &option_index))) { #else /* not HAVE_GETOPT_LONG */ switch ((c = getopt (argc, argv, "hv"))) { #endif /* not HAVE_GETOPT_LONG */ case 'v': /* verbose */ verbose = TRUE; break; case 'h': /* help */ fprintf (stderr, "Usage: optimize [OPTION] THRESHOLD < FILE\n" "\n" " -v --verbose print statistics about the surface\n" " -h --help display this help and exit\n" "\n" "Report bugs to %s\n", GTS_MAINTAINER); return 0; /* success */ break; case '?': /* wrong options */ fprintf (stderr, "Try `optimize --help' for more information.\n"); return 1; /* failure */ } } if (optind >= argc) { /* missing threshold */ fprintf (stderr, "optimize: missing THRESHOLD\n" "Try `optimize --help' for more information.\n"); return 1; /* failure */ } threshold = strtod (argv[optind], NULL); if (threshold < 0.0) { /* threshold must be positive */ fprintf (stderr, "optimize: THRESHOLD must be >= 0.0\n" "Try `optimize --help' for more information.\n"); return 1; /* failure */ } /* read surface in */ s = gts_surface_new (gts_surface_class (), gts_face_class (), gts_edge_class (), gts_vertex_class ()); fp = gts_file_new (stdin); if (gts_surface_read (s, fp)) { fputs ("optimize: file on standard input is not a valid GTS file\n", stderr); fprintf (stderr, "stdin:%d:%d: %s\n", fp->line, fp->pos, fp->error); return 1; /* failure */ } /* if verbose on print stats */ if (verbose) { gts_surface_print_stats (s, stderr); gts_range_init (&angle); gts_surface_foreach_edge (s, (GtsFunc) angle_stats, &angle); gts_range_update (&angle); fputs ("# angle : ", stderr); gts_range_print (&angle, stderr); fputc ('\n', stderr); } surface_optimize (s, -threshold); /* if verbose on print stats */ if (verbose) { gts_surface_print_stats (s, stderr); gts_range_init (&angle); gts_surface_foreach_edge (s, (GtsFunc) angle_stats, &angle); gts_range_update (&angle); fputs ("# angle : ", stderr); gts_range_print (&angle, stderr); fputc ('\n', stderr); } /* write surface */ gts_surface_write (s, stdout); return 0; /* success */ }
int main (int argc, char * argv[]) { GtsSurface * s; GtsFile * fp; GtsFace * first = NULL; int c = 0; gboolean verbose = FALSE; if (!setlocale (LC_ALL, "POSIX")) g_warning ("cannot set locale to POSIX"); colormap = colormap_red_blue (); /* default */ /* parse options using getopt */ while (c != EOF) { #ifdef HAVE_GETOPT_LONG static struct option long_options[] = { {"cmap", required_argument, NULL, 'c'}, {"help", no_argument, NULL, 'h'}, {"verbose", no_argument, NULL, 'v'}, { NULL } }; int option_index = 0; switch ((c = getopt_long (argc, argv, "hvc:", long_options, &option_index))) { #else /* not HAVE_GETOPT_LONG */ switch ((c = getopt (argc, argv, "hvc:"))) { #endif /* not HAVE_GETOPT_LONG */ case 'c': { /* cmap */ FILE * fptr = fopen (optarg, "rt"); if (!fptr) { fprintf (stderr, "traverse: cannot open colormap file `%s'.\n", optarg); return 1; } colormap = colormap_read (fptr); fclose (fptr); break; } case 'v': /* verbose */ verbose = TRUE; break; case 'h': /* help */ fprintf (stderr, "Usage: traverse [OPTION] < file.gts > file.oogl\n" "Output an OOGL (geomview) surface colored according to the (graph) distance\n" "from a random face to the others\n" "\n" " -c FILE --cmap=FILE load FILE as colormap\n" " -v --verbose print statistics about the surface\n" " -h --help display this help and exit\n" "\n" "Reports bugs to %s\n", GTS_MAINTAINER); return 0; /* success */ break; case '?': /* wrong options */ fprintf (stderr, "Try `traverse --help' for more information.\n"); return 1; /* failure */ } } s = gts_surface_new (gts_surface_class (), GTS_FACE_CLASS (depth_face_class ()), gts_edge_class (), gts_vertex_class ()); fp = gts_file_new (stdin); if (gts_surface_read (s, fp)) { fputs ("traverse: file on standard input is not a valid GTS file\n", stderr); fprintf (stderr, "stdin:%d:%d: %s\n", fp->line, fp->pos, fp->error); return 1; /* failure */ } if (verbose) gts_surface_print_stats (s, stderr); gts_surface_foreach_face (s, (GtsFunc) pick_first_face, &first); gts_range_init (&depth_range); if (first) { GtsSurfaceTraverse * t = gts_surface_traverse_new (s, first); GtsFace * f; guint level; while ((f = gts_surface_traverse_next (t, &level))) { DEPTH_FACE (f)->depth = level; gts_range_add_value (&depth_range, level); } gts_surface_traverse_destroy (t); } gts_range_update (&depth_range); if (verbose) { fputs ("distance: ", stderr); gts_range_print (&depth_range, stderr); fputc ('\n', stderr); } gts_surface_write_oogl (s, stdout); return 0; }