Exemplo n.º 1
0
 def shape_to_mesh(self, shape: Shape):
     """ Convert pyphysx shape into the pyrender Mesh """
     clr_string = shape.get_user_data().get(
         'color', None) if shape.get_user_data() is not None else None
     clr = gl_color_from_matplotlib(color=clr_string, return_rgba=True)
     basic_trimesh = self._trimesh_from_basic_shape(shape, clr)
     if basic_trimesh is not None:
         return Mesh.from_trimesh(basic_trimesh)
     elif shape.get_geometry_type() == GeometryType.CONVEXMESH:
         data = shape.get_shape_data()  # N x 9 - i.e. 3 triangles
         primitive = Primitive(data.reshape(-1, 3),
                               normals=None,
                               color_0=clr,
                               mode=GLTF.TRIANGLES,
                               poses=None)
         return Mesh(primitives=[primitive])
     elif shape.get_geometry_type() == GeometryType.PLANE:
         clr = [0.8] * 3 + [
             0.1
         ] if clr_string is None else gl_color_from_matplotlib(
             clr_string, return_rgba=True)
         primitive = Primitive(positions=self._grid_lines(),
                               normals=None,
                               color_0=clr,
                               mode=GLTF.LINES,
                               poses=None)
         return Mesh(primitives=[primitive])
     else:
         raise NotImplementedError('Not supported type of the geometry.')
Exemplo n.º 2
0
def create_2d_point_mesh(width, height, pts_2d, point_size_px):
    # create a triangle mesh
    def _rot_mat(angle_rad):
        return np.array(
            [[np.cos(angle_rad), -np.sin(angle_rad)],
             [np.sin(angle_rad), np.cos(angle_rad)]],
            dtype=np.float32)

    if isinstance(pts_2d, list):
        pts_2d = np.array(pts_2d, dtype=np.float32)

    vertices = np.zeros((3, 3), dtype=np.float32)
    point_size_ndc = point_size_px / height
    vec = np.array([0, point_size_ndc])
    vertices[0, 0:2] = vec
    vertices[1, 0:2] = _rot_mat(np.radians(120)) @ vec
    vertices[2, 0:2] = _rot_mat(np.radians(-120)) @ vec
    mat = MetallicRoughnessMaterial(doubleSided=True,
                                    baseColorFactor=[1.0, 0, 0, 1])

    instances = [np.eye(4) for i in range(pts_2d.shape[0])]
    for i in range(pts_2d.shape[0]):
        instances[i][0, 3] = (2 * pts_2d[i][0] - width) / height
        instances[i][1, 3] = pts_2d[i][1] / height * 2 - 1
        instances[i][2, 3] = -1
    prim = Primitive(positions=vertices,
                     mode=GLTF.TRIANGLES,
                     material=mat,
                     poses=instances)
    return Mesh(primitives=[prim])
