示例#1
0
文件: edge.c 项目: MicBosi/GTS
/**
 * gts_edge_belongs_to_tetrahedron:
 * @e: a #GtsEdge.
 *
 * Returns: %TRUE if @e is used by faces forming a tetrahedron, %FALSE
 * otherwise.
 */
gboolean gts_edge_belongs_to_tetrahedron (GtsEdge * e)
{
    GSList * i;
    GtsVertex * v1, * v2;

    g_return_val_if_fail (e != NULL, FALSE);

    v1 = GTS_SEGMENT (e)->v1;
    v2 = GTS_SEGMENT (e)->v2;
    i = e->triangles;
    while (i) {
        GtsEdge * e1, * e2;
        GtsVertex * vt1;
        GSList * j = i->next;
        triangle_vertices_edges (i->data, e, &vt1, &e1, &e2);
        while (j) {
            GtsSegment * s5;
            GtsEdge * e3, * e4;
            GtsVertex * vt2;

            triangle_vertices_edges (j->data, e, &vt2, &e3, &e4);
            s5 = gts_vertices_are_connected (vt1, vt2);
            if (GTS_IS_EDGE (s5) &&
                    gts_triangle_use_edges (e1, e3, GTS_EDGE (s5)) &&
                    gts_triangle_use_edges (e2, e4, GTS_EDGE (s5)))
                return TRUE;
            j = j->next;
        }
        i = i->next;
    }

    return FALSE;
}
示例#2
0
文件: edge.c 项目: MicBosi/GTS
/**
 * gts_edge_is_duplicate:
 * @e: a #GtsEdge.
 *
 * Returns: the first #GtsEdge different from @e which shares the
 * same endpoints or %NULL if there is none.
 */
GtsEdge * gts_edge_is_duplicate (GtsEdge * e)
{
    GSList * i;
    GtsVertex * v2;

    g_return_val_if_fail (e != NULL, NULL);

    v2 = GTS_SEGMENT (e)->v2;
    i = GTS_SEGMENT (e)->v1->segments;
    if (GTS_SEGMENT (e)->v1 == v2) /* e is degenerate: special treatment */
        while (i) {
            GtsSegment * s = i->data;
            if (s != GTS_SEGMENT (e) &&
                    GTS_IS_EDGE (s) &&
                    s->v1 == v2 && s->v2 == v2)
                return GTS_EDGE (s);
            i = i->next;
        }
    else /* e is not degenerate */
        while (i) {
            GtsSegment * s = i->data;
            if (s != GTS_SEGMENT (e) &&
                    GTS_IS_EDGE (s) &&
                    (s->v1 == v2 || s->v2 == v2))
                return GTS_EDGE (s);
            i = i->next;
        }
    return NULL;
}
示例#3
0
文件: edge.c 项目: MicBosi/GTS
/**
 * gts_edge_swap:
 * @e: a #GtsEdge.
 * @s: a #GtsSurface.
 *
 * Performs an "edge swap" on the two triangles sharing @e and
 * belonging to @s.
 */
