|
2 | 2 | Tutorial
|
3 | 3 | ********************************************************************************
|
4 | 4 |
|
5 |
| -* Similar input parameters as hte original code |
6 |
| -* Meshes represented by a list of vertices and a list of triangles |
7 |
| -* Both Python lists and Numpy arrays are supported |
8 |
| -* Most functions are implemented as pluggables for plugins of COMPAS core |
9 |
| -* Therefore, the code can be used from compas_libigl or from compas directly |
10 |
| -* Results can easily be visualized using the COMPAS Viewer |
11 |
| -* Since the binding is generated with PyBind11 and wraps C++ code, it cannot be used in Rhino/Grasshopper directly |
12 |
| -* However it can be used there through RPC |
| 5 | +.. rst-class:: lead |
13 | 6 |
|
| 7 | +:mod:`compas_libigl` provides bindings for the libigl library. |
| 8 | +It doesn't cover the entire library, but only for specific functions. |
| 9 | +Currently, the following functions are supported: |
| 10 | + |
| 11 | +* :func:`compas_libigl.intersection_ray_mesh` |
| 12 | +* :func:`compas_libigl.intersection_rays_mesh` |
| 13 | +* :func:`compas_libigl.trimesh_boundaries` |
| 14 | +* :func:`compas_libigl.trimesh_gaussian_curvature` |
| 15 | +* :func:`compas_libigl.trimesh_principal_curvature` |
| 16 | +* :func:`compas_libigl.trimesh_geodistance` |
| 17 | +* :func:`compas_libigl.trimesh_isolines` |
| 18 | +* :func:`compas_libigl.trimesh_massmatrix` |
| 19 | +* :func:`compas_libigl.trimesh_harmonic` |
| 20 | +* :func:`compas_libigl.trimesh_lscm` |
| 21 | +* :func:`compas_libigl.trimesh_remesh_along_isoline` |
| 22 | +* :func:`compas_libigl.quadmesh_planarize` |
| 23 | + |
| 24 | + |
| 25 | +Input/Output |
| 26 | +============ |
| 27 | + |
| 28 | +The function signatures of the bindings are similar to the original libigl functions. |
| 29 | +Meshes are represented by a tuple containing a list/array of vertices and a list/array of faces. |
| 30 | +Most functions require the input mesh to be a triangle mesh. |
| 31 | + |
| 32 | +.. code-block:: python |
| 33 | +
|
| 34 | + import compas |
| 35 | + import compas_libigl |
| 36 | + from compas.datastructures import Mesh |
| 37 | +
|
| 38 | + mesh = Mesh.from_obj(compas.get("tubemesh.obj")) |
| 39 | + mesh.quads_to_triangles() |
| 40 | +
|
| 41 | + V, F = mesh.to_vertices_and_faces() |
| 42 | +
|
| 43 | + source = trimesh.vertex_sample(size=1)[0] |
| 44 | + distance = compas_libigl.trimesh_geodistance( |
| 45 | + (V, F), |
| 46 | + source, |
| 47 | + method="heat", |
| 48 | + ) |
| 49 | +
|
| 50 | +
|
| 51 | +Both Python lists and Numpy arrays are supported. |
| 52 | + |
| 53 | +.. code-block:: python |
| 54 | +
|
| 55 | + import numpy |
| 56 | + import compas |
| 57 | + import compas_libigl |
| 58 | + from compas.datastructures import Mesh |
| 59 | +
|
| 60 | + mesh = Mesh.from_obj(compas.get("tubemesh.obj")) |
| 61 | + mesh.quads_to_triangles() |
| 62 | +
|
| 63 | + vertices, faces = mesh.to_vertices_and_faces() |
| 64 | + V = numpy.array(vertices, dtype=float) |
| 65 | + F = numpy.array(faces, dtype=int) |
| 66 | +
|
| 67 | + source = trimesh.vertex_sample(size=1)[0] |
| 68 | + distance = compas_libigl.trimesh_geodistance( |
| 69 | + (V, F), |
| 70 | + source, |
| 71 | + method="heat", |
| 72 | + ) |
| 73 | +
|
| 74 | +
|
| 75 | +Pluggables |
| 76 | +========== |
| 77 | + |
| 78 | + |
| 79 | +Visualisation |
| 80 | +============= |
| 81 | + |
| 82 | + |
| 83 | +Working in Rhino/Grasshopper |
| 84 | +============================ |
| 85 | + |
| 86 | +The bindings are generated with PyBind11 and wrap the C++ code of libigl. |
| 87 | +Therefore, the bindings are not compatible with IronPython and cannot be used in Rhino/Grasshopper directly. |
| 88 | +However, they can be used in Rhino/Grasshopper through RPC. |
| 89 | + |
| 90 | +.. code-block:: python |
| 91 | +
|
| 92 | + import compas |
| 93 | + from compas.rpc import Proxy |
| 94 | + from compas.datastructures import Mesh |
| 95 | + from compas.datastructures import mesh_flatness |
| 96 | + from compas.colors import Color, ColorMap |
| 97 | + from compas.artists import Artist |
| 98 | +
|
| 99 | + compas_libigl = Proxy('compas_libigl') |
| 100 | +
|
| 101 | + mesh = Mesh.from_obj(compas.get("tubemesh.obj")) |
| 102 | + |
| 103 | + V, F = mesh.to_vertices_and_faces() |
| 104 | + V2 = compas_libigl.quadmesh_planarize((V, F), 100, 0.005) |
| 105 | +
|
| 106 | + mesh = Mesh.from_vertices_and_faces(V2, F) |
| 107 | + dev = mesh_flatness(mesh, maxdev=TOL) |
| 108 | + cmap = ColorMap.from_two_colors(Color.white(), Color.blue()) |
| 109 | +
|
| 110 | + facecolor={ |
| 111 | + face: (cmap(dev[face]) if dev[face] <= 1.0 else Color.red()) |
| 112 | + for face in mesh.faces() |
| 113 | + } |
| 114 | +
|
| 115 | + artist = Artist(mesh, layer="libigl::quadmesh_planarize") |
| 116 | + artist.draw(facecolor=facecolor, disjoint=True) |
0 commit comments