def node_xyz(self): """dict : The view coordinates of the mesh object.""" origin = Point(0, 0, 0) stack = [] if self.scale != 1.0: S = Scale.from_factors([self.scale] * 3) stack.append(S) if self.rotation != [0, 0, 0]: R = Rotation.from_euler_angles(self.rotation) stack.append(R) if self.location != origin: if self.anchor is not None: xyz = self.network.vertex_attributes(self.anchor, 'xyz') point = Point(*xyz) T1 = Translation.from_vector(origin - point) stack.insert(0, T1) T2 = Translation.from_vector(self.location) stack.append(T2) if stack: X = reduce(mul, stack[::-1]) network = self.network.transformed(X) else: network = self.network node_xyz = { network: network.node_attributes(node, 'xyz') for node in network.nodes() } return node_xyz
def vertex_xyz(self): """dict : The view coordinates of the volmesh object.""" origin = Point(0, 0, 0) stack = [] if self.scale != 1.0: S = Scale.from_factors([self.scale] * 3) stack.append(S) if self.rotation != [0, 0, 0]: R = Rotation.from_euler_angles(self.rotation) stack.append(R) if self.location != origin: if self.anchor is not None: xyz = self.volmesh.vertex_attributes(self.anchor, 'xyz') point = Point(*xyz) T1 = Translation.from_vector(origin - point) stack.insert(0, T1) T2 = Translation.from_vector(self.location) stack.append(T2) if stack: X = reduce(mul, stack[::-1]) volmesh = self.volmesh.transformed(X) else: volmesh = self.volmesh vertex_xyz = { vertex: volmesh.vertex_attributes(vertex, 'xyz') for vertex in volmesh.vertices() } return vertex_xyz
def test_concatenated(): trans1 = [1, 2, 3] angle1 = [-2.142, 1.141, -0.142] T1 = Translation.from_vector(trans1) R1 = Rotation.from_euler_angles(angle1) M1 = T1.concatenated(R1) assert allclose(M1, T1 * R1)
def test_remeshing(): FILE = os.path.join(HERE, '../..', 'data', 'Bunny.ply') # ============================================================================== # Get the bunny and construct a mesh # ============================================================================== bunny = TriMesh.from_ply(FILE) bunny.cull_vertices() # ============================================================================== # Move the bunny to the origin and rotate it upright. # ============================================================================== vector = scale_vector(bunny.centroid, -1) T = Translation.from_vector(vector) S = Scale.from_factors([100, 100, 100]) R = Rotation.from_axis_and_angle(Vector(1, 0, 0), math.radians(90)) bunny.transform(R * S * T) # ============================================================================== # Remesh # ============================================================================== length = bunny.average_edge_length bunny.remesh(4 * length) bunny.to_mesh()
def test___eq__(): i1 = Transformation() i2 = Transformation() t = Translation.from_vector([1, 0, 0]) assert i1 == i2 assert not (i1 != i2) assert i1 != t assert not (i1 == t)
def _to_occ(self) -> BRepPrimAPI_MakeBox: xaxis = self.frame.xaxis.scaled(-0.5 * self.xsize) yaxis = self.frame.yaxis.scaled(-0.5 * self.ysize) zaxis = self.frame.zaxis.scaled(-0.5 * self.zsize) frame = self.frame.transformed( Translation.from_vector(xaxis + yaxis + zaxis)) ax2 = gp_Ax2(gp_Pnt(*frame.point), gp_Dir(*frame.zaxis), gp_Dir(*frame.xaxis)) return BRepPrimAPI_MakeBox(ax2, self.xsize, self.ysize, self.zsize)
def vertex_xyz(self): bbox = self.mesh.bounding_box() xmin, ymin, zmin = bbox[0] if not self.binary and (xmin < 0 or ymin < 0 or zmin < 0): T = Translation.from_vector([-xmin, -ymin, -zmin]) mesh = self.mesh.transformed(T) else: mesh = self.mesh return {vertex: mesh.vertex_attributes(vertex, 'xyz') for vertex in mesh.vertices()}
def vertex_xyz(self): """dict : The view coordinates of the mesh object.""" origin = Point(0, 0, 0) if self.anchor is not None: xyz = self.mesh.vertex_attributes(self.anchor, 'xyz') point = Point(* xyz) T1 = Translation.from_vector(origin - point) S = Scale.from_factors([self.scale] * 3) R = Rotation.from_euler_angles(self.rotation) T2 = Translation.from_vector(self.location) X = T2 * R * S * T1 else: S = Scale.from_factors([self.scale] * 3) R = Rotation.from_euler_angles(self.rotation) T = Translation.from_vector(self.location) X = T * R * S mesh = self.mesh.transformed(X) vertex_xyz = {vertex: mesh.vertex_attributes(vertex, 'xy') + [0.0] for vertex in mesh.vertices()} return vertex_xyz
def test_basis_vectors(): trans1 = [1, 2, 3] angle1 = [-2.142, 1.141, -0.142] scale1 = [0.123, 2, 0.5] T1 = Translation.from_vector(trans1) R1 = Rotation.from_euler_angles(angle1) S1 = Scale.from_factors(scale1) M = (T1 * R1) * S1 x, y = M.basis_vectors assert allclose(x, Vector(0.41249169135312663, -0.05897071585157175, -0.9090506362335324)) assert allclose(y, Vector(-0.8335562904208867, -0.4269749553355485, -0.35053715668381935))
def hexagongrid(): polygon = Polygon.from_sides_and_radius_xy(6, 1) vertices = polygon.points vertices.append(polygon.centroid) x, y, z = zip(*vertices) xmin = min(x) xmax = max(x) ymin = min(y) ymax = max(y) faces = [[0, 1, 6], [1, 2, 6], [2, 3, 6], [3, 4, 6], [4, 5, 6], [5, 0, 6]] mesh = Mesh.from_vertices_and_faces(vertices, faces) meshes = [] for i in range(2): T = Translation.from_vector([i * (xmax - xmin), 0, 0]) meshes.append(mesh.transformed(T)) for i in range(2): T = Translation.from_vector([i * (xmax - xmin), ymax - ymin, 0]) meshes.append(mesh.transformed(T)) mesh = meshes_join_and_weld(meshes) return mesh
def test_decomposed(): trans1 = [1, 2, 3] angle1 = [-2.142, 1.141, -0.142] scale1 = [0.123, 2, 0.5] T1 = Translation.from_vector(trans1) R1 = Rotation.from_euler_angles(angle1) S1 = Scale.from_factors(scale1) M = (T1 * R1) * S1 Sc, Sh, R, T, P = M.decomposed() assert S1 == Sc assert R1 == R assert T1 == T
def shift(block): """Shift a block along the X or Y axis by a randomly chosen amount. Parameters ---------- block : compas_assembly.datastructures.Block """ scale = choice([+0.01, -0.01, +0.05, -0.05, +0.1, -0.1]) axis = choice([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]) vector = scale_vector(axis, scale) T = Translation.from_vector(vector) block.transform(T)
def node_xyz(self): """dict : The view coordinates of the mesh object.""" origin = Point(0, 0, 0) if self.anchor is not None: xyz = self.network.node_attributes(self.anchor, 'xyz') point = Point(*xyz) T1 = Translation.from_vector(origin - point) S = Scale.from_factors([self.scale] * 3) R = Rotation.from_euler_angles(self.rotation) T2 = Translation.from_vector(self.location) X = T2 * R * S * T1 else: S = Scale.from_factors([self.scale] * 3) R = Rotation.from_euler_angles(self.rotation) T = Translation.from_vector(self.location) X = T * R * S network = self.network.transformed(X) node_xyz = { network: network.node_attributes(node, 'xyz') for node in network.nodes() } return node_xyz
def decomposed(self): """Decompose the `Transformation` into its components. Returns ------- :class:`compas.geometry.Scale` The scale component of the current transformation. :class:`compas.geometry.Shear` The shear component of the current transformation. :class:`compas.geometry.Rotation` The rotation component of the current transformation. :class:`compas.geometry.Translation` The translation component of the current transformation. :class:`compas.geometry.Projection` The projection component of the current transformation. Examples -------- >>> from compas.geometry import Scale, Translation, Rotation >>> trans1 = [1, 2, 3] >>> angle1 = [-2.142, 1.141, -0.142] >>> scale1 = [0.123, 2, 0.5] >>> T1 = Translation.from_vector(trans1) >>> R1 = Rotation.from_euler_angles(angle1) >>> S1 = Scale.from_factors(scale1) >>> M = T1 * R1 * S1 >>> S, H, R, T, P = M.decomposed() >>> S1 == S True >>> R1 == R True >>> T1 == T True """ from compas.geometry import Scale # noqa: F811 from compas.geometry import Shear from compas.geometry import Rotation # noqa: F811 from compas.geometry import Translation # noqa: F811 from compas.geometry import Projection s, h, a, t, p = decompose_matrix(self.matrix) S = Scale.from_factors(s) H = Shear.from_entries(h) R = Rotation.from_euler_angles(a, static=True, axes='xyz') T = Translation.from_vector(t) P = Projection.from_entries(p) return S, H, R, T, P
def RunCommand(is_interactive): if '3GS' not in sc.sticky: compas_rhino.display_message('3GS has not been initialised yet.') return scene = sc.sticky['3GS']['scene'] # get ForceVolMeshObject from scene objects = scene.find_by_name('force') if not objects: compas_rhino.display_message("There is no force diagram in the scene.") return force = objects[0] # make FormNetwork form = volmesh_dual_network(force.diagram, cls=FormNetwork) # set dual/primal form.dual = force.diagram force.diagram.primal = form # add FormNetworkObject translation = relocate_formdiagram(force.diagram, form) form.transform(Translation.from_vector(translation)) form.update_angle_deviations() scene.add_formnetwork(form, name='form', layer='3GS::FormDiagram') # form objects = scene.find_by_name('form') form = objects[0] force.check_eq() form.check_eq() # update scene.update() scene.save() print('Primal diagram successfully created.')
def from_cylinder(cls, cylinder: compas.geometry.Cylinder) -> 'BRep': """Construct a BRep from a COMPAS cylinder. Parameters ---------- cylinder : :class:`~compas.geometry.Cylinder` Returns ------- :class:`~compas_occ.brep.BRep` """ plane = cylinder.circle.plane height = cylinder.height radius = cylinder.circle.radius frame = Frame.from_plane(plane) frame.transform(Translation.from_vector(frame.zaxis * (-0.5 * height))) ax2 = gp_Ax2(gp_Pnt(*frame.point), gp_Dir(*frame.zaxis), gp_Dir(*frame.xaxis)) brep = BRep() brep.shape = BRepPrimAPI_MakeCylinder(ax2, radius, height).Shape() return brep
def calculate_prismatic_transformation(self, position): """Returns a transformation of a prismatic joint. A prismatic joint slides along the axis and has a limited range specified by the upper and lower limits. Parameters ---------- position : :obj:`float` Translation movement in meters. Returns ------- :class:`Translation` Transformation of type translation for the prismatic joint. """ if not self.limit: raise ValueError('Prismatic joints are required to define a limit') position = max(min(position, self.limit.upper), self.limit.lower) return Translation.from_vector(self.axis.vector * position)
def RunCommand(is_interactive): scene = get_scene() if not scene: return form = scene.get("form")[0] if not form: print("There is no FormDiagram in the scene.") return force = scene.get("force")[0] if force: # recreating the force diagram does not work return force = ForceDiagram.from_formdiagram(form.datastructure) force.default_edge_attributes.update({'lmin': 0.1}) bbox_form = form.datastructure.bounding_box_xy() bbox_force = force.bounding_box_xy() xmin_form, xmax_form = bbox_form[0][0], bbox_form[1][0] xmin_force, _ = bbox_force[0][0], bbox_force[1][0] ymin_form, ymax_form = bbox_form[0][1], bbox_form[3][1] ymin_force, ymax_force = bbox_force[0][1], bbox_force[3][1] y_form = ymin_form + 0.5 * (ymax_form - ymin_form) y_force = ymin_force + 0.5 * (ymax_force - ymin_force) dx = 1.3 * (xmax_form - xmin_form) + (xmin_form - xmin_force) dy = y_form - y_force force.transform(Translation.from_vector([dx, dy, 0])) force.update_angle_deviations() scene.add(force, name='force') scene.update() print('ForceDiagram object successfully created.')
def from_box(cls, box: compas.geometry.Box) -> 'BRep': """Construct a BRep from a COMPAS box. Parameters ---------- box : :class:`~compas.geometry.Box` Returns ------- :class:`~compas_occ.brep.BRep` """ xaxis = box.frame.xaxis.scaled(-0.5 * box.xsize) yaxis = box.frame.yaxis.scaled(-0.5 * box.ysize) zaxis = box.frame.zaxis.scaled(-0.5 * box.zsize) frame = box.frame.transformed( Translation.from_vector(xaxis + yaxis + zaxis)) ax2 = gp_Ax2(gp_Pnt(*frame.point), gp_Dir(*frame.zaxis), gp_Dir(*frame.xaxis)) brep = BRep() brep.shape = BRepPrimAPI_MakeBox(ax2, box.xsize, box.ysize, box.zsize).Shape() return brep
from compas.datastructures import Mesh from compas.geometry import Translation, Scale, Point tetra = Mesh.from_polyhedron(4) hexa = Mesh.from_polyhedron(6) octa = Mesh.from_polyhedron(8) dodeca = Mesh.from_polyhedron(12) icosa = Mesh.from_polyhedron(20) o = Point(0, 0, 0) T = Translation.from_vector([2.5, 0, 0]) p = Point(* tetra.vertex_coordinates(tetra.get_any_vertex())) s = 1 / (p - o).length S = Scale.from_factors([s, s, s]) tetra.transform(S) tetra.dual() p = Point(* hexa.vertex_coordinates(hexa.get_any_vertex())) s = 1 / (p - o).length S = Scale.from_factors([s, s, s]) hexa.transform(T * S) hexa.dual() p = Point(* octa.vertex_coordinates(octa.get_any_vertex())) s = 1 / (p - o).length S = Scale.from_factors([s, s, s])
from math import radians from compas.geometry import Pointcloud from compas.geometry import Rotation from compas.geometry import Translation from compas.geometry import Frame from compas.geometry import Point, Vector, Line from compas.geometry import closest_point_on_line from compas.rpc import Proxy import compas_rhino from compas_rhino.artists import PointArtist from compas_rhino.artists import FrameArtist from compas_rhino.artists import LineArtist numerical = Proxy('compas.numerical') pcl = Pointcloud.from_bounds(10, 5, 3, 100) Rz = Rotation.from_axis_and_angle([0.0, 0.0, 1.0], radians(60)) Ry = Rotation.from_axis_and_angle([0.0, 1.0, 0.0], radians(20)) Rx = Rotation.from_axis_and_angle([1.0, 0.0, 0.0], radians(10)) T = Translation.from_vector([2.0, 5.0, 8.0]) pcl.transform(T * Rz * Ry * Rx) PointArtist.draw_collection(pcl, layer="ITA20::PCL", clear=True)
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) plotter.redraw(pause=0.01) plotter.zoom_extents() plotter.show()
# ============================================================================== # Compute the boolean difference # ============================================================================== V, F = boolean_difference(A, B) difference = Mesh.from_vertices_and_faces(V, F) # ============================================================================== # Compute the boolean intersection # ============================================================================== V, F = boolean_intersection(A, B) intersection = Mesh.from_vertices_and_faces(V, F) # ============================================================================== # Visualize # ============================================================================== viewer = App() viewer.add(box, facecolor=(1, 0, 0), opacity=0.5) viewer.add(sphere, facecolor=(0, 0, 1), opacity=0.5) viewer.add(union.transformed(Translation.from_vector([1 * 1.5 * width, 0, 0])), facecolor=(1, 0, 1)) viewer.add(difference.transformed(Translation.from_vector([2 * 1.5 * width, 0, 0])), show_faces=False, show_edges=True, linecolor=(1, 0, 0)) viewer.add(intersection.transformed(Translation.from_vector([2 * 1.5 * width, 0, 0])), facecolor=(0, 1, 0)) viewer.run()
def test_translation(): trans1 = [1, 2, 3] T1 = Translation.from_vector(trans1) assert T1.translation_vector == trans1
# Get Bunny # ============================================================================== before = Mesh.from_ply(compas.get_bunny()) # ============================================================================== # Clean up # ============================================================================== before.cull_vertices() # ============================================================================== # Transform # ============================================================================== T = Translation.from_vector(Point(0, 0, 0) - Point(*before.centroid())) S = Scale.from_factors([100, 100, 100]) R = Rotation.from_axis_and_angle([1, 0, 0], radians(90)) before.transform(R * S * T) # ============================================================================== # Remesh # ============================================================================== L = sum(before.edge_length(*edge) for edge in before.edges()) / before.number_of_edges() V, F = trimesh_remesh(before.to_vertices_and_faces(), 3 * L) after = Mesh.from_vertices_and_faces(V, F)
Point(2, 2, 2), Point(3, 2, 0), Point(4, 2, 0) ], [ Point(0, 3, 0), Point(1, 3, 0), Point(2, 3, 0), Point(3, 3, 0), Point(4, 3, 0) ], ] surface = OCCNurbsSurface.from_points(points=points) T = Translation.from_vector([0, -1.5, 0]) R = Rotation.from_axis_and_angle([0, 0, 1], radians(45)) surface.transform(R * T) # ============================================================================== # AABB # ============================================================================== box = surface.aabb() # ============================================================================== # Visualisation # ============================================================================== view = App()
import time from compas.datastructures import Mesh from compas.geometry import Box, Translation from compas_fab.backends import RosClient from compas_fab.robots import CollisionMesh from compas_fab.robots import PlanningScene with RosClient('localhost') as client: robot = client.load_robot() scene = PlanningScene(robot) brick = Box.from_width_height_depth(0.016, 0.012, 0.031) brick.transform(Translation.from_vector([0, 0, brick.zsize / 2.])) for i in range(5): mesh = Mesh.from_shape(brick) cm = CollisionMesh(mesh, 'brick_wall') cm.frame.point.y += 0.5 cm.frame.point.z += brick.zsize * i scene.append_collision_mesh(cm) # sleep a bit before terminating the client time.sleep(1)
def move(frame): print(frame) for a, b in pairwise(pointcloud): vector = b - a a.transform(Translation.from_vector(vector * 0.1))
def T(): return Translation.from_vector([1, 2, 3])
# ============================================================================== assembly = Assembly() # default block box = Box.from_width_height_depth(W, H, D) brick = Block.from_shape(box) # make all blocks # place each block on top of previous # shift block randomly in XY plane for i in range(N): block = brick.copy() block.transform(Translation.from_vector([0, 0, 0.5 * H + i * H])) shift(block) assembly.add_block(block) # mark the bottom block as support assembly.node_attribute(0, 'is_support', True) # ============================================================================== # Export # ============================================================================== assembly.to_json(FILE) # ============================================================================== # Visualize