def test_meshes():

    with pytest.raises(TypeError):
        x = Mesh()
    with pytest.raises(TypeError):
        x = Primitive()
    with pytest.raises(ValueError):
        x = Primitive([], mode=10)

    # Basics
    x = Mesh([])
    assert x.name is None
    assert x.is_visible
    assert x.weights is None

    x.name = 'str'

    # From Trimesh
    x = Mesh.from_trimesh(trimesh.creation.box())
    assert isinstance(x, Mesh)
    assert len(x.primitives) == 1
    assert x.is_visible
    assert np.allclose(x.bounds, np.array([
        [-0.5, -0.5, -0.5],
        [0.5, 0.5, 0.5]
    ]))
    assert np.allclose(x.centroid, np.zeros(3))
    assert np.allclose(x.extents, np.ones(3))
    assert np.allclose(x.scale, np.sqrt(3))
    assert not x.is_transparent

    # Test some primitive functions
    x = x.primitives[0]
    with pytest.raises(ValueError):
        x.normals = np.zeros(10)
    with pytest.raises(ValueError):
        x.tangents = np.zeros(10)
    with pytest.raises(ValueError):
        x.texcoord_0 = np.zeros(10)
    with pytest.raises(ValueError):
        x.texcoord_1 = np.zeros(10)
    with pytest.raises(TypeError):
        x.material = np.zeros(10)
    assert x.targets is None
    assert np.allclose(x.bounds, np.array([
        [-0.5, -0.5, -0.5],
        [0.5, 0.5, 0.5]
    ]))
    assert np.allclose(x.centroid, np.zeros(3))
    assert np.allclose(x.extents, np.ones(3))
    assert np.allclose(x.scale, np.sqrt(3))
    x.material.baseColorFactor = np.array([0.0, 0.0, 0.0, 0.0])
    assert x.is_transparent

    # From two trimeshes
    x = Mesh.from_trimesh([trimesh.creation.box(),
                          trimesh.creation.cylinder(radius=0.1, height=2.0)],
                          smooth=False)
    assert isinstance(x, Mesh)
    assert len(x.primitives) == 2
    assert x.is_visible
    assert np.allclose(x.bounds, np.array([
        [-0.5, -0.5, -1.0],
        [0.5, 0.5, 1.0]
    ]))
    assert np.allclose(x.centroid, np.zeros(3))
    assert np.allclose(x.extents, [1.0, 1.0, 2.0])
    assert np.allclose(x.scale, np.sqrt(6))
    assert not x.is_transparent

    # From bad data
    with pytest.raises(TypeError):
        x = Mesh.from_trimesh(None)

    # With instancing
    poses = np.tile(np.eye(4), (5,1,1))
    poses[:,0,3] = np.array([0,1,2,3,4])
    x = Mesh.from_trimesh(trimesh.creation.box(), poses=poses)
    assert np.allclose(x.bounds, np.array([
        [-0.5, -0.5, -0.5],
        [4.5, 0.5, 0.5]
    ]))
    poses = np.eye(4)
    x = Mesh.from_trimesh(trimesh.creation.box(), poses=poses)
    poses = np.eye(3)
    with pytest.raises(ValueError):
        x = Mesh.from_trimesh(trimesh.creation.box(), poses=poses)

    # From textured meshes
    fm = trimesh.load('tests/data/fuze.obj')
    x = Mesh.from_trimesh(fm)
    assert isinstance(x, Mesh)
    assert len(x.primitives) == 1
    assert x.is_visible
    assert not x.is_transparent
    assert x.primitives[0].material.baseColorTexture is not None

    x = Mesh.from_trimesh(fm, smooth=False)
    fm.visual = fm.visual.to_color()
    fm.visual.face_colors = np.array([1.0, 0.0, 0.0, 1.0])
    x = Mesh.from_trimesh(fm, smooth=False)
    with pytest.raises(ValueError):
        x = Mesh.from_trimesh(fm, smooth=True)

    fm.visual.vertex_colors = np.array([1.0, 0.0, 0.0, 0.5])
    x = Mesh.from_trimesh(fm, smooth=False)
    x = Mesh.from_trimesh(fm, smooth=True)
    assert x.primitives[0].color_0 is not None
    assert x.is_transparent

    bm = trimesh.load('tests/data/WaterBottle.glb').dump()[0]
    x = Mesh.from_trimesh(bm)
    assert x.primitives[0].material.baseColorTexture is not None
    assert x.primitives[0].material.emissiveTexture is not None
    assert x.primitives[0].material.metallicRoughnessTexture is not None

    # From point cloud
    x = Mesh.from_points(fm.vertices)
