Пример #1
0
def test_scale():
    S = Scale.from_factors([1, 2, 3])
    assert S.matrix == [[1.0, 0.0, 0.0, 0.0], [0.0, 2.0, 0.0, 0.0],
                        [0.0, 0.0, 3.0, 0.0], [0.0, 0.0, 0.0, 1.0]]

    S = Scale.from_factors([2.] * 3, Frame((2, 5, 0), (1, 0, 0), (0, 1, 0)))
    assert S.matrix == [[2.0, 0.0, 0.0, -2.0], [0.0, 2.0, 0.0, -5.0],
                        [0.0, 0.0, 2.0, 0.0], [0.0, 0.0, 0.0, 1.0]]
Пример #2
0
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()
Пример #3
0
    def draw_halfedges(
        self,
        halfedges: Optional[List[Tuple[int, int]]] = None,
        color: Union[str, Color, List[Color], Dict[int,
                                                   Color]] = (0.7, 0.7, 0.7),
        distance: float = 0.05,
        width: float = 0.01,
        shrink: float = 0.8,
    ) -> None:
        """Draw a selection of halfedges.

        Parameters
        ----------
        edges : list, optional
            A list of halfedges to draw.
            The default is ``None``, in which case all halfedges are drawn.
        color : rgb-tuple or dict of rgb-tuples, optional
            The color specification for the halfedges.

        Returns
        -------
        None
        """
        self.clear_halfedges()
        self._halfedgecollection = []

        if color:
            self.halfedge_color = color

        if halfedges:
            self.halfedges = halfedges

        for u, v in self.halfedges:
            face = self.mesh.halfedge_face(u, v)

            if face is None:
                normal = self.mesh.face_normal(self.mesh.halfedge_face(v, u))
            else:
                normal = self.mesh.face_normal(face)

            a, b = self.mesh.edge_coordinates(u, v)
            line = Line(*offset_line((a, b), distance, normal))
            frame = Frame(line.midpoint, [1, 0, 0], [0, 1, 0])
            scale = Scale.from_factors([shrink, shrink, shrink], frame=frame)
            line.transform(scale)

            artist = self.plotter.axes.arrow(line.start[0],
                                             line.start[1],
                                             line.vector[0],
                                             line.vector[1],
                                             width=width,
                                             head_width=10 * width,
                                             head_length=10 * width,
                                             length_includes_head=True,
                                             shape='right',
                                             color=self.halfedge_color.get(
                                                 (u, v),
                                                 self.default_halfedgecolor),
                                             zorder=10000)
            self._halfedgecollection.append(artist)
Пример #4
0
 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
Пример #5
0
def test_sphere_scaling():
    s = Sphere(Point(1, 1, 1), 10)
    s.transform(Scale.from_factors([2, 3, 4]))
    assert s.point.x == 2
    assert s.point.y == 3
    assert s.point.z == 4
    assert s.radius == 40
Пример #6
0
 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
Пример #7
0
 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
Пример #8
0
    def scale(self, scale_factor):
        """Scale the volume uniformly.

        Parameters
        ----------
        scale_factor : :obj:`float`
            Scale factor to use in scaling operation.
        """
        S = Scale.from_factors([scale_factor] * 3)
        self.transform(S)
Пример #9
0
    def scale(self, scale_factor):
        """Scales the collision mesh uniformly.

        Parameters
        ----------
        scale_factor : :obj:`float`
            Scale factor.
        """
        S = Scale.from_factors([scale_factor] * 3)
        self.mesh.transform(S)
Пример #10
0
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))
Пример #11
0
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
Пример #12
0
 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
Пример #13
0
    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
Пример #14
0
    def scale(self, factor):
        """Scales the robot model's geometry by factor (absolute).

        Parameters
        ----------
        factor : float
            The factor to scale the robot with.

        Returns
        -------
        None
        """
        self.model.scale(factor)

        relative_factor = factor / self.scale_factor
        transformation = Scale.from_factors([relative_factor] * 3)
        self.scale_link(self.model.root, transformation)
        self.scale_factor = factor
