Esempio n. 1
0
File: oocs.c Progetto: Gilles86/afni
int main (int argc, char * argv[])
{
  GtsSurface * s;
  GtsBBox * bbox;
  gdouble delta;
  GtsPoint * p1, * p2, * p3;
  guint nt;
  GtsRange cluster_stats;
  GtsClusterGrid * cluster_grid;
  
  if (argc != 2) {
    fprintf (stderr, "usage: oocs DELTA < infile > outfile\n");
    return 1;
  }

  s = gts_surface_new (gts_surface_class (),
		       gts_face_class (),
		       gts_edge_class (),
		       gts_vertex_class ());

  bbox = gts_bbox_new (gts_bbox_class (), s, 0., 0., 0., 0., 0., 0.);
  scanf ("%u", &nt);
  scanf ("%lf %lf %lf", &bbox->x1, &bbox->y1, &bbox->z1);
  scanf ("%lf %lf %lf", &bbox->x2, &bbox->y2, &bbox->z2);
  delta = atof (argv[1])*sqrt (gts_bbox_diagonal2 (bbox));

  cluster_grid = gts_cluster_grid_new (gts_cluster_grid_class (), 
				       gts_cluster_class (), 
				       s, bbox, delta);

  p1 = gts_point_new (gts_point_class (), 0., 0., 0.);
  p2 = gts_point_new (gts_point_class (), 0., 0., 0.);
  p3 = gts_point_new (gts_point_class (), 0., 0., 0.);

  while (scanf ("%lf %lf %lf", &p1->x, &p1->y, &p1->z) == 3 &&
	 scanf ("%lf %lf %lf", &p2->x, &p2->y, &p2->z) == 3 &&
	 scanf ("%lf %lf %lf", &p3->x, &p3->y, &p3->z) == 3)
    gts_cluster_grid_add_triangle (cluster_grid, p1, p2, p3, NULL);
  cluster_stats = gts_cluster_grid_update (cluster_grid);

  gts_object_destroy (GTS_OBJECT (p1));
  gts_object_destroy (GTS_OBJECT (p2));
  gts_object_destroy (GTS_OBJECT (p3));
  gts_object_destroy (GTS_OBJECT (cluster_grid));

  fprintf (stderr, "Initial number of triangles: %u\n", nt);
  fprintf (stderr, "%d clusters of size: min: %g avg: %.1f|%.1f max: %g\n",
	   cluster_stats.n,
	   cluster_stats.min, 
	   cluster_stats.mean, cluster_stats.stddev, 
	   cluster_stats.max);
  gts_surface_print_stats (s, stderr);
  gts_surface_write (s, stdout);

  return 0;
}
Esempio n. 2
0
/* This function is modified from the original in GTS in order to avoid 
 * deallocating any objects referenced by the live-objects table.  The 
 * approach is similar to what is used for replace() in vertex.c.
 */
