from compas.topology import trimesh_remesh from compas.plotters import MeshPlotter points = hstack((10.0 * random.random_sample((10, 2)), zeros( (10, 1)))).tolist() faces = delaunay_from_points(points) mesh = Mesh.from_vertices_and_faces(points, faces) trimesh_remesh(mesh, 1.0, allow_boundary_split=True) points = [mesh.vertex_coordinates(key) for key in mesh.vertices()] faces = delaunay_from_points(points) mesh = Mesh.from_vertices_and_faces(points, faces) dual = mesh_dual(mesh) # network = FaceNetwork.from_vertices_and_faces(points, faces) # network_find_faces(network) # dual = network_dual(network) lines = [] for u, v in mesh.edges(): lines.append({ 'start': mesh.vertex_coordinates(u, 'xy'), 'end': mesh.vertex_coordinates(v, 'xy'), 'color': '#cccccc', 'width': 0.5 }) plotter = MeshPlotter(dual, figsize=(10, 7))
# set fixed vertices fixed = set(mesh.vertices_on_boundary()) # artist = MeshArtist(mesh, layer='delaunay') # artist.draw_faces(join_faces=True) conduit = MeshConduit(mesh, refreshrate=2) # run remeshing algorithm with conduit.enabled(): trimesh_remesh(mesh, target=trg_l, kmax=kmax, tol=0.1, divergence=0.01, allow_boundary_split=True, allow_boundary_swap=True, allow_boundary_collapse=False, smooth=True, fixed=fixed, callback=callback, callback_args=[srf]) artist = MeshArtist(mesh, layer='remeshed') artist.draw_faces(join_faces=True) dual_mesh = mesh_dual(mesh) artist = MeshArtist(dual_mesh, layer='dual') artist.draw_edges(color=[255, 0, 0]) artist.redraw()
def voronoi_from_delaunay(delaunay): """Construct the Voronoi dual of the triangulation of a set of points. Parameters ---------- delaunay : Mesh A delaunay mesh. Returns ------- Mesh The corresponding voronoi mesh. Warning ------- This function does not work properly if all vertices of the delaunay are on the boundary. Example ------- .. plot:: :include-source: from compas.datastructures import Mesh from compas.topology import trimesh_remesh from compas.topology import delaunay_from_points from compas.topology import voronoi_from_delaunay from compas.geometry import pointcloud_xy from compas.plotters import MeshPlotter points = pointcloud_xy(10, (0, 10)) faces = delaunay_from_points(points) delaunay = Mesh.from_vertices_and_faces(points, faces) trimesh_remesh(delaunay, 1.0, allow_boundary_split=True) points = [delaunay.vertex_coordinates(key) for key in delaunay.vertices()] faces = delaunay_from_points(points) delaunay = Mesh.from_vertices_and_faces(points, faces) voronoi = voronoi_from_delaunay(delaunay) lines = [] for u, v in voronoi.edges(): lines.append({ 'start': voronoi.vertex_coordinates(u, 'xy'), 'end' : voronoi.vertex_coordinates(v, 'xy'), 'width': 1.0 }) plotter = MeshPlotter(delaunay, figsize=(10, 6)) plotter.draw_lines(lines) plotter.draw_vertices( radius=0.075, facecolor={key: '#0092d2' for key in delaunay.vertices() if key not in delaunay.vertices_on_boundary()}) plotter.draw_edges(color='#cccccc') plotter.show() """ voronoi = mesh_dual(delaunay) for key in voronoi.vertices(): a, b, c = delaunay.face_coordinates(key) center, radius, normal = circle_from_points_xy(a, b, c) voronoi.vertex[key]['x'] = center[0] voronoi.vertex[key]['y'] = center[1] voronoi.vertex[key]['z'] = center[2] return voronoi
def editing_primal_dual(primal, default_settings, curve_constraints, point_constraints): dx = default_settings['dx'] dy = default_settings['dy'] density = default_settings['density'] pattern = default_settings['pattern'] smoothing_iterations = default_settings['smoothing iterations'] smoothing_damping = default_settings['smoothing damping'] # grammar rules + propagation scheme rules = [ 'settings', 'face_opening', 'flat_corner_2', 'flat_corner_3', 'flat_corner_33', 'split_35', 'split_35_diag', 'split_26', 'simple_split', 'double_split', 'singular_boundary_1', 'singular_boundary_2', 'clear_faces', 'move_vertices', 'stop' ] primal_guid = draw_mesh(primal) dense_primal = densification(primal, 1, custom=False) # smooth rs.EnableRedraw(False) constraints = {} for pt in point_constraints: vertex = None min_dist = -1 for vkey in dense_primal.vertices_on_boundary(): dist = distance_point_point(rs.PointCoordinates(pt), dense_primal.vertex_coordinates(vkey)) if min_dist < 0 or min_dist > dist: vertex = vkey min_dist = dist constraints[vertex] = ('point', rs.PointCoordinates(pt)) for vkey in dense_primal.vertices_on_boundary(): if vkey not in constraints: curve = None min_dist = -1 for crv in curve_constraints: vkey_guid = rs.AddPoint(dense_primal.vertex_coordinates(vkey)) t = rs.CurveClosestPoint(crv, vkey_guid) pt = rs.EvaluateCurve(crv, t) dist = distance_point_point( pt, dense_primal.vertex_coordinates(vkey)) rs.DeleteObject(vkey_guid) if min_dist < 0 or min_dist > dist: curve = crv min_dist = dist constraints[vkey] = ('curve', curve) rs.EnableRedraw(True) mesh_smooth_area(dense_primal, kmax=smoothing_iterations, damping=smoothing_damping, callback=apply_constraints, callback_args=[dense_primal, constraints]) dense_primal_guid = draw_mesh(dense_primal) rs.MoveObject(dense_primal_guid, [dx, 0, 0]) dense_dual = mesh_dual(dense_primal, Mesh) rotate_mesh(dense_dual, pi / 2) rs.EnableRedraw(False) dense_dual_guid = draw_mesh(dense_dual) rs.MoveObject(dense_dual_guid, [2 * dx, 0, 0]) rs.EnableRedraw(True) # start editing count = 1000 while count > 0: count -= 1 primal.update_default_edge_attributes() #ask for rule rule = rs.GetString('rule?', strings=rules) # exit if rule == 'stop': break elif rule == 'settings': density, pattern, dx, dy, smoothing_iterations, smoothing_damping = rs.PropertyListBox( [ 'density', 'pattern', 'dx', 'dy', 'smoothing iterations', 'smoothing damping' ], [ density, pattern, dx, dy, smoothing_iterations, smoothing_damping ], title='settings') density = float(density) dx = float(dx) dy = float(dy) smoothing_iterations = int(smoothing_iterations) smoothing_damping = float(smoothing_damping) # apply editing rule elif rule in rules: regular_vertices = list(primal.vertices()) apply_rule(primal, rule) #if rule != 'clear_faces': mesh_propagation(primal, regular_vertices) rs.DeleteObjects(primal_guid) rs.DeleteObjects(dense_primal_guid) rs.DeleteObjects(dense_dual_guid) primal_guid = draw_mesh(primal) for fkey in primal.faces(): if len(primal.face_vertices(fkey)) != 4: rs.AddPoint(primal.face_centroid(fkey)) dense_primal = densification(primal, density, custom=False) dense_primal = dense_primal.to_mesh() dense_primal = patterning(dense_primal, pattern) to_del = [ vkey for vkey in dense_primal.vertices() if len(dense_primal.vertex_neighbours(vkey)) == 0 ] for vkey in to_del: del dense_primal.vertex[vkey] # smooth rs.EnableRedraw(False) constraints = {} for pt in point_constraints: vertex = None min_dist = -1 for vkey in dense_primal.vertices_on_boundary(): dist = distance_point_point( rs.PointCoordinates(pt), dense_primal.vertex_coordinates(vkey)) if min_dist < 0 or min_dist > dist: vertex = vkey min_dist = dist constraints[vertex] = ('point', rs.PointCoordinates(pt)) for vkey in dense_primal.vertices_on_boundary(): if vkey not in constraints: curve = None min_dist = -1 for crv in curve_constraints: vkey_guid = rs.AddPoint( dense_primal.vertex_coordinates(vkey)) t = rs.CurveClosestPoint(crv, vkey_guid) pt = rs.EvaluateCurve(crv, t) dist = distance_point_point( pt, dense_primal.vertex_coordinates(vkey)) rs.DeleteObject(vkey_guid) if min_dist < 0 or min_dist > dist: curve = crv min_dist = dist constraints[vkey] = ('curve', curve) rs.EnableRedraw(True) mesh_smooth_area(dense_primal, kmax=smoothing_iterations, damping=smoothing_damping, callback=apply_constraints, callback_args=[dense_primal, constraints]) rs.EnableRedraw(False) dense_primal_guid = draw_mesh(dense_primal) rs.MoveObject(dense_primal_guid, [dx, 0, 0]) rs.EnableRedraw(True) dense_dual = mesh_dual(dense_primal, Mesh) rotate_mesh(dense_dual, pi / 2) rs.EnableRedraw(False) dense_dual_guid = draw_mesh(dense_dual) rs.MoveObject(dense_dual_guid, [2 * dx, 0, 0]) rs.EnableRedraw(True) return primal, dense_primal, dense_dual