def __and__(self, other): """Compute the boolean intersection using the "&" operator of this shape and another. Parameters ---------- other : :class:`compas.geometry.Shape` The solid to intersect with. Returns ------- :class:`compas.geometry.Polyhedron` The resulting solid. Examples -------- >>> from compas.geometry import Box, Sphere >>> A = Box.from_width_height_depth(2, 2, 2) >>> B = Sphere([1, 1, 1], 1.0) >>> C = A & B # doctest: +SKIP """ from compas.geometry import boolean_intersection_mesh_mesh from compas.geometry import Polyhedron A = self.to_vertices_and_faces(triangulated=True) B = other.to_vertices_and_faces(triangulated=True) V, F = boolean_intersection_mesh_mesh(A, B) return Polyhedron(V, F)
def __sub__(self, other): """Compute the boolean difference using the "-" operator of this shape and another. Parameters ---------- other : :class:`Solid` The solid to subtract. Returns ------- :class:`Solid` The resulting solid. Examples -------- >>> from compas.geometry import Box, Sphere >>> A = Box.from_width_height_depth(2, 2, 2) >>> B = Sphere([1, 1, 1], 1.0) >>> C = A - B """ from compas.geometry import boolean_difference_mesh_mesh from compas.geometry import Polyhedron A = self.to_vertices_and_faces(triangulated=True) B = other.to_vertices_and_faces(triangulated=True) V, F = boolean_difference_mesh_mesh(A, B) return Polyhedron(V, F)
def from_polyhedron(cls, f): """Construct a mesh from a platonic solid. Parameters ---------- f : int The number of faces. Should be one of ``4, 6, 8, 12, 20``. Returns ------- Mesh A mesh object. Examples -------- >>> """ p = Polyhedron(f) return cls.from_vertices_and_faces(p.vertices, p.faces)
def mesh_to_tets(self) -> List[Polyhedron]: """Convert the model mesh to a COMPAS mesh data structure.""" nodes = self.mesh.get_nodes() node_tags = nodes[0] node_coords = nodes[1].reshape((-1, 3), order='C') xyz = {} for tag, coords in zip(node_tags, node_coords): xyz[int(tag)] = coords elements = self.mesh.get_elements() tets = [] for etype, etags, ntags in zip(*elements): if etype == 4: # tetrahedron for i, etag in enumerate(etags): n = self.mesh.get_element_properties(etype)[3] vertices = [xyz[index] for index in ntags[i * n: i * n + n]] faces = [ [0, 1, 2], [0, 2, 3], [1, 3, 2], [0, 3, 1]] tets.append(Polyhedron(vertices, faces)) return tets
import random from compas.geometry import Plane from compas.geometry import Circle from compas.geometry import Cone from compas.geometry import Polyhedron from compas_viewers.objectviewer import Arrow from compas_viewers.objectviewer import ObjectViewer viewer = ObjectViewer() plane = Plane([2, 0, 0], [0, 0, 1]) circle = Circle(plane, 0.5) cone = Cone(circle, 1) viewer.add(cone) polyhedron = Polyhedron(4) viewer.add(polyhedron) arrow = Arrow([-2, 0, 0], [0, 1, 1]) viewer.add(arrow) viewer.show()
def test_centroid_points_fails_when_input_is_not_list_of_lists(points): with pytest.raises(TypeError): centroid_points(points) @pytest.mark.parametrize(("points"), [ [[0.0, 0.0, 0.0], [0.0, 0.0]], [[0.0, 0.0]], ]) def test_centroid_points_fails_when_input_is_not_complete_points(points): with pytest.raises(ValueError): centroid_points(points) @pytest.mark.parametrize(("polyhedron", "centroid"), [ (Polyhedron(6), [0.0, 0.0, 0.0]), ]) def test_centroid_polyhedron(polyhedron, centroid): x, y, z = centroid assert allclose(centroid_polyhedron(polyhedron), (x, y, z)) # ============================================================================== # size # ============================================================================== @pytest.mark.parametrize(("polyhedron", "volume"), [(Polyhedron(6), None)]) def test_volume_polyhedron(polyhedron, volume): if volume is None: L = length_vector(