void gts_edge_swap (GtsEdge * e, GtsSurface * s)
{
    GtsTriangle * t1 = NULL, * t2 = NULL, * t;
    GtsFace * f;
    GSList * i;
    GtsVertex * v1, * v2, * v3, * v4, * v5, * v6;
    GtsEdge * e1, * e2, * e3, * e4;
    GtsSegment * v3v6;

    g_return_if_fail (e != NULL);
    g_return_if_fail (s != NULL);

    i = e->triangles;
    while (i) {
        if (GTS_IS_FACE (i->data) && gts_face_has_parent_surface (i->data, s)) {
            if (!t1)
                t1 = i->data;
            else if (!t2)
                t2 = i->data;
            else
                g_return_if_fail (gts_edge_face_number (e, s) == 2);
        }
        i = i->next;
    }
    g_assert (t1 && t2);

    gts_triangle_vertices_edges (t1, e, &v1, &v2, &v3, &e, &e1, &e2);
    gts_triangle_vertices_edges (t2, e, &v4, &v5, &v6, &e, &e3, &e4);
    g_assert (v2 == v4 && v1 == v5);

    v3v6 = gts_vertices_are_connected (v3, v6);
    if (!GTS_IS_EDGE (v3v6))
        v3v6 = GTS_SEGMENT (gts_edge_new (s->edge_class, v3, v6));
    f = gts_face_new (s->face_class, e1, GTS_EDGE (v3v6), e4);
    if ((t = gts_triangle_is_duplicate (GTS_TRIANGLE (f))) &&
            GTS_IS_FACE (t)) {
        gts_object_destroy (GTS_OBJECT (f));
        f = GTS_FACE (t);
    }
    gts_surface_add_face (s, f);

    f = gts_face_new (s->face_class, GTS_EDGE (v3v6), e2, e3);
    if ((t = gts_triangle_is_duplicate (GTS_TRIANGLE (f))) &&
            GTS_IS_FACE (t)) {
        gts_object_destroy (GTS_OBJECT (f));
        f = GTS_FACE (t);
    }
    gts_surface_add_face (s, f);

    gts_surface_remove_face (s, GTS_FACE (t1));
    gts_surface_remove_face (s, GTS_FACE (t2));
}
示例#4
0
文件: cartesian.c 项目: ClavinSBU/gts
static GtsEdge * new_edge (GtsVertex * v1, GtsVertex * v2)
{
  GtsSegment * s = gts_vertices_are_connected (v1, v2);
  return s == NULL ? 
    gts_edge_new (GTS_EDGE_CLASS (gts_constraint_class ()), v1, v2) :
    GTS_EDGE (s);
}
示例#5
0
文件: edge.c 项目: MicBosi/GTS
static void edge_clone (GtsObject * clone, GtsObject * object)
{
    (* GTS_OBJECT_CLASS (gts_edge_class ())->parent_class->clone) (clone,
            object);
    GTS_SEGMENT (clone)->v1 = GTS_SEGMENT (clone)->v2 = NULL;
    GTS_EDGE (clone)->triangles = NULL;
}
示例#6
0
文件: edge.c 项目: MicBosi/GTS
/**
 * gts_edges_from_vertices:
 * @vertices: a list of #GtsVertex.
 * @parent: a #GtsSurface.
 *
 * Returns: a list of unique #GtsEdge which have one of their vertices in
 * @vertices and are used by a face of @parent.
 */
GSList * gts_edges_from_vertices (GSList * vertices, GtsSurface * parent)
{
    GHashTable * hash;
    GSList * edges = NULL, * i;

    g_return_val_if_fail (parent != NULL, NULL);

    hash = g_hash_table_new (NULL, NULL);
    i = vertices;
    while (i) {
        GSList * j = GTS_VERTEX (i->data)->segments;
        while (j) {
            GtsSegment * s = j->data;
            if (GTS_IS_EDGE (s) &&
                    gts_edge_has_parent_surface (GTS_EDGE (s), parent) &&
                    g_hash_table_lookup (hash, s) == NULL) {
                edges = g_slist_prepend (edges, s);
                g_hash_table_insert (hash, s, i);
            }
            j = j->next;
        }
        i = i->next;
    }
    g_hash_table_destroy (hash);
    return edges;
}
示例#7
0
文件: edge.c 项目: MicBosi/GTS
static void edge_destroy (GtsObject * object)
{
    GtsEdge * edge = GTS_EDGE (object);
    GSList * i;

    i = edge->triangles;
    while (i) {
        GSList * next = i->next;
        gts_object_destroy (i->data);
        i = next;
    }
    g_assert (edge->triangles == NULL);

    (* GTS_OBJECT_CLASS (gts_edge_class ())->parent_class->destroy) (object);
}
示例#8
0
文件: triangle.c 项目: finetjul/gts
/**
 * gts_triangles_from_edges:
 * @edges: a list of #GtsEdge.
 *
 * Builds a list of unique triangles which have one of their edges in @edges.
 *
 * Returns: the list of triangles.
 */
