Source code for compas.datastructures.mesh.planarisation
from__future__importprint_functionfrom__future__importabsolute_importfrom__future__importdivisionfromcompas.geometryimportproject_points_planefromcompas.geometryimportcentroid_pointsfromcompas.geometryimportdistance_point_pointfromcompas.geometryimportdistance_line_linefromcompas.geometryimportbestfit_planefromcompas.utilitiesimportwindow__all__=['mesh_flatness','mesh_planarize_faces',]defmesh_flatness(mesh,maxdev=1.0):"""Compute mesh flatness per face. Parameters ---------- mesh : Mesh A mesh object. maxdev : float, optional A maximum value for the allowed deviation from flatness. Default is ``1.0``. Returns ------- dict For each face, a deviation from *flatness*. Notes ----- The "flatness" of a face is expressed as the ratio of the distance between the diagonals to the average edge length. For the fabrication of glass panels, for example, ``0.02`` could be a reasonable maximum value. Warnings -------- This function only works as expected for quadrilateral faces. """dev=[]forfkeyinmesh.faces():points=mesh.face_coordinates(fkey)iflen(points)==3:dev.append(0.0)else:lengths=[distance_point_point(a,b)fora,binwindow(points+points[0:1],2)]length=sum(lengths)/len(lengths)d=distance_line_line((points[0],points[2]),(points[1],points[3]))dev.append((d/length)/maxdev)returndev
[docs]defmesh_planarize_faces(mesh,fixed=None,kmax=100,callback=None,callback_args=None):"""Planarise a set of connected faces. Planarisation is implemented as a two-step iterative procedure. At every iteration, faces are first individually projected to their best-fit plane, and then the vertices are projected to the centroid of the disconnected corners of the faces. Parameters ---------- mesh : Mesh A mesh object. fixed : list, optional [None] A list of fixed vertices. kmax : int, optional [100] The number of iterations. d : float, optional [1.0] A damping factor. callback : callable, optional [None] A user-defined callback that is called after every iteration. callback_args : list, optional [None] A list of arguments to be passed to the callback function. Returns ------- None """ifcallback:ifnotcallable(callback):raiseException('The callback is not callable.')fixed=fixedor[]fixed=set(fixed)forkinrange(kmax):positions={key:[]forkeyinmesh.vertices()}forfkeyinmesh.faces():vertices=mesh.face_vertices(fkey)points=[mesh.vertex_coordinates(key)forkeyinvertices]plane=bestfit_plane(points)projections=project_points_plane(points,plane)forindex,keyinenumerate(vertices):positions[key].append(projections[index])forkey,attrinmesh.vertices(True):ifkeyinfixed:continuex,y,z=centroid_points(positions[key])attr['x']=xattr['y']=yattr['z']=zifcallback:callback(k,callback_args)