pygel3d

PyGEL is a collection of classes and functions that expose features in the GEL library. The primary purpose of PyGEL (and GEL) is to be useful for geometry processing tasks. Especially tasks that involve 3D polygonal meshes, but there is also a graph component useful e.g. for skeletonization. The PyGEL package is called pygel3d and it contains five modules:

hmesh provides Manifold which is a class that represents polygonal meshes using the halfedge representation. hmesh also provides a slew of functions for manipulating polygonal meshes and the MeshDistance class which makes it simple to compute the distance to a triangle mesh.

graph contains the Graph class which is used for graphs: i.e. collections of vertices (in 3D) connected by edges. Unlike a Manifold, a Graph does not have to represent a surface. There are also some associated functions which may be useful: in particular, there is the LS_skeletonize function which computes a curve skeleton from a Graph and returns the result as a new Graph.

gl_display provides the Viewer class which makes it simple to visualize meshes and graphs.

jupyter_display makes it easy to use PyGEL in the context of a Jupyter Notebook. This module contains a function that allows you to create a widget for interactively visualizing a mesh or a graph in a Notebook. The feature is based on the Plotly library and it is possible to export the resulting notebooks to HTML while preserving the interactive 3D graphics in the notebook.

spatial contains the I3DTree class which is simply a kD-tree specialized for mapping 3D points to integers - typically indices. Of course, scipy.spatial has a more generic class, so this is perhaps not the most important part of PyGEL.

  1""" PyGEL is a collection of classes and functions that expose features in the
  2GEL library. The primary purpose of PyGEL (and GEL) is to be useful for geometry
  3processing tasks. Especially tasks that involve 3D polygonal meshes, but there is
  4also a graph component useful e.g. for skeletonization. The PyGEL package is called
  5pygel3d and it contains five modules:
  6
  7hmesh provides Manifold which is a class that represents polygonal meshes using the
  8halfedge representation. hmesh also provides a slew of functions for manipulating
  9polygonal meshes and the MeshDistance class which makes it simple to compute the
 10distance to a triangle mesh.
 11
 12graph contains the Graph class which is used for graphs: i.e. collections of
 13vertices (in 3D) connected by edges. Unlike a Manifold, a Graph does not have to
 14represent a surface. There are also some associated functions which may be useful:
 15in particular, there is the LS_skeletonize function which computes a curve skeleton
 16from a Graph and returns the result as a new Graph.
 17
 18gl_display provides the Viewer class which makes it simple to visualize meshes and
 19graphs.
 20
 21jupyter_display makes it easy to use PyGEL in the context of a Jupyter Notebook.
 22This module contains a function that allows you to create a widget for interactively
 23visualizing a mesh or a graph in a Notebook. The feature is based on the Plotly
 24library and it is possible to export the resulting notebooks to HTML while preserving
 25the interactive 3D graphics in the notebook.
 26
 27spatial contains the I3DTree class which is simply a kD-tree specialized for mapping
 283D points to integers - typically indices. Of course, scipy.spatial has a more
 29generic class, so this is perhaps not the most important part of PyGEL.
 30"""
 31__all__ = ["hmesh", "graph", "gl_display", "jupyter_display", "spatial"]
 32
 33import os
 34from sys import platform, prefix
 35import ctypes as ct
 36import numpy as np
 37from numpy.ctypeslib import ndpointer
 38
 39def _get_script_path():
 40    return os.path.dirname(__file__)
 41
 42def _get_lib_name():
 43    if platform == "darwin":
 44        return "libPyGEL.dylib"
 45    if platform == "win32":
 46        return "PyGEL.dll"
 47    return "libPyGEL.so"
 48
 49# Load PyGEL the Python GEL bridge library
 50lib_py_gel = ct.cdll.LoadLibrary(_get_script_path() + "/" + _get_lib_name())
 51
 52# An InvalidIndex is just a special integer value.
 53InvalidIndex = ct.c_size_t.in_dll(lib_py_gel, "InvalidIndex").value
 54
 55# The following many lines explitize the arguments and return types of the C API
 56
 57# IntVector
 58lib_py_gel.IntVector_new.restype = ct.c_void_p
 59lib_py_gel.IntVector_get.argtypes = (ct.c_void_p, ct.c_size_t)
 60lib_py_gel.IntVector_size.argtypes = (ct.c_void_p,)
 61lib_py_gel.IntVector_size.restype = ct.c_size_t
 62lib_py_gel.IntVector_delete.argtypes = (ct.c_void_p,)
 63
 64
 65# Vec3dVector
 66lib_py_gel.Vec3dVector_new.restype = ct.c_void_p
 67lib_py_gel.Vec3dVector_get.argtypes = (ct.c_void_p, ct.c_size_t)
 68lib_py_gel.Vec3dVector_get.restype = ct.POINTER(ct.c_double)
 69lib_py_gel.Vec3dVector_size.argtypes = (ct.c_void_p,)
 70lib_py_gel.Vec3dVector_size.restype = ct.c_size_t
 71lib_py_gel.Vec3dVector_delete.argtypes = (ct.c_void_p,)
 72
 73# I3DTree
 74lib_py_gel.I3DTree_new.restype = ct.c_void_p
 75lib_py_gel.I3DTree_delete.argtypes = (ct.c_void_p,)
 76lib_py_gel.I3DTree_insert.argtypes = (ct.c_void_p, ct.c_double, ct.c_double, ct.c_double, ct.c_size_t)
 77lib_py_gel.I3DTree_build.argtypes = (ct.c_void_p,)
 78lib_py_gel.I3DTree_closest_point.argtypes = (ct.c_void_p, ct.c_double, ct.c_double, ct.c_double, ct.c_double, ct.POINTER(ct.c_double*3), ct.POINTER(ct.c_size_t))
 79lib_py_gel.I3DTree_in_sphere.argtypes = (ct.c_void_p, ct.c_double, ct.c_double, ct.c_double, ct.c_double, ct.c_void_p,ct.c_void_p)
 80
 81# Manifold class
 82lib_py_gel.Manifold_from_triangles.argtypes = (ct.c_size_t,ct.c_size_t, ndpointer(np.float64, ndim=2, flags='C'), ndpointer(ct.c_int, ndim=2, flags='C'))
 83lib_py_gel.Manifold_from_triangles.restype = ct.c_void_p
 84lib_py_gel.Manifold_from_points.argtypes = (ct.c_size_t,ndpointer(np.float64, ndim=2, flags='C'), ndpointer(np.float64, shape=3),ndpointer(np.float64, shape=3))
 85lib_py_gel.Manifold_from_points.restype = ct.c_void_p
 86lib_py_gel.Manifold_new.restype = ct.c_void_p
 87lib_py_gel.Manifold_copy.restype = ct.c_void_p
 88lib_py_gel.Manifold_copy.argtypes = (ct.c_void_p,)
 89lib_py_gel.Manifold_merge.argtypes = (ct.c_void_p,ct.c_void_p)
 90lib_py_gel.Manifold_delete.argtypes = (ct.c_void_p,)
 91lib_py_gel.Manifold_positions.restype = ct.c_size_t
 92lib_py_gel.Manifold_positions.argtypes = (ct.c_void_p, ct.POINTER(ct.POINTER(ct.c_double)))
 93lib_py_gel.Manifold_no_allocated_vertices.restype = ct.c_size_t
 94lib_py_gel.Manifold_no_allocated_vertices.argtypes = (ct.c_void_p,)
 95lib_py_gel.Manifold_no_allocated_faces.restype = ct.c_size_t
 96lib_py_gel.Manifold_no_allocated_faces.argtypes = (ct.c_void_p,)
 97lib_py_gel.Manifold_no_allocated_halfedges.restype = ct.c_size_t
 98lib_py_gel.Manifold_no_allocated_halfedges.argtypes = (ct.c_void_p,)
 99lib_py_gel.Manifold_vertices.restype = ct.c_size_t