Пример #15
0
"""Example: Decompose transformations
"""
from compas.geometry import Translation
from compas.geometry import Rotation
from compas.geometry import Scale

scale_factors = [0.1, 0.3, 0.4]
A = Scale.from_factors(scale_factors)  # create Scale
axis, angle = [-0.8, 0.35, 0.5], 2.2
B = Rotation.from_axis_and_angle(axis, angle)  # create Rotation
translation = [1, 2, 3]
C = Translation.from_vector(translation)  # create Translation

# Concatenate transformations
M = C * B * A

# A matrix can also be decomposed into its components of Scale,
# Shear, Rotation, Translation and Perspective
Sc, Sh, R, T, P = M.decomposed()
# Check, must be all `True`
print(A == Sc)
print(B == R)
print(C == T)
print(P * T * R * Sh * Sc == M)
Пример #16
0
# Subdivide a mesh following the doo-sabin scheme
subd = sd.mesh_subdivide_doosabin(mesh, k=1, fixed=None)
artist7 = MeshArtist(subd, layer="06_subdivide_doosabin")
artist7.clear_layer()
artist7.draw_vertices()
artist7.draw_faces()
artist7.draw_edges()
artist7.draw_vertexlabels()
artist7.draw_facelabels()
artist7.draw_edgelabels()

# 3d mesh - Custom rules
# n of faces - 4, 6, 8, 12, 20
poly = Mesh.from_polyhedron(8)

S = Scale.from_factors([5, 5, 5])
poly.transform(S)

point = [8, 0.5, 0]
T = Translation.from_vector(point)
poly.transform(T)

mesh2 = sd.mesh_subdivide_tri(poly)
mesh3 = mesh_subdivide_pyramid(mesh2, k=1, height=0.5)
mesh4 = sd.trimesh_subdivide_loop(mesh3)
mesh5 = sd.mesh_subdivide_catmullclark(mesh4)

# subdivide each face of the mesh
centers = []
for key in mesh5.faces():
    centers.append(mesh5.face_centroid(key))
Пример #17
0
import math
import compas_libigl as igl
from compas.datastructures import Mesh
from compas.utilities import Colormap, rgb_to_hex
from compas.geometry import Line, Polyline, Rotation, Scale
from compas_viewers.objectviewer import ObjectViewer

# ==============================================================================
# Input geometry
# ==============================================================================

mesh = Mesh.from_off(igl.get_beetle())

Rx = Rotation.from_axis_and_angle([1, 0, 0], math.radians(90))
Rz = Rotation.from_axis_and_angle([0, 0, 1], math.radians(90))
S = Scale.from_factors([10, 10, 10])

mesh.transform(S * Rz * Rx)

# ==============================================================================
# Isolines
# ==============================================================================

scalars = mesh.vertices_attribute('z')
vertices, edges = igl.trimesh_isolines(mesh.to_vertices_and_faces(), scalars,
                                       10)
isolines = igl.groupsort_isolines(vertices, edges)

# ==============================================================================
# Visualisation
# ==============================================================================
Пример #18
0
from compas.geometry import Vector, Translation, Scale
from compas.geometry import Polyline
from compas.datastructures import Mesh
from compas_occ.brep import BRep
from compas_view2.app import App

mesh = Mesh.from_obj(compas.get('tubemesh.obj'))

centroid = mesh.centroid()
zmin = min(mesh.vertices_attribute('z'))
vector = Vector(*centroid)
vector.z = zmin
vector *= -1

T = Translation.from_vector(vector)
S = Scale.from_factors([0.3, 0.3, 0.3])

mesh.transform(S * T)

brep = BRep.from_mesh(mesh)

lines = []
curves = []

for edge in brep.edges:
    if edge.is_line:
        lines.append(edge.to_line())
    elif edge.is_bspline:
        curves.append(Polyline(edge.curve.locus()))

viewer = App(viewmode='ghosted')
from compas.geometry import Translation
from compas.geometry import Scale
from compas.geometry import Reflection
from compas.geometry import Projection
from compas.geometry import Shear

axis, angle = [0.2, 0.4, 0.1], 0.3
R = Rotation.from_axis_and_angle(axis, angle)
print("Rotation:\n", R)