def test_scenes():

    # Basics
    s = Scene()
    assert np.allclose(s.bg_color, np.ones(4))
    assert np.allclose(s.ambient_light, np.zeros(3))
    assert len(s.nodes) == 0
    assert s.name is None
    s.name = 'asdf'
    s.bg_color = None
    s.ambient_light = None
    assert np.allclose(s.bg_color, np.ones(4))
    assert np.allclose(s.ambient_light, np.zeros(3))

    assert s.nodes == set()
    assert s.cameras == set()
    assert s.lights == set()
    assert s.point_lights == set()
    assert s.spot_lights == set()
    assert s.directional_lights == set()
    assert s.meshes == set()
    assert s.camera_nodes == set()
    assert s.light_nodes == set()
    assert s.point_light_nodes == set()
    assert s.spot_light_nodes == set()
    assert s.directional_light_nodes == set()
    assert s.mesh_nodes == set()
    assert s.main_camera_node is None
    assert np.all(s.bounds == 0)
    assert np.all(s.centroid == 0)
    assert np.all(s.extents == 0)
    assert np.all(s.scale == 0)

    # From trimesh scene
    tms = trimesh.load('tests/data/WaterBottle.glb')
    s = Scene.from_trimesh_scene(tms)
    assert len(s.meshes) == 1
    assert len(s.mesh_nodes) == 1

    # Test bg color formatting
    s = Scene(bg_color=[0, 1.0, 0])
    assert np.allclose(s.bg_color, np.array([0.0, 1.0, 0.0, 1.0]))

    # Test constructor for nodes
    n1 = Node()
    n2 = Node()
    n3 = Node()
    nodes = [n1, n2, n3]
    s = Scene(nodes=nodes)
    n1.children.append(n2)
    s = Scene(nodes=nodes)
    n3.children.append(n2)
    with pytest.raises(ValueError):
        s = Scene(nodes=nodes)
    n3.children = []
    n2.children.append(n3)
    n3.children.append(n2)
    with pytest.raises(ValueError):
        s = Scene(nodes=nodes)

    # Test node accessors
    n1 = Node()
    n2 = Node()
    n3 = Node()
    nodes = [n1, n2]
    s = Scene(nodes=nodes)
    assert s.has_node(n1)
    assert s.has_node(n2)
    assert not s.has_node(n3)

    # Test node poses
    for n in nodes:
        assert np.allclose(s.get_pose(n), np.eye(4))
    with pytest.raises(ValueError):
        s.get_pose(n3)
    with pytest.raises(ValueError):
        s.set_pose(n3, np.eye(4))
    tf = np.eye(4)
    tf[:3, 3] = np.ones(3)
    s.set_pose(n1, tf)
    assert np.allclose(s.get_pose(n1), tf)
    assert np.allclose(s.get_pose(n2), np.eye(4))

    nodes = [n1, n2, n3]
    tf2 = np.eye(4)
    tf2[:3, :3] = np.diag([-1, -1, 1])
    n1.children.append(n2)
    n1.matrix = tf
    n2.matrix = tf2
    s = Scene(nodes=nodes)
    assert np.allclose(s.get_pose(n1), tf)
    assert np.allclose(s.get_pose(n2), tf.dot(tf2))
    assert np.allclose(s.get_pose(n3), np.eye(4))

    n1 = Node()
    n2 = Node()
    n3 = Node()
    n1.children.append(n2)
    s = Scene()
    s.add_node(n1)
    with pytest.raises(ValueError):
        s.add_node(n2)
    s.set_pose(n1, tf)
    assert np.allclose(s.get_pose(n1), tf)
    assert np.allclose(s.get_pose(n2), tf)
    s.set_pose(n2, tf2)
    assert np.allclose(s.get_pose(n2), tf.dot(tf2))

    # Test node removal
    n1 = Node()
    n2 = Node()
    n3 = Node()
    n1.children.append(n2)
    n2.children.append(n3)
    s = Scene(nodes=[n1, n2, n3])
    s.remove_node(n2)
    assert len(s.nodes) == 1
    assert n1 in s.nodes
    assert len(n1.children) == 0
    assert len(n2.children) == 1
    s.add_node(n2, parent_node=n1)
    assert len(n1.children) == 1
    n1.matrix = tf
    n3.matrix = tf2
    assert np.allclose(s.get_pose(n3), tf.dot(tf2))

    # Now test ADD function
    s = Scene()
    m = Mesh([], name='m')
    cp = PerspectiveCamera(yfov=2.0)
    co = OrthographicCamera(xmag=1.0, ymag=1.0)
    dl = DirectionalLight()
    pl = PointLight()
    sl = SpotLight()

    n1 = s.add(m, name='mn')
    assert n1.mesh == m
    assert len(s.nodes) == 1
    assert len(s.mesh_nodes) == 1
    assert n1 in s.mesh_nodes
    assert len(s.meshes) == 1
    assert m in s.meshes
    assert len(s.get_nodes(node=n2)) == 0
    n2 = s.add(m, pose=tf)
    assert len(s.nodes) == len(s.mesh_nodes) == 2
    assert len(s.meshes) == 1
    assert len(s.get_nodes(node=n1)) == 1
    assert len(s.get_nodes(node=n1, name='mn')) == 1
    assert len(s.get_nodes(name='mn')) == 1
    assert len(s.get_nodes(obj=m)) == 2
    assert len(s.get_nodes(obj=m, obj_name='m')) == 2
    assert len(s.get_nodes(obj=co)) == 0
    nsl = s.add(sl, name='sln')
    npl = s.add(pl, parent_name='sln')
    assert nsl.children[0] == npl
    ndl = s.add(dl, parent_node=npl)
    assert npl.children[0] == ndl
    nco = s.add(co)
    ncp = s.add(cp)

    assert len(s.light_nodes) == len(s.lights) == 3
    assert len(s.point_light_nodes) == len(s.point_lights) == 1
    assert npl in s.point_light_nodes
    assert len(s.spot_light_nodes) == len(s.spot_lights) == 1
    assert nsl in s.spot_light_nodes
    assert len(s.directional_light_nodes) == len(s.directional_lights) == 1
    assert ndl in s.directional_light_nodes
    assert len(s.cameras) == len(s.camera_nodes) == 2
    assert s.main_camera_node == nco
    s.main_camera_node = ncp
    s.remove_node(ncp)
    assert len(s.cameras) == len(s.camera_nodes) == 1
    assert s.main_camera_node == nco
    s.remove_node(n2)
    assert len(s.meshes) == 1
    s.remove_node(n1)
    assert len(s.meshes) == 0
    s.remove_node(nsl)
    assert len(s.lights) == 0
    s.remove_node(nco)
    assert s.main_camera_node is None

    s.add_node(n1)
    s.clear()
    assert len(s.nodes) == 0

    # Trigger final errors
    with pytest.raises(ValueError):
        s.main_camera_node = None
    with pytest.raises(ValueError):
        s.main_camera_node = ncp
    with pytest.raises(ValueError):
        s.add(m, parent_node=n1)
    with pytest.raises(ValueError):
        s.add(m, name='asdf')
        s.add(m, name='asdf')
        s.add(m, parent_name='asdf')
    with pytest.raises(ValueError):
        s.add(m, parent_name='asfd')
    with pytest.raises(TypeError):
        s.add(None)

    s.clear()
    # Test bounds
    m1 = Mesh.from_trimesh(trimesh.creation.box())
    m2 = Mesh.from_trimesh(trimesh.creation.box())
    m3 = Mesh.from_trimesh(trimesh.creation.box())
    n1 = Node(mesh=m1)
    n2 = Node(mesh=m2, translation=[1.0, 0.0, 0.0])
    n3 = Node(mesh=m3, translation=[0.5, 0.0, 1.0])
    s.add_node(n1)
    s.add_node(n2)
    s.add_node(n3)
    assert np.allclose(s.bounds, [[-0.5, -0.5, -0.5], [1.5, 0.5, 1.5]])
    s.clear()
    s.add_node(n1)
    s.add_node(n2, parent_node=n1)
    s.add_node(n3, parent_node=n2)
    assert np.allclose(s.bounds, [[-0.5, -0.5, -0.5], [2.0, 0.5, 1.5]])
    tf = np.eye(4)
    tf[:3, 3] = np.ones(3)
    s.set_pose(n3, tf)
    assert np.allclose(s.bounds, [[-0.5, -0.5, -0.5], [2.5, 1.5, 1.5]])
    s.remove_node(n2)
    assert np.allclose(s.bounds, [[-0.5, -0.5, -0.5], [0.5, 0.5, 0.5]])
    s.clear()
    assert np.allclose(s.bounds, 0.0)
