Source code for ddg.optimize.functionals.planar_faces_energy

from ddg.optimize.functional import HalfEdgeFunctional
from ddg.datastructures.halfedge.get import get_edge_loop
import scipy.spatial.qhull as qhull
from scipy.spatial import ConvexHull

[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 get_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 qhull.QhullError as e: if str(e)[0:6] != "QH6154": raise else: continue return E