Boundary First Flattening
Example
import mouette as M
mesh = M.mesh.load("path/to/mesh")
bff = M.parametrization.BoundaryFirstFlattening(mesh, bnd_scale_fctr=scale, verbose=True)
mesh = bff.run() # /!\ mesh is not modified in place
See https://github.com/GCoiffier/mouette/blob/main/examples/parametrization/bff.py
ArrayAttribute(elem_type, n_elem, elem_size=1, default_value=None)
Bases: _BaseAttribute
init method and the whole Attribute class are not supposed to be manipulated outside of the DataContainer class. An ArrayAttribute stores its values in a numpy array. This is a less flexible but safer approach than Attribute.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
elem_type |
the type of the attribute (bool, int, float, complex, string) |
required | |
n_elem |
int
|
Total number of elements in the container. Should match the size of the DataContainer the attribute is stored in. |
required |
elem_size |
int
|
Number of elem_type objects to be stored per element. Defaults to 1. |
1
|
dense |
bool
|
description. Defaults to False. |
required |
default_value |
optional)
|
the default value of the attribute is n_elem is not specified. If it is not specified either, it will correspond to the default value of the type provided in elem_type. |
None
|
__iter__()
Sparse attributes allow to iterate only over non-default elements
clear()
Empties the attribute. Frees the memory and ensures that all access return default value
empty()
Check if an attribute is empty. For an attribute to be empty, its number of elements should not be fixed, and the dictionnary should be empty
Attribute(elem_type, elem_size=1, default_value=None)
Bases: _BaseAttribute
init method and the whole Attribute class are not supposed to be manipulated outside of the DataContainer class
Parameters:
Name | Type | Description | Default |
---|---|---|---|
elem_type |
the type of the attribute (bool, int, float, complex, string) |
required | |
elem_size |
int
|
Number of elem_type objects to be stored per element. Defaults to 1. |
1
|
default_value |
optional)
|
the default value of the attribute is n_elem is not specified. If it is not specified either, it will correspond to the default value of the type provided in elem_type. |
None
|
__iter__()
Sparse attributes allow to iterate only over non-default elements
clear()
Empties the attribute. Frees the memory and ensures that all access return default value
empty()
Check if an attribute is empty. For an attribute to be empty, its number of elements should not be fixed, and the dictionnary should be empty
BoundaryFirstFlattening(mesh, bnd_scale_fctr=None, bnd_curvature=None, verbose=False, **kwargs)
Bases: BaseParametrization
Boundary First Flattening: A conformal flattening algorithm with control over the boundary conditions, either in terms of scale factor or curvature
References
- [1] Boundary First Flattening, Rohan Sawhney and Keenan Crane, ACM ToG, 2017
Warning
This algorithm reorders the vertices so that boundary vertices are labeled [0, N-1] in order. Therefore, the uvs coordinates are not computed on the original mesh but on a reordered copy. Access the final result with self.mesh
Parameters:
Name | Type | Description | Default |
---|---|---|---|
mesh |
SurfaceMesh
|
the input surface. Should be a triangulation of a topological disk. |
required |
bnd_scale_fctr |
Attribute
|
Scale factor on the boundary. Ignores values for interior vertices. Defaults to None. If provided, will automatically compute boundary curvature and ignore the |
None
|
bnd_curvature |
Attribute
|
Geodesic curvature on the boundary. Ignores values for interior vertices. Defaults to None. If provided (and no |
None
|
verbose |
bool
|
verbose mode. Defaults to False. |
False
|
Other Parameters:
Name | Type | Description |
---|---|---|
save_on_corners |
bool
|
if True, stores the results on face corners instead of vertices. Defaults to True |
use_cotan |
bool
|
if True, uses the cotan Laplacian instead of the connectivity Laplacian. Defaults to True. |
hilbert_transform |
bool
|
if True, extends the boundary values with the Hilbert transform |
Raises:
Type | Description |
---|---|
Exception
|
if the mesh is not the triangulation of a topological disk |
Note
If neither of bnd_scale_fctr
and bnd_curvature
are provided, the algorithm will run in default mode with scale factors = 0 on the boundary. Otherwise, provided scale factors have priority over provided curvatures.
flat_mesh: SurfaceMesh
property
A flat representation of the mesh where uv-coordinates are copied to xy.
Returns:
Name | Type | Description |
---|---|---|
SurfaceMesh |
SurfaceMesh
|
the flat mesh |
run()
Run the algorithm
Raises:
Type | Description |
---|---|
Exception
|
If the mesh is not a triangulation of a topological disk |
Returns:
Name | Type | Description |
---|---|---|
SurfaceMesh |
SurfaceMesh
|
a copy of the original mesh with reordered vertices and computed uv-coordinates |
PointCloud(data=None)
Bases: Mesh
A data structure for representing point clouds
Attributes:
Name | Type | Description |
---|---|---|
vertices |
DataContainer
|
the container for all vertices |
__str__ |
str
|
Representation of the object and its elements as a string. |
id_vertices
property
Shortcut for range(len(self.vertices))
append(x)
Shortcut for self.vertices.append(x)
, since we can only append elements in the 'vertices' container
PolyLine(data=None)
Bases: Mesh
A data structure for representing polylines.
Attributes:
Name | Type | Description |
---|---|---|
vertices |
DataContainer
|
the container for all vertices |
edges |
DataContainer
|
the container for all edges |
__str__ |
Representation of the object and its elements as a string. |
id_edges
property
Shortcut for range(len(self.edges))
id_vertices
property
Shortcut for range(len(self.vertices))
SurfaceMesh(data=None)
Bases: Mesh
A data structure for representing polygonal surfaces.
Attributes:
Name | Type | Description |
---|---|---|
vertices |
DataContainer
|
the container for all vertices |
edges |
DataContainer
|
the container for all edges |
faces |
DataContainer
|
the container for all faces |
face_corners |
DataContainer
|
the container for all corner of faces |
boundary_edges |
list
|
list of all edge indices on the boundary |
interior_edges |
list
|
list of all interior edge indices (all edges \ boundary_edges) |
boundary_vertices |
list
|
list of all vertex indices on the boundary |
interior_vertices |
list
|
list of all interior verticex indices (all vertices \ boundary_vertices) |
connectivity |
_SurfaceConnectivity
|
the connectivity utility class |
id_corners
property
Shortcut for range(len(self.face_corners))
id_edges
property
Shortcut for range(len(self.edges))
id_faces
property
Shortcut for range(len(self.faces))
id_vertices
property
Shortcut for range(len(self.vertices))
clear_boundary_data()
Clear all boundary data. Next call to a boundary/interior container or method will recompute everything
is_edge_on_border(u, v)
whether edge (u,v) is a boundary edge or not
Parameters:
Name | Type | Description | Default |
---|---|---|---|
u |
int
|
vertex id |
required |
v |
int
|
vertex id |
required |
Returns:
Name | Type | Description |
---|---|---|
bool |
bool
|
whether edge (u,v) is a boundary edge or not. Returns False if (u,v) is not a valid edge. |
is_quad()
Returns:
Name | Type | Description |
---|---|---|
bool |
bool
|
True if the mesh is quadrangular (all faces are quad) |
is_triangular()
Returns:
Name | Type | Description |
---|---|---|
bool |
bool
|
True if the mesh is triangular (all faces are triangles) |
is_vertex_on_border(u)
whether vertex u
is a boundary vertex or not.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
u |
int
|
vertex id |
required |
Returns:
Name | Type | Description |
---|---|---|
bool |
bool
|
whether vertex |
ith_vertex_of_face(fid, i)
helper function to get the i-th vertex of a face, i.e. self.faces[fid][i]
Parameters:
Name | Type | Description | Default |
---|---|---|---|
fid |
int
|
face id |
required |
i |
int
|
vertex id in face. Should be 0 <= vid < len(face) |
required |
Returns:
Name | Type | Description |
---|---|---|
int |
int
|
the id of the i-th vertex in face |
pt_of_face(fid)
point coordinates of vertices of face fid
Parameters:
Name | Type | Description | Default |
---|---|---|---|
fid |
int
|
face id |
required |
Returns:
Name | Type | Description |
---|---|---|
Iterable |
iterator of Vec objects representing point coordinates of vertices |
Vec
Bases: ndarray
A simple class to manipulate vectors in mouette. Basically, it inherits from a numpy array and implements some quality of life features for 2D and 3D vectors especially.
x: float
property
writable
First coordinate of the vector
Returns:
Name | Type | Description |
---|---|---|
float |
float
|
|
xy
property
First two coordinates of the vector
Returns:
Name | Type | Description |
---|---|---|
float |
|
y
property
writable
Second coordinate of the vector
Returns:
Name | Type | Description |
---|---|---|
float |
|
z
property
writable
Third coordinate of the vector
Returns:
Name | Type | Description |
---|---|---|
float |
|
X()
classmethod
The [1,0,0] vector
Returns:
Name | Type | Description |
---|---|---|
Vec |
[1,0,0] |
Y()
classmethod
The [0,1,0] vector
Returns:
Name | Type | Description |
---|---|---|
Vec |
[0,1,0] |
Z()
classmethod
The [0,0,1] vector
Returns:
Name | Type | Description |
---|---|---|
Vec |
[0,0,1] |
dot(other)
Dot product between two vectors:
$ a \cdot b = \sum_i a[i]b[i]$
Parameters:
Name | Type | Description | Default |
---|---|---|---|
other |
Vec
|
other vector to dot with |
required |
Returns:
Name | Type | Description |
---|---|---|
float |
float
|
the dot product |
from_complex(c)
classmethod
2D vector from complex number
Parameters:
Name | Type | Description | Default |
---|---|---|---|
c |
complex
|
|
required |
Returns:
Name | Type | Description |
---|---|---|
Vec |
|
norm(which='l2')
Vector norm. Three norms are implemented: the Euclidean l2 norm, the l1 norm or the l-infinite norm:
l2 : $ \sqrt{ \sum_i v[i]^2 } $
l1 : $ \sum_i |v[i]| $
linf : $ \max_i |v[i]| $
Parameters:
Name | Type | Description | Default |
---|---|---|---|
which |
str
|
which norm to compute. Choices are "l2", "l1" and "linf". Defaults to "l2". |
'l2'
|
Returns:
Name | Type | Description |
---|---|---|
float |
float
|
the vector's norm |
normalize(which='l2')
Normalizes the vector to have unit norm.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
which |
str
|
which norm to compute. Choices are "l2", "l1" and "linf". Defaults to "l2". |
'l2'
|
normalized(vec, which='l2')
staticmethod
Computes and returns a normalized vector of the input vector vec
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
vec |
Vec
|
the input vector |
required |
which |
str
|
which norm to compute. Choices are "l2", "l1" and "linf". Defaults to "l2". |
'l2'
|
Returns:
Name | Type | Description |
---|---|---|
Vec |
the normalized vector |
outer(other)
Outer product between two vectors:
\(a \otimes b = c \in \mathbb{R}^{n \times n}\) such that \(c[i,j] = a[i]b[j]\).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
other |
Vec
|
the second vector |
required |
Returns:
Type | Description |
---|---|
ndarray
|
np.array: an array of shape (n,n) |
random(n)
classmethod
Generates a random vector of size n
with coefficients sampled uniformly and independently in [0;1)
Parameters:
Name | Type | Description | Default |
---|---|---|---|
n |
int
|
size |
required |
Returns:
Name | Type | Description |
---|---|---|
Vec |
|
zeros(n)
classmethod
Generates a vector of size n
full of zeros.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
n |
int
|
size |
required |
Returns:
Name | Type | Description |
---|---|---|
Vec |
|
VolumeMesh(data=None)
Bases: Mesh
id_cells
property
Shortcut for range(len(self.cells))
id_corners
property
Shortcut for range(len(self.face_corners))
id_edges
property
Shortcut for range(len(self.edges))
id_faces
property
Shortcut for range(len(self.faces))
id_vertices
property
Shortcut for range(len(self.vertices))
is_edge_on_border(*args)
Simple test to determine if a given edge is on the boundary of the mesh.
Returns:
Name | Type | Description |
---|---|---|
bool |
bool
|
Returns True if the given edge is on the boundary of the mesh. |
is_face_on_border(*args)
Simple test to determine if a given face is on the boundary of the mesh.
Returns:
Name | Type | Description |
---|---|---|
bool |
bool
|
Returns True is the given face exists and is on the boundary of the mesh |
is_tetrahedral()
Returns:
Name | Type | Description |
---|---|---|
bool |
bool
|
True if the mesh is tetrahedral (all cells are tetrahedra) |