1 /* GTS - Library for the manipulation of triangulated surfaces
2 * Copyright (C) 1999 Stéphane Popinet
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
22 gboolean gts_allow_floating_faces
= FALSE
;
24 static void face_destroy (GtsObject
* object
)
26 GtsFace
* face
= GTS_FACE (object
);
31 GSList
* next
= i
->next
;
32 gts_surface_remove_face (i
->data
, face
);
35 g_assert (face
->surfaces
== NULL
);
37 (* GTS_OBJECT_CLASS (gts_face_class ())->parent_class
->destroy
) (object
);
40 static void face_clone (GtsObject
* clone
, GtsObject
* object
)
42 (* GTS_OBJECT_CLASS (gts_face_class ())->parent_class
->clone
) (clone
,
44 GTS_FACE (clone
)->surfaces
= NULL
;
47 static void face_class_init (GtsFaceClass
* klass
)
49 GTS_OBJECT_CLASS (klass
)->clone
= face_clone
;
50 GTS_OBJECT_CLASS (klass
)->destroy
= face_destroy
;
53 static void face_init (GtsFace
* face
)
55 face
->surfaces
= NULL
;
61 * Returns: the #GtsFaceClass.
63 GtsFaceClass
* gts_face_class (void)
65 static GtsFaceClass
* klass
= NULL
;
68 GtsObjectClassInfo face_info
= {
71 sizeof (GtsFaceClass
),
72 (GtsObjectClassInitFunc
) face_class_init
,
73 (GtsObjectInitFunc
) face_init
,
77 klass
= gts_object_class_new (GTS_OBJECT_CLASS (gts_triangle_class ()),
86 * @klass: a #GtsFaceClass.
91 * Returns: a new #GtsFace using @e1, @e2 and @e3 as edges.
93 GtsFace
* gts_face_new (GtsFaceClass
* klass
,
94 GtsEdge
* e1
, GtsEdge
* e2
, GtsEdge
* e3
)
98 f
= GTS_FACE (gts_object_new (GTS_OBJECT_CLASS (klass
)));
99 gts_triangle_set (GTS_TRIANGLE (f
), e1
, e2
, e3
);
105 * gts_face_has_parent_surface:
109 * Returns: %TRUE if @f belongs to @s, %FALSE otherwise.
111 gboolean
gts_face_has_parent_surface (GtsFace
* f
, GtsSurface
* s
)
115 g_return_val_if_fail (f
!= NULL
, FALSE
);
127 * gts_faces_from_edges:
128 * @edges: a list of #GtsEdge.
129 * @s: a #GtsSurface or %NULL.
131 * Builds a list of unique faces which belong to @s and have
132 * one of their edges in @edges.
134 * Returns: the list of faces.
136 GSList
* gts_faces_from_edges (GSList
* edges
, GtsSurface
* s
)
139 GSList
* faces
= NULL
, * i
;
141 hash
= g_hash_table_new (NULL
, NULL
);
144 GSList
* j
= GTS_EDGE (i
->data
)->triangles
;
146 GtsTriangle
* t
= j
->data
;
147 if (GTS_IS_FACE (t
) &&
148 (!s
|| gts_face_has_parent_surface (GTS_FACE (t
), s
)) &&
149 g_hash_table_lookup (hash
, t
) == NULL
) {
150 faces
= g_slist_prepend (faces
, t
);
151 g_hash_table_insert (hash
, t
, i
);
157 g_hash_table_destroy (hash
);
163 * gts_face_neighbor_number:
165 * @s: a #GtsSurface or %NULL.
167 * Returns: the number of faces neighbors of @f and belonging to @s.
169 guint
gts_face_neighbor_number (GtsFace
* f
, GtsSurface
* s
)
173 GtsEdge
* e
[4], ** e1
= e
;
175 g_return_val_if_fail (f
!= NULL
, 0);
177 e
[0] = GTS_TRIANGLE (f
)->e1
;
178 e
[1] = GTS_TRIANGLE (f
)->e2
;
179 e
[2] = GTS_TRIANGLE (f
)->e3
;
182 i
= (*e1
++)->triangles
;
184 GtsTriangle
* t
= i
->data
;
185 if (GTS_FACE (t
) != f
&&
187 (!s
|| gts_face_has_parent_surface (GTS_FACE (t
), s
)))
197 * gts_face_neighbors:
199 * @s: a #GtsSurface or %NULL.
201 * Returns: a list of unique #GtsFace neighbors of @f and belonging to @s.
203 GSList
* gts_face_neighbors (GtsFace
* f
, GtsSurface
* s
)
205 GSList
* i
, * list
= NULL
;
206 GtsEdge
* e
[4], ** e1
= e
;
208 g_return_val_if_fail (f
!= NULL
, NULL
);
210 e
[0] = GTS_TRIANGLE (f
)->e1
;
211 e
[1] = GTS_TRIANGLE (f
)->e2
;
212 e
[2] = GTS_TRIANGLE (f
)->e3
;
215 i
= (*e1
++)->triangles
;
217 GtsTriangle
* t
= i
->data
;
218 if (GTS_FACE (t
) != f
&&
220 (!s
|| gts_face_has_parent_surface (GTS_FACE (t
), s
)))
221 list
= g_slist_prepend (list
, t
);
230 * gts_face_foreach_neighbor:
232 * @s: a #GtsSurface or %NULL.
234 * @data: user data to pass to @func.
236 * Calls @func for each neighbor of @f belonging to @s (if not %NULL).
238 void gts_face_foreach_neighbor (GtsFace
* f
,
244 GtsEdge
* e
[4], ** e1
= e
;
246 g_return_if_fail (f
!= NULL
);
247 g_return_if_fail (func
!= NULL
);
249 e
[0] = GTS_TRIANGLE (f
)->e1
;
250 e
[1] = GTS_TRIANGLE (f
)->e2
;
251 e
[2] = GTS_TRIANGLE (f
)->e3
;
254 i
= (*e1
++)->triangles
;
256 GtsTriangle
* t
= i
->data
;
257 if (GTS_FACE (t
) != f
&&
259 (!s
|| gts_face_has_parent_surface (GTS_FACE (t
), s
)))
266 static gboolean
triangle_is_incompatible (GtsTriangle
* t
, GtsEdge
* e
, GtsSurface
* s
)
268 GSList
* i
= e
->triangles
;
272 GTS_IS_FACE (i
->data
) &&
273 gts_face_has_parent_surface (i
->data
, s
) &&
274 !gts_triangles_are_compatible (t
, i
->data
, e
))
282 * gts_face_is_compatible:
286 * Returns: %TRUE if @f is compatible with all its neighbors belonging
287 * to @s, %FALSE otherwise.
289 gboolean
gts_face_is_compatible (GtsFace
* f
, GtsSurface
* s
)
291 g_return_val_if_fail (f
!= NULL
, FALSE
);
292 g_return_val_if_fail (s
!= NULL
, FALSE
);
294 return !(triangle_is_incompatible (GTS_TRIANGLE (f
), GTS_TRIANGLE (f
)->e1
, s
) ||
295 triangle_is_incompatible (GTS_TRIANGLE (f
), GTS_TRIANGLE (f
)->e2
, s
) ||
296 triangle_is_incompatible (GTS_TRIANGLE (f
), GTS_TRIANGLE (f
)->e3
, s
));