100lib_py_gel.Manifold_vertices.argtypes = (ct.c_void_p, ct.c_void_p)
101lib_py_gel.Manifold_faces.restype = ct.c_size_t
102lib_py_gel.Manifold_faces.argtypes = (ct.c_void_p, ct.c_void_p)
103lib_py_gel.Manifold_halfedges.restype = ct.c_size_t
104lib_py_gel.Manifold_halfedges.argtypes = (ct.c_void_p,ct.c_void_p)
105lib_py_gel.Manifold_circulate_vertex.restype = ct.c_size_t
106lib_py_gel.Manifold_circulate_vertex.argtypes = (ct.c_void_p, ct.c_size_t, ct.c_char, ct.c_void_p)
107lib_py_gel.Manifold_circulate_face.restype = ct.c_size_t
108lib_py_gel.Manifold_circulate_face.argtypes = (ct.c_void_p, ct.c_size_t, ct.c_char, ct.c_void_p)
109lib_py_gel.Manifold_add_face.argtypes = (ct.c_void_p, ct.c_size_t, ndpointer(np.float64, ndim=2, flags='C'))
110lib_py_gel.Manifold_remove_face.restype = ct.c_bool
111lib_py_gel.Manifold_remove_face.argtypes = (ct.c_void_p, ct.c_size_t)
112lib_py_gel.Manifold_remove_edge.restype = ct.c_bool
113lib_py_gel.Manifold_remove_edge.argtypes = (ct.c_void_p, ct.c_size_t)
114lib_py_gel.Manifold_remove_vertex.restype = ct.c_bool
115lib_py_gel.Manifold_remove_vertex.argtypes = (ct.c_void_p, ct.c_size_t)
116lib_py_gel.Manifold_vertex_in_use.restype = ct.c_bool
117lib_py_gel.Manifold_vertex_in_use.argtypes = (ct.c_void_p,ct.c_size_t)
118lib_py_gel.Manifold_face_in_use.restype = ct.c_bool
119lib_py_gel.Manifold_face_in_use.argtypes = (ct.c_void_p, ct.c_size_t)
120lib_py_gel.Manifold_halfedge_in_use.restype = ct.c_bool
121lib_py_gel.Manifold_halfedge_in_use.argtypes = (ct.c_void_p, ct.c_size_t)
122lib_py_gel.Manifold_flip_edge.restype =  ct.c_bool
123lib_py_gel.Manifold_flip_edge.argtypes = (ct.c_void_p, ct.c_size_t)
124lib_py_gel.Manifold_collapse_edge.restype = ct.c_bool
125lib_py_gel.Manifold_collapse_edge.argtypes = (ct.c_void_p,ct.c_size_t,ct.c_bool)
126lib_py_gel.Manifold_split_face_by_edge.restype = ct.c_size_t
127lib_py_gel.Manifold_split_face_by_edge.argtypes = (ct.c_void_p, ct.c_size_t,ct.c_size_t,ct.c_size_t)
128lib_py_gel.Manifold_split_face_by_vertex.restype = ct.c_size_t
129lib_py_gel.Manifold_split_face_by_vertex.argtypes = (ct.c_void_p, ct.c_size_t)
130lib_py_gel.Manifold_split_edge.restype = ct.c_size_t
131lib_py_gel.Manifold_split_edge.argtypes = (ct.c_void_p, ct.c_size_t)
132lib_py_gel.Manifold_stitch_boundary_edges.restype = ct.c_bool
133lib_py_gel.Manifold_stitch_boundary_edges.argtypes = (ct.c_void_p, ct.c_size_t,ct.c_size_t)
134lib_py_gel.Manifold_merge_faces.restype = ct.c_bool
135lib_py_gel.Manifold_merge_faces.argtypes = (ct.c_void_p, ct.c_size_t,ct.c_size_t)
136lib_py_gel.Manifold_close_hole.argtypes = (ct.c_void_p,ct.c_size_t)
137lib_py_gel.Manifold_cleanup.argtypes = (ct.c_void_p,)
138
139
140# Walker is a helper class assisting us in navigating a mesh.
141# Not directly expose in PyGEL3D
142lib_py_gel.Walker_next_halfedge.restype = ct.c_size_t
143lib_py_gel.Walker_next_halfedge.argtypes = (ct.c_void_p, ct.c_size_t)
144lib_py_gel.Walker_prev_halfedge.restype = ct.c_size_t
145lib_py_gel.Walker_prev_halfedge.argtypes = (ct.c_void_p, ct.c_size_t)
146lib_py_gel.Walker_opposite_halfedge.restype = ct.c_size_t
147lib_py_gel.Walker_opposite_halfedge.argtypes = (ct.c_void_p, ct.c_size_t)
148lib_py_gel.Walker_incident_face.restype = ct.c_size_t
149lib_py_gel.Walker_incident_face.argtypes = (ct.c_void_p, ct.c_size_t)
150lib_py_gel.Walker_incident_vertex.restype = ct.c_size_t
151lib_py_gel.Walker_incident_vertex.argtypes = (ct.c_void_p, ct.c_size_t)
152
153# A list of helper functions
154lib_py_gel.is_halfedge_at_boundary.restype = ct.c_bool
155lib_py_gel.is_halfedge_at_boundary.argtypes = (ct.c_void_p, ct.c_size_t)
156lib_py_gel.is_vertex_at_boundary.restype = ct.c_bool
157lib_py_gel.is_vertex_at_boundary.argtypes = (ct.c_void_p, ct.c_size_t)
158lib_py_gel.length.restype = ct.c_double
159lib_py_gel.length.argtypes = (ct.c_void_p, ct.c_size_t)
160lib_py_gel.boundary_edge.restype = ct.c_bool
161lib_py_gel.boundary_edge.argtypes = (ct.c_void_p, ct.c_size_t, ct.c_size_t)
162lib_py_gel.valency.restype = ct.c_size_t
163lib_py_gel.valency.argtypes = (ct.c_void_p, ct.c_size_t)
164lib_py_gel.vertex_normal.argtypes = (ct.c_void_p, ct.c_size_t, ndpointer(dtype=np.float64, shape=(3,)))
165lib_py_gel.connected.restype = ct.c_bool
166lib_py_gel.connected.argtypes = (ct.c_void_p, ct.c_size_t, ct.c_size_t)
167lib_py_gel.no_edges.restype = ct.c_size_t
168lib_py_gel.no_edges.argtypes = (ct.c_void_p, ct.c_size_t)
169lib_py_gel.face_normal.argtypes = (ct.c_void_p, ct.c_size_t, ndpointer(dtype=np.float64, shape=(3,)))
170lib_py_gel.area.restype = ct.c_double
171lib_py_gel.area.argtypes = (ct.c_void_p, ct.c_size_t)
172lib_py_gel.one_ring_area.restype = ct.c_double
173lib_py_gel.one_ring_area.argtypes = (ct.c_void_p, ct.c_size_t)
174lib_py_gel.total_area.restype = ct.c_double
175lib_py_gel.total_area.argtypes = (ct.c_void_p,)
176lib_py_gel.volume.restype = ct.c_double
177lib_py_gel.volume.argtypes = (ct.c_void_p,)
178lib_py_gel.perimeter.restype = ct.c_double
179lib_py_gel.perimeter.argtypes = (ct.c_void_p, ct.c_size_t)
180lib_py_gel.centre.argtypes = (ct.c_void_p, ct.c_size_t, ndpointer(dtype=np.float64, shape=(3,)))
181lib_py_gel.valid.restype = ct.c_bool
182lib_py_gel.valid.argtypes = (ct.c_void_p,)
183lib_py_gel.closed.restype = ct.c_bool
184lib_py_gel.closed.argtypes = (ct.c_void_p,)
185lib_py_gel.bbox.argtypes = (ct.c_void_p, ndpointer(dtype=np.float64, shape=(3,)),ndpointer(dtype=np.float64, shape=(3,)))
186lib_py_gel.bsphere.argtypes = (ct.c_void_p, ndpointer(dtype=np.float64, shape=(3,)), ct.POINTER(ct.c_double))
187lib_py_gel.stitch_mesh.argtypes = (ct.c_void_p,ct.c_double)
188lib_py_gel.stitch_mesh.restype = ct.c_int
189lib_py_gel.obj_save.argtypes = (ct.c_char_p, ct.c_void_p)
190lib_py_gel.off_save.argtypes = (ct.c_char_p, ct.c_void_p)
191lib_py_gel.x3d_save.argtypes = (ct.c_char_p, ct.c_void_p)
192lib_py_gel.obj_load.argtypes = (ct.c_char_p, ct.c_void_p)
193lib_py_gel.off_load.argtypes = (ct.c_char_p, ct.c_void_p)
194lib_py_gel.ply_load.argtypes = (ct.c_char_p, ct.c_void_p)
195lib_py_gel.x3d_load.argtypes = (ct.c_char_p, ct.c_void_p)
196lib_py_gel.rsr_recon.argtypes = (ct.c_void_p, ndpointer(ndim=2, dtype=ct.c_double,flags='F'), ndpointer(ndim=2, dtype=ct.c_double,flags='F'), ct.c_int, ct.c_int, ct.c_bool, ct.c_int, ct.c_int, ct.c_int, ct.c_int, ct.c_int)
197lib_py_gel.remove_caps.argtypes = (ct.c_void_p, ct.c_float)
198lib_py_gel.remove_needles.argtypes = (ct.c_void_p, ct.c_float, ct.c_bool)
199lib_py_gel.close_holes.argtypes = (ct.c_void_p,ct.c_int)
200lib_py_gel.flip_orientation.argtypes = (ct.c_void_p,)
201lib_py_gel.merge_coincident_boundary_vertices.argtypes = (ct.c_void_p, ct.c_double)
202lib_py_gel.minimize_curvature.argtypes = (ct.c_void_p,ct.c_bool)
203lib_py_gel.minimize_dihedral_angle.argtypes = (ct.c_void_p, ct.c_int, ct.c_bool, ct.c_bool, ct.c_double)
204lib_py_gel.maximize_min_angle.argtypes = (ct.c_void_p,ct.c_float,ct.c_bool)
205lib_py_gel.optimize_valency.argtypes = (ct.c_void_p,ct.c_bool)
206lib_py_gel.randomize_mesh.argtypes = (ct.c_void_p,ct.c_int)
207lib_py_gel.quadric_simplify.argtypes = (ct.c_void_p,ct.c_double,ct.c_double,ct.c_double)
208lib_py_gel.average_edge_length.argtypes = (ct.c_void_p,)
209lib_py_gel.average_edge_length.restype = ct.c_float
210lib_py_gel.median_edge_length.argtypes = (ct.c_void_p,)
211lib_py_gel.median_edge_length.restype = ct.c_float
212lib_py_gel.refine_edges.argtypes = (ct.c_void_p,ct.c_float)
213lib_py_gel.refine_edges.restype = ct.c_int
214lib_py_gel.cc_split.argtypes = (ct.c_void_p,)
215lib_py_gel.loop_split.argtypes = (ct.c_void_p,)
216lib_py_gel.root3_subdivide.argtypes = (ct.c_void_p,)
217lib_py_gel.rootCC_subdivide.argtypes = (ct.c_void_p,)
218lib_py_gel.butterfly_subdivide.argtypes = (ct.c_void_p,)
219lib_py_gel.cc_smooth.argtypes = (ct.c_void_p,)
220lib_py_gel.volume_preserving_cc_smooth.argtypes = (ct.c_void_p,ct.c_int)
221lib_py_gel.regularize_quads.argtypes = (ct.c_void_p,ct.c_float,ct.c_float,ct.c_int)
222lib_py_gel.loop_smooth.argtypes = (ct.c_void_p,)
223lib_py_gel.ear_clip_triangulate.argtypes = (ct.c_void_p,)
224lib_py_gel.shortest_edge_triangulate.argtypes = (ct.c_void_p,)
225lib_py_gel.graph_to_feq.argtypes = (ct.c_void_p, ct.c_void_p, ndpointer(dtype=np.float64, ndim=1), ct.c_bool, ct.c_bool)
226lib_py_gel.graph_to_feq.restype = ct.c_void_p
227lib_py_gel.non_rigid_registration.argtypes = (ct.c_void_p, ct.c_void_p)
228lib_py_gel.taubin_smooth.argtypes = (ct.c_void_p, ct.c_int)
229lib_py_gel.laplacian_smooth.argtypes = (ct.c_void_p, ct.c_float, ct.c_int)
230lib_py_gel.anisotropic_smooth.argtypes = (ct.c_void_p, ct.c_float, ct.c_int)
231lib_py_gel.volumetric_isocontour.argtypes = (ct.c_void_p, ct.c_int, ct.c_int, ct.c_int, ndpointer(ndim=3, dtype=ct.c_float,flags='F'), ndpointer(dtype=ct.c_double,shape=(3,)), ndpointer(dtype=ct.c_double,shape=(3,)), ct.c_float, ct.c_bool, ct.c_bool, ct.c_bool )
232lib_py_gel.extrude_faces.argtypes = (ct.c_void_p, ndpointer(dtype=ct.c_int, ndim=1), ct.c_int, ct.c_void_p)
233lib_py_gel.kill_face_loop.argtypes = (ct.c_void_p,)
234lib_py_gel.kill_degenerate_face_loops.argtypes = (ct.c_void_p,ct.c_double)
235lib_py_gel.stable_marriage_registration.argtypes = (ct.c_void_p,ct.c_void_p)
236lib_py_gel.stable_marriage_registration.restype = ct.c_int
237
238
239
240# MeshDistance allows us to compute the signed distance to a mesh
241lib_py_gel.MeshDistance_new.restype = ct.c_void_p
242lib_py_gel.MeshDistance_new.argtypes = (ct.c_void_p,)
243lib_py_gel.MeshDistance_signed_distance.argtypes = (ct.c_void_p,ct.c_int, ndpointer(dtype=ct.c_float,flags='C'),ndpointer(dtype=ct.c_float,flags='C',ndim=1),ct.c_float)
244lib_py_gel.MeshDistance_ray_inside_test.argtypes = (ct.c_void_p,ct.c_int, ndpointer(dtype=ct.c_float,flags='C'),ndpointer(dtype=ct.c_int,flags='C',ndim=1),ct.c_int)
245lib_py_gel.MeshDistance_ray_intersect.argtypes = (ct.c_void_p,ndpointer(dtype=ct.c_float,shape=3),ndpointer(dtype=ct.c_float,shape=3),ct.POINTER(ct.c_float))
246lib_py_gel.MeshDistance_ray_intersect.restype = ct.c_bool
247lib_py_gel.MeshDistance_delete.argtypes = (ct.c_void_p,)
248
249# The Graph class
250lib_py_gel.Graph_new.restype = ct.c_void_p
251lib_py_gel.Graph_copy.restype = ct.c_void_p
252lib_py_gel.Graph_copy.argtypes = (ct.c_void_p,)
253lib_py_gel.Graph_delete.argtypes = (ct.c_void_p,)
254lib_py_gel.Graph_clear.argtypes = (ct.c_void_p,)
255lib_py_gel.Graph_cleanup.argtypes = (ct.c_void_p,)
256lib_py_gel.Graph_nodes.argtypes = (ct.c_void_p, ct.c_void_p)
257lib_py_gel.Graph_nodes.restype = ct.c_size_t
258lib_py_gel.Graph_neighbors.restype = ct.c_size_t
259lib_py_gel.Graph_neighbors.argtypes = (ct.c_void_p, ct.c_size_t, ct.c_void_p, ct.c_char)
260lib_py_gel.Graph_positions.argtypes = (ct.c_void_p,ct.POINTER(ct.POINTER(ct.c_double)))
261lib_py_gel.Graph_positions.restype = ct.c_size_t
262lib_py_gel.Graph_average_edge_length.argtypes = (ct.c_void_p,)
263lib_py_gel.Graph_average_edge_length.restype = ct.c_double
264lib_py_gel.Graph_add_node.argtypes = (ct.c_void_p, ndpointer(ct.c_double))
265lib_py_gel.Graph_add_node.restype = ct.c_size_t
266lib_py_gel.Graph_remove_node.argtypes = (ct.c_void_p, ct.c_size_t)
267lib_py_gel.Graph_node_in_use.argtypes = (ct.c_void_p, ct.c_size_t)
268lib_py_gel.Graph_node_in_use.restype = ct.c_bool
269lib_py_gel.Graph_connect_nodes.argtypes = (ct.c_void_p, ct.c_size_t, ct.c_size_t)
270lib_py_gel.Graph_connect_nodes.restype = ct.c_size_t
271lib_py_gel.Graph_disconnect_nodes.argtypes = (ct.c_void_p, ct.c_size_t, ct.c_size_t)
272lib_py_gel.Graph_merge_nodes.argtypes = (ct.c_void_p, ct.c_size_t, ct.c_size_t, ct.c_bool)
273
274# Graph functions
275lib_py_gel.graph_from_mesh.argtypes = (ct.c_void_p, ct.c_void_p)
276lib_py_gel.graph_load.argtypes = (ct.c_void_p, ct.c_char_p)
277lib_py_gel.graph_load.restype = ct.c_void_p
278lib_py_gel.graph_save.argtypes = (ct.c_void_p, ct.c_char_p)
279lib_py_gel.graph_save.restype = ct.c_bool
280lib_py_gel.graph_to_mesh_cyl.argtypes = (ct.c_void_p, ct.c_void_p, ct.c_float)
281lib_py_gel.graph_to_mesh_cyl.restype = ct.c_void_p
282lib_py_gel.graph_to_mesh_iso.argtypes = (ct.c_void_p, ct.c_void_p, ct.c_float, ct.c_int)
283lib_py_gel.graph_to_mesh_iso.restype = ct.c_void_p
284lib_py_gel.graph_smooth.argtypes = (ct.c_void_p, ct.c_int, ct.c_float)
285lib_py_gel.graph_edge_contract.argtypes = (ct.c_void_p, ct.c_double)
286lib_py_gel.graph_prune.argtypes = (ct.c_void_p,)
287lib_py_gel.graph_saturate.argtypes = (ct.c_void_p, ct.c_int, ct.c_double, ct.c_double)
288lib_py_gel.graph_LS_skeleton.argtypes = (ct.c_void_p, ct.c_void_p, ct.c_void_p, ct.c_bool)
289lib_py_gel.graph_MSLS_skeleton.argtypes = (ct.c_void_p, ct.c_void_p, ct.c_void_p, ct.c_int)
290lib_py_gel.graph_front_skeleton.argtypes = (ct.c_void_p, ct.c_void_p, ct.c_void_p, ct.c_int, ndpointer(dtype=np.float64,flags='C'), ct.c_int)
291lib_py_gel.graph_combined_skeleton.argtypes = (ct.c_void_p, ct.c_void_p, ct.c_void_p, ct.c_int, ndpointer(dtype=np.float64,flags='C'), ct.c_int)
292lib_py_gel.graph_minimum_spanning_tree.argtypes = (ct.c_void_p, ct.c_void_p, ct.c_int)
293lib_py_gel.graph_close_chordless_cycles.argtypes = (ct.c_void_p, ct.c_int, ct.c_int, ct.c_double)
294
295class IntVector:
296    """ Vector of integer values.
297    This is a simple class that implements iteration and index based
298    retrieval. Allocation happens in a call to libPyGEL. Since memory
299    is managed by the PyGEL library, the vector can be resized by library
300    functions. Not used directly by PyGEL3D users."""
301    def __init__(self):
302        self.obj = lib_py_gel.IntVector_new(0)
303    def __del__(self):
304        lib_py_gel.IntVector_delete(self.obj)
305    def __len__(self):
306        return int(lib_py_gel.IntVector_size(self.obj))
307    def __getitem__(self,key):
308        return lib_py_gel.IntVector_get(self.obj,key)
309    def __iter__(self):
310        n = lib_py_gel.IntVector_size(self.obj)
311        for i in range(0,n):
312            yield lib_py_gel.IntVector_get(self.obj, i)
313
314class Vec3dVector:
315    """ Vector of 3D vectors.
316    This is a simple class that implements iteration and index based
317    retrieval. Allocation happens in a call to libPyGEL. Since memory
318    is managed by the PyGEL library, the vector can be resized by library
319    functions. Not used directly by PyGEL3D users."""
320    def __init__(self):
321        self.obj = lib_py_gel.Vec3dVector_new(0)
322    def __del__(self):
323        lib_py_gel.Vec3dVector_delete(self.obj)
324    def __len__(self):
325        return int(lib_py_gel.Vec3dVector_size(self.obj))
326    def __getitem__(self,key):
327        return lib_py_gel.Vec3dVector_get(self.obj,key)
328    def __iter__(self):
329        n = lib_py_gel.Vec3dVector_size(self.obj)
330        for i in range(0,n):
331            data = lib_py_gel.Vec3dVector_get(self.obj, i)
332            yield [data[0], data[1], data[2]]