Source code for ddg.optimize.he.functionals.planar_faces_energy

from scipy.spatial import ConvexHull, QhullError

from ddg.halfedge import edge_loop
from ddg.optimize.he.functional import HalfEdgeFunctional


[docs]class PlanarFacesEnergy(HalfEdgeFunctional): """ Measures the non-planarity of the faces of a discrete surface using their volume. """ def __init__(self, surface, attr_name, attr_dimension=None, boundary_cells=set()): super().__init__( surface, attr_name, "verts", attr_dimension=attr_dimension, boundary_cells=boundary_cells, )
[docs] def evaluate(self, x): """ The evaluate function creates a convex hull for each face using scipy.spatial.ConvexHull which uses the Qhull algorithm (qhull.org) and then evaluates the volume of each face. The errors in the Qhull algorithm each start with the ID "QH6...". "QH6154" refers to the error where the inputs for the convex hull are already planar. In this method, this specific error is bypassed for obvious reasons. """ E = 0 for face in self.surface.faces: vertices = [] for edge in edge_loop(face.edge): i = edge.tail coordinate = ( x[i.interior_cell_index] if i.interior_cell_index is not None else getattr(i, self.attr_name) ) vertices.append(coordinate) try: hull = ConvexHull(vertices) E += hull.volume**2 except QhullError as e: if str(e)[0:6] != "QH6154": raise else: continue return E