GList*
pygts_vertices_merge(GList* vertices, gdouble epsilon,
		     gboolean (* check) (GtsVertex *, GtsVertex *))
{
  GPtrArray *array;
  GList *i, *next;
  GNode *kdtree;
  GtsVertex *v;
  GtsBBox *bbox;
  GSList *selected, *j;
  GtsVertex *sv;
  PygtsObject *obj;
  PygtsVertex *vertex=NULL;
  GSList *parents=NULL, *ii,*cur;

  g_return_val_if_fail(vertices != NULL, 0);

  array = g_ptr_array_new();
  i = vertices;
  while (i) {
    g_ptr_array_add(array, i->data);
    i = g_list_next(i);
  }
  kdtree = gts_kdtree_new(array, NULL);
  g_ptr_array_free(array, TRUE);

  i = vertices;
  while(i) {
    v = (GtsVertex*)i->data;
    if (!GTS_OBJECT(v)->reserved) { /* Do something only if v is active */

      /* build bounding box */
      bbox = gts_bbox_new(gts_bbox_class(), v, 
			  GTS_POINT(v)->x - epsilon,
			  GTS_POINT(v)->y - epsilon,
			  GTS_POINT(v)->z - epsilon,
			  GTS_POINT(v)->x + epsilon,
			  GTS_POINT(v)->y + epsilon,
			  GTS_POINT(v)->z + epsilon);

      /* select vertices which are inside bbox using kdtree */
      j = selected = gts_kdtree_range(kdtree, bbox, NULL);
      while(j) {
        sv = (GtsVertex*)j->data;
        if( sv!=v && !GTS_OBJECT(sv)->reserved && (!check||(*check)(sv, v)) ) {
          /* sv is not v and is active */
	  if( (obj = (PygtsObject*)g_hash_table_lookup(obj_table,GTS_OBJECT(sv))) !=NULL ) {
	    vertex = PYGTS_VERTEX(obj);
	    /* Detach and save any parent segments */
	    ii = sv->segments;
	    while(ii!=NULL) {
	      cur = ii;
	      ii = g_slist_next(ii);
	      if(PYGTS_IS_PARENT_SEGMENT(cur->data)) {
		sv->segments = g_slist_remove_link(sv->segments, cur);
		parents = g_slist_prepend(parents,cur->data);
		g_slist_free_1(cur);
	      }
	    } 
	  }

          gts_vertex_replace(sv, v);
          GTS_OBJECT(sv)->reserved = sv; /* mark sv as inactive */

	  /* Reattach the parent segments */
	  if( vertex != NULL ) {
	    ii = parents;
	    while(ii!=NULL) {
	      sv->segments = g_slist_prepend(sv->segments, ii->data);
	      ii = g_slist_next(ii);
	    }
	    g_slist_free(parents);
	    parents = NULL;
	  }
	  vertex = NULL;
        }
        j = g_slist_next(j);
      }
      g_slist_free(selected);
      gts_object_destroy(GTS_OBJECT(bbox));
    }
    i = g_list_next(i);
  }
  gts_kdtree_destroy(kdtree);


  /* destroy inactive vertices and removes them from list */

  /* we want to control vertex destruction */
  gts_allow_floating_vertices = TRUE;

  i = vertices;
  while (i) {
    v = (GtsVertex*)i->data;
    next = g_list_next(i);
    if(GTS_OBJECT(v)->reserved) { /* v is inactive */
      if( g_hash_table_lookup(obj_table,GTS_OBJECT(v))==NULL ) {
	gts_object_destroy(GTS_OBJECT(v));
      }
      else {
	GTS_OBJECT(v)->reserved = 0;
      }
      vertices = g_list_remove_link(vertices, i);
      g_list_free_1(i);
    }
    i = next;
  }
  gts_allow_floating_vertices = FALSE; 

  return vertices;
}
Esempio n. 3
0
int main (int argc, char * argv[])
{
  GtsSurface * s;
  GtsFile * fp;
  GtsMatrix * m;
  int c = 0;
  gboolean verbose = FALSE;
  gboolean revert = FALSE;
  gboolean normalize = FALSE;

  if (!setlocale (LC_ALL, "POSIX"))
    g_warning ("cannot set locale to POSIX");

  m = gts_matrix_identity (NULL);

  /* parse options using getopt */
  while (c != EOF) {
#ifdef HAVE_GETOPT_LONG
    static struct option long_options[] = {
      {"rx", required_argument, NULL, 'r'},
      {"ry", required_argument, NULL, 'm'},
      {"rz", required_argument, NULL, 'n'},
      {"scale", required_argument, NULL, 's'},
      {"sx", required_argument, NULL, 'R'},
      {"sy", required_argument, NULL, 'M'},
      {"sz", required_argument, NULL, 'N'},
      {"tx", required_argument, NULL, 't'},
      {"ty", required_argument, NULL, 'u'},
      {"tz", required_argument, NULL, 'w'},
      {"revert", no_argument, NULL, 'i'},
      {"normalize", no_argument, NULL, 'o'},
      {"help", no_argument, NULL, 'h'},
      {"verbose", no_argument, NULL, 'v'},
      { NULL }
    };
    int option_index = 0;
    switch ((c = getopt_long (argc, argv, "hvr:m:n:s:R:M:N:it:u:w:o",
			      long_options, &option_index))) {
#else /* not HAVE_GETOPT_LONG */
    switch ((c = getopt (argc, argv, "hvr:m:n:s:R:M:N:it:u:w:o"))) {
#endif /* not HAVE_GETOPT_LONG */
    case 'o': /* normalize */
      normalize = TRUE;
      break;
    case 'r': { /* rotate around x-axis */
      gdouble angle, cosa, sina;
      GtsMatrix * rot, * p;
      
      rot = gts_matrix_identity (NULL);
      angle = atof (optarg)*PI/180.;
      cosa = cos (angle);
      sina = sin (angle);
      rot[1][1] = cosa; rot[1][2] = -sina;
      rot[2][1] = sina; rot[2][2] = cosa;
      p = gts_matrix_product (m, rot);
      gts_matrix_destroy (rot);
      gts_matrix_destroy (m);
      m = p;
      break;
    }
    case 'm': { /* rotate around y-axis */
      gdouble angle, cosa, sina;
      GtsMatrix * rot, * p;
      
      rot = gts_matrix_identity (NULL);
      angle = atof (optarg)*PI/180.;
      cosa = cos (angle);
      sina = sin (angle);
      rot[0][0] = cosa; rot[0][2] = sina;
      rot[2][0] = -sina; rot[2][2] = cosa;
      p = gts_matrix_product (m, rot);
      gts_matrix_destroy (rot);
      gts_matrix_destroy (m);
      m = p;
      break;
    }
    case 'n': { /* rotate around z-axis */
      gdouble angle, cosa, sina;
      GtsMatrix * rot, * p;
      
      rot = gts_matrix_identity (NULL);
      angle = atof (optarg)*PI/180.;
      cosa = cos (angle);
      sina = sin (angle);
      rot[0][0] = cosa; rot[0][1] = -sina;
      rot[1][0] = sina; rot[1][1] = cosa;
      p = gts_matrix_product (m, rot);
      gts_matrix_destroy (rot);
      gts_matrix_destroy (m);
      m = p;
      break;
    }
    case 's': { /* scale */
      GtsMatrix * scale, * p;
      gdouble s = atof (optarg);

      scale = gts_matrix_identity (NULL);
      scale[0][0] = scale[1][1] = scale[2][2] = s;
      p = gts_matrix_product (m, scale);
      gts_matrix_destroy (scale);
      gts_matrix_destroy (m);
      m = p;
      break;
    }
    case 'R': { /* sx */
      GtsMatrix * scale, * p;
      gdouble s = atof (optarg);

      scale = gts_matrix_identity (NULL);
      scale[0][0] = s;
      p = gts_matrix_product (m, scale);
      gts_matrix_destroy (scale);
      gts_matrix_destroy (m);
      m = p;
      break;
    }
    case 'M': { /* sy */
      GtsMatrix * scale, * p;
      gdouble s = atof (optarg);

      scale = gts_matrix_identity (NULL);
      scale[1][1] = s;
      p = gts_matrix_product (m, scale);
      gts_matrix_destroy (scale);
      gts_matrix_destroy (m);
      m = p;
      break;
    }
    case 'N': { /* sz */
      GtsMatrix * scale, * p;
      gdouble s = atof (optarg);

      scale = gts_matrix_identity (NULL);
      scale[2][2] = s;
      p = gts_matrix_product (m, scale);
      gts_matrix_destroy (scale);
      gts_matrix_destroy (m);
      m = p;
      break;
    }
    case 't': /* tx */
      m[0][3] += atof (optarg);
      break;
    case 'u': /* ty */
      m[1][3] += atof (optarg);
      break;
    case 'w': /* tz */
      m[2][3] += atof (optarg);
      break;
    case 'i': /* revert */
      revert = TRUE;
      break;
    case 'v': /* verbose */
      verbose = TRUE;
      break;
    case 'h': /* help */
      fprintf (stderr,
             "Usage: transform [OPTION] < file.gts\n"
	     "Apply geometric transformations to the input.\n"
	     "\n"
	     "  -r ANGLE  --rx=ANGLE      rotate around x-axis (angle in degrees)\n"
	     "  -m ANGLE  --ry=ANGLE      rotate around y-axis\n"
	     "  -n ANGLE  --rz=ANGLE      rotate around z-axis\n"
	     "  -s FACTOR --scale=FACTOR  scale by FACTOR\n"
	     "  -R FACTOR --sx=FACTOR     scale x-axis by FACTOR\n"
	     "  -M FACTOR --sy=FACTOR     scale y-axis by FACTOR\n"
	     "  -N FACTOR --sz=FACTOR     scale z-axis by FACTOR\n"
             "  -t V      --tx=V          translate of V along x-axis\n"
             "  -u V      --ty=V          translate of V along y-axis\n"
             "  -w V      --tz=V          translate of V along z-axis\n"
	     "  -i        --revert        turn surface inside out\n"
             "  -o        --normalize     fit the resulting surface in a cube of\n"
	     "                            size 1 centered at the origin\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 `transform --help' for more information.\n");
      return 1; /* failure */
    }
  }

  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 ("transform: 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);

  if (revert)
    gts_surface_foreach_face (s, (GtsFunc) gts_triangle_revert, NULL);
  gts_surface_foreach_vertex (s, (GtsFunc) gts_point_transform, m);
  if (normalize) {
    GtsBBox * bb = gts_bbox_surface (gts_bbox_class (), s);
    gdouble scale = bb->x2 - bb->x1;
    GtsMatrix * sc;

    if (bb->y2 - bb->y1 > scale) scale = bb->y2 - bb->y1;
    if (bb->z2 - bb->z1 > scale) scale = bb->z2 - bb->z1;
    if (scale > 0.) scale = 1./scale;
    else scale = 1.;
    sc = gts_matrix_identity (NULL);
    sc[0][3] = - (bb->x1 + bb->x2)/2.;
    sc[1][3] = - (bb->y1 + bb->y2)/2.;
    sc[2][3] = - (bb->z1 + bb->z2)/2.;
    gts_surface_foreach_vertex (s, (GtsFunc) gts_point_transform, sc);
    sc[0][0] = sc[1][1] = sc[2][2] = scale;    
    sc[0][3] = sc[1][3] = sc[2][3] = 0.;
    gts_surface_foreach_vertex (s, (GtsFunc) gts_point_transform, sc);
    gts_matrix_destroy (sc);
  }
  gts_surface_write (s, stdout);

  return 0;
}
Esempio n. 4
0
static void prepend_triangle_bbox (GtsTriangle * t, GSList ** bboxes)
{
  *bboxes = g_slist_prepend (*bboxes, 
			     gts_bbox_triangle (gts_bbox_class (), t));
}
Esempio n. 5
0
/**
 * gts_bb_tree_new:
 * @bboxes: a list of #GtsBBox.
 *
 * Builds a new hierarchy of bounding boxes for @bboxes. At each
 * level, the GNode->data field contains a #GtsBBox bounding box of
 * all the children. The tree is binary and is built by repeatedly
 * cutting in two approximately equal halves the bounding boxes at
 * each level until a leaf node (i.e. a bounding box given in @bboxes)
 * is reached. In order to minimize the depth of the tree, the cutting
 * direction is always chosen as perpendicular to the longest
 * dimension of the bounding box.
 *
 * Returns: a new hierarchy of bounding boxes.  
 */
GNode * gts_bb_tree_new (GSList * bboxes)
{
  GSList * i, * positive = NULL, * negative = NULL;
  GNode * node;
  GtsBBox * bbox;
  guint dir, np = 0, nn = 0;
  gdouble * p1, * p2;
  gdouble cut;
  
  g_return_val_if_fail (bboxes != NULL, NULL);

  if (bboxes->next == NULL) /* leaf node */
    return g_node_new (bboxes->data);

  bbox = gts_bbox_bboxes (gts_bbox_class (), bboxes);
  node = g_node_new (bbox);

  if (bbox->x2 - bbox->x1 > bbox->y2 - bbox->y1) {
    if (bbox->z2 - bbox->z1 > bbox->x2 - bbox->x1)
      dir = 2;
    else
      dir = 0;
  }
  else if (bbox->z2 - bbox->z1 > bbox->y2 - bbox->y1)
    dir = 2;
  else
    dir = 1;

  p1 = (gdouble *) &bbox->x1;
  p2 = (gdouble *) &bbox->x2;
  cut = (p1[dir] + p2[dir])/2.;
  i = bboxes;
  while (i) {
    bbox = i->data; 
    p1 = (gdouble *) &bbox->x1;
    p2 = (gdouble *) &bbox->x2;
    if ((p1[dir] + p2[dir])/2. > cut) {
      positive = g_slist_prepend (positive, bbox);
      np++;
    }
    else {
      negative = g_slist_prepend (negative, bbox);
      nn++;
    }
    i = i->next;
  }
  if (!positive) {
    GSList * last = g_slist_nth (negative, (nn - 1)/2);
    positive = last->next;
    last->next = NULL;
  }
  else if (!negative) {
    GSList * last = g_slist_nth (positive, (np - 1)/2);
    negative = last->next;
    last->next = NULL;
  }
  g_node_prepend (node, gts_bb_tree_new (positive));
  g_slist_free (positive);
  g_node_prepend (node, gts_bb_tree_new (negative));
  g_slist_free (negative);
  
  return node;
}