GSList * gts_triangles_from_edges (GSList * edges)
{
    GHashTable * hash;
    GSList * triangles = NULL, * i;

    hash = g_hash_table_new (NULL, NULL);
    i = edges;
    while (i) {
        GSList * j = GTS_EDGE (i->data)->triangles;
        while (j) {
            GtsTriangle * t = j->data;
            if (g_hash_table_lookup (hash, t) == NULL) {
                triangles = g_slist_prepend (triangles, t);
                g_hash_table_insert (hash, t, i);
            }
            j = j->next;
        }
        i = i->next;
    }
    g_hash_table_destroy (hash);

    return triangles;
}
示例#9
0
文件: delaunay.c 项目: Gilles86/afni
static void gts_constraint_split (GtsConstraint * c, 
				  GtsSurface * s,
				  GtsFifo * fifo)
{
  GSList * i;
  GtsVertex * v1, * v2;
  GtsEdge * e;

  g_return_if_fail (c != NULL);
  g_return_if_fail (s != NULL);

  v1 = GTS_SEGMENT (c)->v1;
  v2 = GTS_SEGMENT (c)->v2;
  e = GTS_EDGE (c);

  i = e->triangles;
  while (i) {
    GtsFace * f = i->data;
    if (GTS_IS_FACE (f) && gts_face_has_parent_surface (f, s)) {
      GtsVertex * v = gts_triangle_vertex_opposite (GTS_TRIANGLE (f), e);
      if (gts_point_orientation (GTS_POINT (v1), 
				 GTS_POINT (v2), 
				 GTS_POINT (v)) == 0.) {
	GSList * j = e->triangles;
	GtsFace * f1 = NULL;
	GtsEdge * e1, * e2;

	/* replaces edges with constraints */
	gts_triangle_vertices_edges (GTS_TRIANGLE (f), e,
				     &v1, &v2, &v, &e, &e1, &e2);
	if (!GTS_IS_CONSTRAINT (e1)) {
	  GtsEdge * ne1 = 
	    gts_edge_new (GTS_EDGE_CLASS (GTS_OBJECT (c)->klass), v2, v);
	  gts_edge_replace (e1, ne1);
	  gts_object_destroy (GTS_OBJECT (e1));
	  e1 = ne1;
	  if (fifo) gts_fifo_push (fifo, e1);
	}
	if (!GTS_IS_CONSTRAINT (e2)) {
	  GtsEdge * ne2 = 
	    gts_edge_new (GTS_EDGE_CLASS (GTS_OBJECT (c)->klass), v, v1);
	  gts_edge_replace (e2, ne2);
	  gts_object_destroy (GTS_OBJECT (e2));
	  e2 = ne2;
	  if (fifo) gts_fifo_push (fifo, e2);
	}

	/* look for face opposite */
	while (j && !f1) {
	  if (GTS_IS_FACE (j->data) && 
	      gts_face_has_parent_surface (j->data, s))
	    f1 = j->data;
	  j = j->next;
	}
	if (f1) { /* c is not a boundary of s */
	  GtsEdge * e3, * e4, * e5;
	  GtsVertex * v3;
	  gts_triangle_vertices_edges (GTS_TRIANGLE (f1), e,
				       &v1, &v2, &v3, &e, &e3, &e4);
	  e5 = gts_edge_new (s->edge_class, v, v3);
	  gts_surface_add_face (s, gts_face_new (s->face_class, e5, e2, e3));
	  gts_surface_add_face (s, gts_face_new (s->face_class, e5, e4, e1));
	  gts_object_destroy (GTS_OBJECT (f1));
	}
	gts_object_destroy (GTS_OBJECT (f));
	return;
      }
    }
    i = i->next;
  }
}
示例#10
0
文件: edge.c 项目: MicBosi/GTS
/**
 * gts_edge_new:
 * @klass: a #GtsEdgeClass.
 * @v1: a #GtsVertex.
 * @v2: a #GtsVertex.
 *
 * Returns: a new #GtsEdge linking @v1 and @v2.
 */
GtsEdge * gts_edge_new (GtsEdgeClass * klass,
                        GtsVertex * v1, GtsVertex * v2)
{
    return GTS_EDGE (gts_segment_new (GTS_SEGMENT_CLASS (klass), v1, v2));
}