def automated_smoothing_constraints(mesh, points = None, curves = None, surface = None, mesh2 = None): """Apply automatically point, curve and surface constraints to the vertices of a mesh to smooth. Parameters ---------- mesh : Mesh The mesh to apply the constraints to for smoothing. points : list List of XYZ coordinates on which to constrain mesh vertices. Default is None. curves : list List of Rhino curve guids on which to constrain mesh vertices. Default is None. surface : Rhino surface guid A Rhino surface guid on which to constrain mesh vertices. Default is None. mesh2 : Rhino mesh guid A Rhino mesh guid on which to constrain mesh vertices. Default is None. Returns ------- constraints : dict A dictionary of mesh constraints for smoothing as vertex keys pointing to point, curve or surface objects. """ if surface: surface = RhinoSurface.from_guid(surface) if curves: curves = [RhinoCurve.from_guid(curve) for curve in curves] if mesh2: mesh2 = RhinoMesh.from_guid(mesh2) constraints = {} constrained_vertices = {} vertices = list(mesh.vertices()) vertex_coordinates = [mesh.vertex_coordinates(vkey) for vkey in mesh.vertices()] if points is not None and len(points) != 0: constrained_vertices.update({vertices[closest_point_in_cloud(rs.PointCoordinates(point), vertex_coordinates)[2]]: point for point in points}) if mesh2 is not None: constraints.update({vkey: mesh2.guid for vkey in mesh.vertices()}) if surface is not None: constraints.update({vkey: surface.guid for vkey in mesh.vertices()}) if curves is not None and len(curves) != 0: boundaries = [split_boundary for boundary in mesh.boundaries() for split_boundary in list_split(boundary, [boundary.index(vkey) for vkey in constrained_vertices.keys() if vkey in boundary])] boundary_midpoints = [Polyline([mesh.vertex_coordinates(vkey) for vkey in boundary]).point(t = .5) for boundary in boundaries] curve_midpoints = [rs.EvaluateCurve(curve, rs.CurveParameter(curve, .5)) for curve in curves] midpoint_map = {i: closest_point_in_cloud(boundary_midpoint, curve_midpoints)[2] for i, boundary_midpoint in enumerate(boundary_midpoints)} constraints.update({vkey: curves[midpoint_map[i]].guid for i, boundary in enumerate(boundaries) for vkey in boundary}) if points is not None: constraints.update(constrained_vertices) return constraints
def automated_smoothing_surface_constraints(mesh, surface): """Apply automatically surface-related constraints to the vertices of a mesh to smooth: kinks, boundaries and surface. Parameters ---------- mesh : Mesh The mesh to apply the constraints to for smoothing. surface : Rhino surface guid A Rhino surface guid on which to constrain mesh vertices. Returns ------- constraints : dict A dictionary of mesh constraints for smoothing as vertex keys pointing to point, curve or surface objects. """ surface = RhinoSurface.from_guid(surface) constraints = {} points = [rs.AddPoint(point) for point in surface.kinks()] curves = surface.borders(type = 0) constraints.update({vkey: surface.guid for vkey in mesh.vertices()}) for vkey in mesh.vertices_on_boundary(): xyz = mesh.vertex_coordinates(vkey) projections = {curve: distance_point_point(xyz, RhinoCurve.from_guid(curve).closest_point(xyz)) for curve in curves} constraints.update({vkey: min(projections, key = projections.get)}) key_to_index = {i: vkey for i, vkey in enumerate(mesh.vertices_on_boundary())} vertex_coordinates = tuple(mesh.vertex_coordinates(vkey) for vkey in mesh.vertices_on_boundary()) constraints.update({key_to_index[closest_point_in_cloud(rs.PointCoordinates(point), vertex_coordinates)[2]]: point for point in points}) return constraints
def create_variable_thick_shell(mesh, minthick, maxthick): bkeys = mesh.vertices_on_boundary() bpts = [mesh.get_vertex_attributes(k, ['x', 'y', 'z']) for k in bkeys] fkeys = mesh.face.keys() dist_dict = { fkey: closest_point_in_cloud(mesh.face_centroid(fkey), bpts)[0] for fkey in mesh.face } min_ = min(dist_dict.values()) max_ = max(dist_dict.values()) for fkey in fkeys: thick = (((dist_dict[fkey] - min_) * (maxthick - minthick)) / (max_ - min_)) + minthick mesh.set_face_attribute(fkey, 'thick', thick)
def pull_to_mesh(self, s_mesh, name): # self.pos, self.f_id = s_mesh.closest_point(self.pos) d, xyz, i = cg.closest_point_in_cloud(self.pos, s_mesh.face_centroids) self.f_id = s_mesh.gkey_fkey[geometric_key(xyz)] # self.update_pos(self.pos) edge = self.pull_to_edge(s_mesh, self.f_id) if edge is not None: self.edge = edge self.is_intersection = True # self.vel = s_mesh.get_vector_on_face(self.pos, self.f_id, name) self.vel = s_mesh.c_mesh.face_attribute(key=self.f_id, name=name)
def get_closest_pt(pt, pts): """ Finds the closest point of 'pt' in the point cloud 'pts'. Parameters ---------- pt: :class: 'compas.geometry.Point' pts: list, :class: 'compas.geometry.Point3d' Returns ---------- compas.geometry.Point3d The closest point """ ci = closest_point_in_cloud(point=pt, cloud=pts)[2] return pts[ci]
def get_closest_pt_index(pt, pts): """ Finds the index of the closest point of 'pt' in the point cloud 'pts'. Parameters ---------- pt: compas.geometry.Point3d pts: list, compas.geometry.Point3d Returns ---------- int The index of the closest point """ ci = closest_point_in_cloud(point=pt, cloud=pts)[2] # distances = [distance_point_point_sqrd(p, pt) for p in pts] # ci = distances.index(min(distances)) return ci
def create_sk3_branch(u, v): def find_vertices(u, v): sk3_joint_u = sk3_joints[u] # inside of network_u, find vertices on the verge leaf_u = descendent_tree[u][ v] # this is network local key, not convexhull mesh leaf_u = sk3_joint_u.network_convexhull[leaf_u] nbrs = sk3_joint_u.convexhull_mesh.vertex_neighbors(leaf_u, ordered=True) keys = [ sk3_joint_u.descendent_tree[leaf_u][nbr]['lp'] for nbr in nbrs ] points = [sk3_joint_u.vertex_coordinates(key) for key in keys] return points if u in joints and v in joints: # its an internal edge points_u = find_vertices(u, v) points_v = find_vertices(v, u) if len(points_u) != len(points_v): mesh = get_convex_hull_mesh(points_u + points_v) else: points_v = points_v[::-1] index = closest_point_in_cloud(points_u[0], points_v)[2] points_v = points_v[index:] + points_v[:index] vertices = points_u + points_v faces = [] n = len(points_u) for i in range(n): faces.append([i, (i + 1) % n, (i + 1) % n + n, i + n]) mesh = Mesh.from_vertices_and_faces(vertices, faces) else: if u in leafs: leaf, joint = u, v elif v in leafs: leaf, joint = v, u points_joint = find_vertices(joint, leaf) network = networks[joint] u_local = descendent_tree[joint][joint] v_local = descendent_tree[joint][leaf] vec = [ i * (1 - joint_length) for i in network_global.edge_vector(joint, leaf) ] points_leaf = [add_vectors(pt, vec) for pt in points_joint] vertices = points_joint + points_leaf faces = [] n = len(points_joint) for i in range(n): faces.append([i, (i + 1) % n, (i + 1) % n + n, i + n]) mesh = Mesh.from_vertices_and_faces(vertices, faces) return mesh