Exemplo n.º 5
0
def test_nodes():

    x = Node()
    assert x.name is None
    assert x.camera is None
    assert x.children == []
    assert x.skin is None
    assert np.allclose(x.matrix, np.eye(4))
    assert x.mesh is None
    assert np.allclose(x.rotation, [0, 0, 0, 1])
    assert np.allclose(x.scale, np.ones(3))
    assert np.allclose(x.translation, np.zeros(3))
    assert x.weights is None
    assert x.light is None

    x.name = 'node'

    # Test node light/camera/mesh tests
    c = PerspectiveCamera(yfov=2.0)
    m = Mesh([])
    d = DirectionalLight()
    x.camera = c
    assert x.camera == c
    with pytest.raises(TypeError):
        x.camera = m
        x.camera = d
    x.camera = None
    x.mesh = m
    assert x.mesh == m
    with pytest.raises(TypeError):
        x.mesh = c
        x.mesh = d
    x.light = d
    assert x.light == d
    with pytest.raises(TypeError):
        x.light = m
        x.light = c

    # Test transformations getters/setters/etc...
    # Set up test values
    x = np.array([1.0, 0.0, 0.0])
    y = np.array([0.0, 1.0, 0.0])
    t = np.array([1.0, 2.0, 3.0])
    s = np.array([0.5, 2.0, 1.0])

    Mx = transformations.rotation_matrix(np.pi / 2.0, x)
    qx = np.roll(transformations.quaternion_about_axis(np.pi / 2.0, x), -1)
    Mxt = Mx.copy()
    Mxt[:3, 3] = t
    S = np.eye(4)
    S[:3, :3] = np.diag(s)
    Mxts = Mxt.dot(S)

    My = transformations.rotation_matrix(np.pi / 2.0, y)
    qy = np.roll(transformations.quaternion_about_axis(np.pi / 2.0, y), -1)
    Myt = My.copy()
    Myt[:3, 3] = t

    x = Node(matrix=Mx)
    assert np.allclose(x.matrix, Mx)
    assert np.allclose(x.rotation, qx)
    assert np.allclose(x.translation, np.zeros(3))
    assert np.allclose(x.scale, np.ones(3))

    x.matrix = My
    assert np.allclose(x.matrix, My)
    assert np.allclose(x.rotation, qy)
    assert np.allclose(x.translation, np.zeros(3))
    assert np.allclose(x.scale, np.ones(3))
    x.translation = t
    assert np.allclose(x.matrix, Myt)
    assert np.allclose(x.rotation, qy)
    x.rotation = qx
    assert np.allclose(x.matrix, Mxt)
    x.scale = s
    assert np.allclose(x.matrix, Mxts)

    x = Node(matrix=Mxt)
    assert np.allclose(x.matrix, Mxt)
    assert np.allclose(x.rotation, qx)
    assert np.allclose(x.translation, t)
    assert np.allclose(x.scale, np.ones(3))

    x = Node(matrix=Mxts)
    assert np.allclose(x.matrix, Mxts)
    assert np.allclose(x.rotation, qx)
    assert np.allclose(x.translation, t)
    assert np.allclose(x.scale, s)

    # Individual element getters
    x.scale[0] = 0
    assert np.allclose(x.scale[0], 0)

    x.translation[0] = 0
    assert np.allclose(x.translation[0], 0)

    x.matrix = np.eye(4)
    x.matrix[0, 0] = 500
    assert x.matrix[0, 0] == 1.0

    # Failures
    with pytest.raises(ValueError):
        x.matrix = 5 * np.eye(4)
    with pytest.raises(ValueError):
        x.matrix = np.eye(5)
    with pytest.raises(ValueError):
        x.matrix = np.eye(4).dot([5, 1, 1, 1])
    with pytest.raises(ValueError):
        x.rotation = np.array([1, 2])
    with pytest.raises(ValueError):
        x.rotation = np.array([1, 2, 3])
    with pytest.raises(ValueError):
        x.rotation = np.array([1, 2, 3, 4])
    with pytest.raises(ValueError):
        x.translation = np.array([1, 2, 3, 4])
    with pytest.raises(ValueError):
        x.scale = np.array([1, 2, 3, 4])