translation_vector = [5, 3, 1]
T = Translation.from_vector(translation_vector)
print("Translation:\n", T)

scale_factors = [0.1, 0.3, 0.4]
S = Scale.from_factors(scale_factors)
print("Scale:\n", S)

point, normal = [0.3, 0.2, 1], [0.3, 0.1, 1]
R = Reflection.from_plane((point, normal))
print("Reflection:\n", R)

point, normal = [0, 0, 0], [0, 0, 1]
perspective = [1, 1, 0]
P = Projection.from_plane_and_point((point, normal), perspective)
print("Perspective projection:\n", R)

angle, direction = 0.1, [0.1, 0.2, 0.3]
point, normal = [4, 3, 1], [-0.11, 0.31, -0.17]
S = Shear.from_angle_direction_plane(angle, direction, (point, normal))
print("Shear:\n", S)
Пример #20
0
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])
Пример #21
0
cylinder = Cylinder(circle, 0.7 * height)

circle = [[0, 0, 0.7 * height], [0, 0, 1]], 0.1
cone = Cone(circle, 0.3 * height)

for node in network.nodes():
    a = network.node_attributes(node, 'xyz')

    for nbr in network.neighbors(node):
        edge = node, nbr
        if not network.has_edge(*edge):
            edge = nbr, node

        b = network.node_attributes(nbr, 'xyz')
        force = network.edge_attribute(edge, 'f')
        direction = normalize_vector(subtract_vectors(b, a))

        frame = Frame.from_plane([a, direction])
        X = Transformation.from_frame_to_frame(world, frame)
        S = Scale.from_factors([force, 1, 1])
        X = X * S

        shaft = cylinder.transformed(X)
        tip = cone.transformed(X)

        artist = CylinderArtist(shaft, layer=layer, color=(255, 0, 0))
        artist.draw(u=16)

        artist = ConeArtist(tip, layer=layer, color=(255, 0, 0))
        artist.draw(u=16)
Пример #22
0
from compas.datastructures import Mesh
from compas.geometry import Point, Box
from compas.geometry import Translation, Scale
from compas_view2 import app

box = Box.from_diagonal([(0.0, 0.0, 0.0), (1.0, 1.0, 1.0)])
mesh = Mesh.from_shape(box)

trimesh = Mesh.from_polyhedron(4)
tribox = Box.from_bounding_box(trimesh.bounding_box())

S = tribox.width / box.width

trimesh.transform(Scale.from_factors([S, S, S]))
trimesh.transform(
    Translation.from_vector(Point(0.5, 0.5, 0.5) - Point(0, 0, 0)))

tri = mesh.subdivide(k=3, scheme='tri')
quad = mesh.subdivide(k=3, scheme='quad')
corner = mesh.subdivide(k=3, scheme='corner')
ck = mesh.subdivide(k=3, scheme='catmullclark')
doosabin = mesh.subdivide(k=3, scheme='doosabin')
frames = mesh.subdivide(offset=0.2, scheme='frames')
loop = trimesh.subdivide(k=3, scheme='loop')

corner.transform(Translation.from_vector([1.2 * 1, 0.0, 0.0]))
loop.transform(Translation.from_vector([1.2 * 2, 0.0, 0.0]))
quad.transform(Translation.from_vector([1.2 * 3, 0.0, 0.0]))
ck.transform(Translation.from_vector([1.2 * 4, 0.0, 0.0]))
doosabin.transform(Translation.from_vector([1.2 * 5, 0.0, 0.0]))
frames.transform(Translation.from_vector([1.2 * 6, 0.0, 0.0]))
Пример #23
0
"""Example: pre- vs. post- multiplication
"""
import math
from compas.geometry import Translation
from compas.geometry import Rotation
from compas.geometry import Scale

R = Rotation.from_axis_and_angle([0, 0, 1], math.radians(30))
T = Translation.from_vector([2, 0, 0])
S = Scale.from_factors([0.5] * 3)
X1 = S * T * R
X2 = R * T * S

print(X1)
print(X2)
print(X1 == X2) # should not be the same!