Beispiel #1
0
bool ofxGtsSurface::prepareBoolean(ofxGtsSurface &source) {
	if(!loaded || !source.loaded) {
		ofLog(OF_LOG_NOTICE, "Gts surface not loaded, could not perform boolean operation");
		return false;
	}
	
	if(!gts_surface_is_orientable(surface)) {
		ofLog(OF_LOG_ERROR, "Gts surface is not an orientable manifold, could not perform boolean operation");
		return false;
	}
	
	if(gts_surface_is_self_intersecting(surface)) {
		ofLog(OF_LOG_ERROR, "Gts surface self-intersects, could not perform boolean operation");
		return false;
	}
	
	if(!gts_surface_is_orientable(source.surface)) {
		ofLog(OF_LOG_ERROR, "Gts surface is not an orientable manifold, could not perform boolean operation");
		return false;
	}
	
	if(gts_surface_is_self_intersecting(source.surface)) {
		ofLog(OF_LOG_ERROR, "Gts surface self-intersects, could not perform boolean operation");
		return false;
	}
	
	GSList *bboxes = NULL;
	gts_surface_foreach_face(surface, (GtsFunc) prepend_triangle_bbox, &bboxes);
	/* build bounding box tree for first surface */
	tree1 = gts_bb_tree_new(bboxes);
	/* free list of bboxes */
	g_slist_free (bboxes);
	is_open1 = gts_surface_volume(surface) < 0. ? TRUE : FALSE;
	
	/* build bounding boxes for second surface */
	bboxes = NULL;
	gts_surface_foreach_face(source.surface, (GtsFunc) prepend_triangle_bbox, &bboxes);
	/* build bounding box tree for second surface */
	tree2 = gts_bb_tree_new(bboxes);
	/* free list of bboxes */
	g_slist_free (bboxes);
	is_open2 = gts_surface_volume (source.surface) < 0. ? TRUE : FALSE;
	
	si = gts_surface_inter_new (gts_surface_inter_class (), 
								surface, source.surface, tree1, tree2, is_open1, is_open2);
	
	gboolean closed = TRUE;
	gts_surface_inter_check(si, &closed);
	boolPerformed = true;
	if(!closed) {
		ofLog(OF_LOG_NOTICE, "Gts surface is not closed, could not perform boolean operation");
		return false;
	}

	return true;
}
Beispiel #2
0
/**
 * gts_bb_tree_surface:
 * @s: a #GtsSurface.
 *
 * Returns: a new hierarchy of bounding boxes bounding the faces of @s.
 */
GNode * gts_bb_tree_surface (GtsSurface * s)
{
  GSList * bboxes = NULL;
  GNode * tree;

  g_return_val_if_fail (s != NULL, NULL);

  gts_surface_foreach_face (s, (GtsFunc) prepend_triangle_bbox, &bboxes);
  tree = gts_bb_tree_new (bboxes);
  g_slist_free (bboxes);

  return tree;
}
Beispiel #3
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;
}