def cutting_plane(mesh, ry=10, rz=-50): plane = Plane(mesh.centroid(), Vector(1, 0, 0)) Ry = Rotation.from_axis_and_angle(Vector(0, 1, 0), radians(ry), plane.point) Rz = Rotation.from_axis_and_angle(Vector(0, 0, 1), radians(rz), plane.point) plane.transform(Rz * Ry) return plane
def to_circle(self) -> compas.geometry.Circle: """Convert the edge geometry to a circle. Returns ------- :class:`~compas.geometry.Circle` A COMPAS circle. Raises ------ ValueError If the underlying geometry is not a circle. """ if not self.is_circle: raise ValueError( f'The underlying geometry is not a circle: {self.type}') curve = self.adaptor.Curve() circle = curve.Circle() location = circle.Location() direction = circle.Axis().Direction() radius = circle.Radius() point = location.X(), location.Y(), location.Z() normal = direction.X(), direction.Y(), direction.Z() return Circle(Plane(point, normal), radius)
def to_ellipse(self) -> compas.geometry.Ellipse: """Convert the edge geometry to an ellipse. Returns ------- :class:`~compas.geometry.Ellipse` A COMPAS ellipse. Raises ------ ValueError If the underlying geometry is not an ellipse. """ if not self.is_ellipse: raise ValueError( f'The underlying geometry is not an ellipse: {self.type}') curve = self.adaptor.Curve() ellipse = curve.Ellipse() location = ellipse.Location() direction = ellipse.Axis().Direction() major = ellipse.MajorRadius() minor = ellipse.MinorRadius() point = location.X(), location.Y(), location.Z() normal = direction.X(), direction.Y(), direction.Z() return Ellipse(Plane(point, normal), major, minor)
def from_planes(cls, planes): """Construct a polyhedron from intersecting planes. Parameters ---------- planes : list of :class:`compas.geometry.Plane` or list of (point, normal) Returns ------- :class:`compas.geometry.Polyhedron` Examples -------- >>> from compas.geometry import Plane >>> left = Plane([-1, 0, 0], [-1, 0, 0]) >>> right = Plane([+1, 0, 0], [+1, 0, 0]) >>> top = Plane([0, 0, +1], [0, 0, +1]) >>> bottom = Plane([0, 0, -1], [0, 0, -1]) >>> front = Plane([0, -1, 0], [0, -1, 0]) >>> back = Plane([0, +1, 0], [0, +1, 0]) >>> p = Polyhedron.from_planes([left, right, top, bottom, front, back]) """ from compas.geometry import Plane from compas.geometry import centroid_points planes = [Plane(point, normal) for point, normal in planes] interior = centroid_points([plane.point for plane in planes]) return cls.from_halfspaces([plane.abcd for plane in planes], interior)
def generate_paths(self): """Generates the planar slicing paths.""" z = [ self.mesh.vertex_attribute(key, 'z') for key in self.mesh.vertices() ] min_z, max_z = min(z), max(z) d = abs(min_z - max_z) no_of_layers = int(d / self.layer_height) + 1 normal = Vector(0, 0, 1) planes = [ Plane(Point(0, 0, min_z + i * self.layer_height), normal) for i in range(no_of_layers) ] # planes.pop(0) # remove planes that are on the print platform if self.slicer_type == "default": logger.info('') logger.info("Planar slicing using default function ...") self.layers = compas_slicer.slicers.create_planar_paths( self.mesh, planes) elif self.slicer_type == "cgal": logger.info('') logger.info("Planar slicing using CGAL ...") self.layers = compas_slicer.slicers.create_planar_paths_cgal( self.mesh, planes) else: raise NameError("Invalid slicing type : " + self.slicer_type)
def plot(self): """Visualize the current map with the plotter. Returns ------- None """ from compas_plotters.plotter import Plotter from compas.geometry import Pointcloud from compas.geometry import Plane, Circle, Polygon plotter = Plotter(figsize=(16, 12)) w = 16 h = 10 n = len(self.colors) d = w / n cloud = Pointcloud.from_bounds(w, h, 0, n) white = Color.white() for i, color in enumerate(self.colors): c = Circle(Plane(cloud[i], [0, 0, 1]), 0.1) p = Polygon([[i * d, -2, 0], [(i + 1) * d, -2, 0], [(i + 1) * d, -1, 0], [i * d, -1, 0]]) plotter.add(c, facecolor=color, edgecolor=white, linewidth=0.5) plotter.add(p, facecolor=color, edgecolor=color) plotter.zoom_extents() plotter.show()
def from_data(cls, data): """Construct a cone from its data representation. Parameters ---------- data : :obj:`dict` The data dictionary. Returns ------- Cone The constructed cone. Examples -------- >>> from compas.geometry import Cone >>> from compas.geometry import Circle >>> from compas.geometry import Plane >>> data = {'circle': Circle(Plane.worldXY(), 5).data, 'height': 7.} >>> cone = Cone.from_data(data) """ cone = cls(Circle(Plane.worldXY(), 1), 1) cone.data = data return cone
def get_Beam_interecting_Planes(self, BeamsRef, flag=0, face_id=None): """Computes the interecting planes of a given Beam ---------- """ if flag == 0: intersecting_planes = [] frame = BeamsRef.get_face_frame(4) intersecting_planes.append(Plane(frame.point, frame.normal)) frame = BeamsRef.get_face_frame(3) intersecting_planes.append(Plane(frame.point, frame.normal)) return intersecting_planes elif flag == 1: frame = BeamsRef.get_face_frame(self.get_start_face(face_id)) start_frame = Plane(frame.point, frame.normal) return start_frame else: pass
def get_distance(self, point): """ single point distance function """ plane = Plane(self.frame.point, self.frame.normal) plndst = distance_point_plane_signed(point, plane) pr = rotate_points([point], plndst / 10, self.frame.normal, self.frame.point) d = self.obj.get_distance(pr[0]) return d
def offset_polygon_xy(points, dist, planarize=False): if len(points) < 3: return None frame = Frame.from_plane( Plane.from_three_points(points[0], points[1], points[2])) xform = Transformation.from_frame_to_frame(frame, Frame.worldXY()) if planarize: points = [point_on_plane(point, frame) for point in points] points = transform_points(points, xform) points = offset_polygon(points, dist) points = transform_points(points, xform.inverse()) return points
def plane_to_compas(plane): """Convert a Rhino plane to a COMPAS plane. Parameters ---------- plane : :class:`Rhino.Geometry.Plane` Returns ------- :class:`compas.geometry.Plane` """ return Plane(point_to_compas(plane.Origin), vector_to_compas(plane.Normal))
def tet_from_points(tet_end_points): assert len(tet_end_points) == 4, 'input points must be four!' ids = frozenset([0,1,2,3]) faces = [] if is_coplanar(tet_end_points): return None, None for face in combinations(ids, 3): left_id, = ids - set(face) if is_point_infront_plane(tet_end_points[left_id], Plane.from_three_points(*[tet_end_points[i] for i in face])): face = [face[0], face[2], face[1]] faces.append(list(face) + [left_id]) return tet_end_points, faces
def get_planes_vertices(self): if len(self.pts_list) > 0: for i, vertex in enumerate(self.pts_list): normal = self.normals[i] binorm = self.binorms[i] if i != 0: if self.normals[i-1].angle(normal) > 0.5*math.pi and \ self.binorms[i-1].angle(binorm) > 0.5*math.pi: normal = normal * (-1) binorm = binorm * (-1) plane = Plane.from_point_and_two_vectors( vertex, normal, binorm) self.planes.append(plane)
def points_on_sphere_generator(sphere): for theta_deg in range(0, 360, 20): for phi_deg in range(0, 90, 10): theta = math.radians(theta_deg) phi = math.radians(phi_deg) x = sphere.point.x + sphere.radius * math.cos(theta) * math.sin(phi) y = sphere.point.y + sphere.radius * math.sin(theta) * math.sin(phi) z = sphere.point.z + sphere.radius * math.cos(phi) point = Point(x, y, z) axis = sphere.point - point plane = Plane((x, y, z), axis) f = Frame.from_plane(plane) # for UR5 is zaxis the xaxis yield Frame(f.point, f.zaxis, f.yaxis)
def cone_to_compas(cone): """Convert a Rhino cone to a COMPAS cone. Parameters ---------- cone: :class:`Rhino.Geometry.Cone` Returns ------- :class:`compas.geometry.Cone` """ plane = Plane(cone.BasePoint, vector_to_compas(cone.Plane.Normal).inverted()) return Cone(Circle(plane, cone.Radius), cone.Height)
def __init__(self, scene, arrow, **kwargs): super(ArrowObject, self).__init__(scene, arrow, **kwargs) length = np.linalg.norm(arrow.direction) plane = Plane(arrow.point + arrow.direction * 0.7, arrow.direction) circle = Circle(plane, length * 0.15) cone = Cone(circle, length * 0.3) line = Line(Point(*arrow.point), Point(*(arrow.point + arrow.direction * 0.7))) self.view = ArrowView(arrow, ConeObject(None, cone, 3), LineObject(None, line))
def __iter__(self): if self.start_vector: # correct start_vector self.start_vector = (self.axis.cross( self.start_vector.unitized())).cross(self.axis) for alpha in arange(0, 2 * math.pi, self.angle_step): R = Rotation.from_axis_and_angle(self.axis, alpha) yield self.start_vector.transformed(R) else: f = Frame.from_plane(Plane((0, 0, 0), self.axis)) for alpha in arange(0, 2 * math.pi, self.angle_step): x = math.cos(alpha) y = math.sin(alpha) yield f.to_world_coordinates(Vector(x, y, 0))
def get_planes_on_each_vertex(Skeleton): vTangents, vNormals, vBinormals = get_vectors_on_vertices(Skeleton) vIndices, eIndices = get_indices_of_vertices_and_edges(Skeleton) vertices = get_vertices_from_Skeleton(Skeleton) planes = [] for vIndex in vIndices: vtangent = vTangents[vIndex] vnormal = vNormals[vIndex] vbinorm = vBinormals[vIndex] vertex = vertices[vIndex] plane_vertex = Plane.from_point_and_two_vectors( vertex, vbinorm, vnormal) planes.append(plane_vertex) return planes
def __iter__(self): yield self.axis alphas = arange(self.max_alpha / self.step, self.max_alpha + self.max_alpha / self.step, self.max_alpha / self.step) radii = [math.sin(alpha) for alpha in alphas] x, y = math.cos(alphas[0]), math.sin(alphas[0]) d = math.sqrt((1 - x)**2 + y**2) # get any vector normal to axis axis2 = Frame.from_plane(Plane((0, 0, 0), self.axis)).xaxis for alpha, r in zip(alphas, radii): R1 = Rotation.from_axis_and_angle(axis2, alpha) amount = int(round(2 * math.pi * r / d)) betas = arange(0, 2 * math.pi, 2 * math.pi / amount) for beta in betas: R2 = Rotation.from_axis_and_angle(self.axis, beta) yield self.axis.transformed(R2 * R1)
def test_slicer(): FILE = os.path.join(HERE, '../..', 'data', '3DBenchy.stl') # ============================================================================== # Get benchy and construct a mesh # ============================================================================== benchy = Mesh.from_stl(FILE) # ============================================================================== # Create planes # ============================================================================== # replace by planes along a curve bbox = benchy.bounding_box() x, y, z = zip(*bbox) zmin, zmax = min(z), max(z) normal = Vector(0, 0, 1) planes = [] for i in np.linspace(zmin, zmax, 50): plane = Plane(Point(0, 0, i), normal) planes.append(plane) # ============================================================================== # Slice # ============================================================================== M = benchy.to_vertices_and_faces() pointsets = slice_mesh(M, planes) # ============================================================================== # Process output # ============================================================================== polylines = [] for points in pointsets: points = [Point(*point) for point in points] polyline = Polyline(points) polylines.append(polyline)
def data(self): """Returns the data dictionary that represents the torus. Returns ------- dict The torus data. Examples -------- >>> from compas.geometry import Plane >>> from compas.geometry import Torus >>> torus = Torus(Plane.worldXY(), 5, 2) >>> sdict = {'plane': Plane.worldXY().data, 'radius_axis': 5., 'radius_pipe': 2.} >>> sdict == torus.data True """ return {'plane': Plane.worldXY().to_data(), 'radius_axis': self.radius_axis, 'radius_pipe': self.radius_pipe}
def from_data(cls, data): """Construct a torus from its data representation. Parameters ---------- data : :obj:`dict` The data dictionary. Returns ------- Torus The constructed torus. Examples -------- >>> from compas.geometry import Torus >>> data = {'plane': Plane.worldXY().data, 'radius_axis': 4., 'radius_pipe': 1.} >>> torus = Torus.from_data(data) """ torus = cls(Plane.worldXY(), 1, 1) torus.data = data return torus
def from_data(cls, data): """Construct a torus from its data representation. Parameters ---------- data : dict The data dictionary. Returns ------- :class:`compas.geometry.Torus` The constructed torus. Examples -------- >>> from compas.geometry import Torus >>> data = {'plane': Plane.worldXY().data, 'radius_axis': 4., 'radius_pipe': 1.} >>> torus = Torus.from_data(data) """ torus = cls(Plane.from_data(data['plane']), data['radius_axis'], data['radius_pipe']) return torus
def _get_geometry_and_origin(primitive): shape = None origin = None if isinstance(primitive, compas.geometry.Box): shape = Box.from_geometry(primitive) origin = Origin(*primitive.frame) if isinstance(primitive, compas.geometry.Capsule): shape = Capsule.from_geometry(primitive) point = primitive.line.midpoint normal = primitive.line.vector plane = Plane(point, normal) origin = Origin.from_plane(plane) if isinstance(primitive, compas.geometry.Cylinder): shape = Cylinder.from_geometry(primitive) origin = Origin.from_plane(primitive.circle.plane) if isinstance(primitive, compas.geometry.Sphere): shape = Sphere.from_geometry(primitive) origin = Origin(primitive.point, [1, 0, 0], [0, 1, 0]) if not shape: raise Exception('Unrecognized primitive type {}'.format( primitive.__class__)) geometry = Geometry(shape) return geometry, origin
def face_plane(self,plane_id): """Computes the plane of each face of a beam ---------- plane_id: (int) ID of plane Return: ------ compas plane """ origin_frame = self.frame.copy() if plane_id == 0: plane = Plane(origin_frame.point, origin_frame.xaxis) elif plane_id == 1: face_1 = self.face_frame(1).copy() plane = Plane(face_1.point, face_1.yaxis) elif plane_id == 2: face_2 = self.face_frame(2).copy() plane = Plane(face_2.point, face_2.yaxis) elif plane_id == 3: face_3 = self.face_frame(3).copy() plane = Plane(face_3.point, face_3.yaxis) elif plane_id == 4: face_4 = self.face_frame(4).copy() plane = Plane(face_4.point, face_4.yaxis) elif plane_id == 5: #horizontal plane that at the center of the beam center_point = self.center_point_at_beam_start() plane = Plane(center_point, self.frame.normal) elif plane_id == 6: #vertical plane that at the center of the beam center_point = self.center_point_at_beam_start() plane = Plane(center_point, self.frame.yaxis) return plane
from compas.geometry import Vector, Point, Plane from compas.geometry import Polyline from compas.geometry import Circle from compas_occ.geometry import OCCNurbsCurve from compas_view2.app import App circle = Circle(Plane(Point(0, 0, 0), Vector(0, 0, 1)), 1.0) curve = OCCNurbsCurve.from_circle(circle) # ============================================================================== # Visualisation # ============================================================================== view = App() view.add(Polyline(curve.locus()), linewidth=3) view.add(Polyline(curve.points), show_points=True, pointsize=20, pointcolor=(1, 0, 0), linewidth=1, linecolor=(0.3, 0.3, 0.3)) view.run()
from numpy import array from scipy.spatial import HalfspaceIntersection from scipy.spatial import ConvexHull from itertools import combinations from compas.geometry import Plane, Vector from compas.datastructures import Mesh from compas_view2.app import App left = Plane([-1, 0, 0], [-1, 0, 0]) right = Plane([+1, 0, 0], [+1, 0, 0]) top = Plane([0, 0, +1], [0, 0, +1]) bottom = Plane([0, 0, -1], [0, 0, -1]) front = Plane([0, -1, 0], [0, -1, 0]) back = Plane([0, +1, 0], [0, +1, 0]) halfspaces = array( [left.abcd, right.abcd, top.abcd, bottom.abcd, front.abcd, back.abcd], dtype=float) interior = array([0, 0, 0], dtype=float) hsi = HalfspaceIntersection(halfspaces, interior) hull = ConvexHull(hsi.intersections) mesh = Mesh.from_vertices_and_faces( [hsi.intersections[i] for i in hull.vertices], hull.simplices) mesh.unify_cycles()
descdent_tree[u][v] = {'jp': None, 'lp': None} descdent_tree[v][u] = {'jp': None, 'lp': None} current_key = convex_hull_mesh.number_of_vertices() for fkey in convex_hull_mesh.faces(): f_centroid = convex_hull_mesh.face_centroid(fkey) vec = Vector.from_start_end(pt_center, f_centroid) # if the branches has a 'convex' corner, # flip the vec to the corresponding face. f_normal = convex_hull_mesh.face_normal(fkey) angle = angle_vectors(f_normal, vec, False) if angle > math.pi * 0.5: # vec.scale(-1) pln = Plane(pt_center, f_normal) pt_mirror = mirror_point_plane(f_centroid, pln) vec = Vector.from_start_end(pt_center, pt_mirror) # angle = math.pi - angle vec.unitize() # dist = joint_width / math.cos(angle) # vec.scale(dist) vec.scale(joint_width) pt = add_vectors(pt_center, vec) face = convex_hull_mesh.face[fkey] v_keys = face + [face[0]] for u, v in pairwise(v_keys):
# ============================================================================== # Main # ============================================================================== if __name__ == '__main__': from compas.geometry import Ellipse from compas.geometry import Point from compas.geometry import Plane from compas.geometry import Vector from compas.geometry import Translation from compas_plotters import GeometryPlotter plotter = GeometryPlotter() plane = Plane(Point(0, 0, 0), Vector(0, 0, 1)) a = Ellipse(plane, 5.0, 3.0) b = Ellipse(plane, 2.0, 1.0) c = Ellipse(plane, 3.0, 1.0) T = Translation.from_vector([0.1, 0.0, 0.0]) plotter.add(a, edgecolor='#ff0000', fill=False) plotter.add(b, edgecolor='#00ff00', fill=False) plotter.add(c, edgecolor='#0000ff', fill=False) plotter.pause(1.0) for i in range(100): a.transform(T)
from compas.geometry import Frame from compas.geometry import Plane from compas.geometry import Vector a = Vector(1, 0, 0) b = Vector.from_start_end([1, 0, 0], [2, 0, 0]) assert a == b a = Plane([0, 0, 0], [0, 0, 1]) b = Plane.from_three_points([0, 0, 0], [1, 0, 0], [0, 1, 0]) assert a == b a = Frame([0, 0, 0], [3, 0, 0], [0, 2, 0]) b = Frame.from_points([0, 0, 0], [5, 0, 0], [1, 2, 0]) assert a == b