def build_scene(num_cubes, color_candidates): # Generate positions of each cube cube_position_array, barycenter = generate_block_positions(num_cubes) assert len(cube_position_array) == num_cubes # Place cubes scene = Scene(bg_color=np.array([0.0, 0.0, 0.0]), ambient_light=np.array([0.3, 0.3, 0.3, 1.0])) cube_nodes = [] for position in cube_position_array: mesh = trimesh.creation.box(extents=cube_size * np.ones(3)) mesh = Mesh.from_trimesh(mesh, smooth=False) node = Node(mesh=mesh, translation=np.array(([ position[0] - barycenter[0], position[1] - barycenter[1], position[2] - barycenter[2], ]))) scene.add_node(node) cube_nodes.append(node) update_cube_color_and_position(cube_nodes, color_candidates) # Place a light light = DirectionalLight(color=np.ones(3), intensity=15.0) quaternion_yaw = pyrender.quaternion.from_yaw(math.pi / 4) quaternion_pitch = pyrender.quaternion.from_pitch(-math.pi / 5) quaternion = pyrender.quaternion.multiply(quaternion_pitch, quaternion_yaw) quaternion = quaternion / np.linalg.norm(quaternion) node = Node(light=light, rotation=quaternion, translation=np.array([1, 1, 1])) scene.add_node(node) return scene, cube_nodes
def place_objects(scene, colors, objects, max_num_objects=3, min_num_objects=1, discrete_position=False, rotate_object=False): # Place objects directions = [-1.5, 0.0, 1.5] available_positions = [] for z in directions: for x in directions: available_positions.append((x, z)) available_positions = np.array(available_positions) num_objects = random.choice(range(min_num_objects, max_num_objects + 1)) indices = np.random.choice(np.arange(len(available_positions)), replace=False, size=num_objects) for xz in available_positions[indices]: node = random.choice(objects)() node.mesh.primitives[0].color_0 = random.choice(colors) if discrete_position == False: xz += np.random.uniform(-0.3, 0.3, size=xz.shape) if rotate_object: yaw = np.random.uniform(0, math.pi * 2, size=1)[0] rotation = pyrender.quaternion.from_yaw(yaw) parent = Node(children=[node], rotation=rotation, translation=np.array([xz[0], 0, xz[1]])) else: parent = Node(children=[node], translation=np.array([xz[0], 0, xz[1]])) scene.add_node(parent)
def place_dice(scene, mnist_images, discrete_position=False, rotate_dice=False): dice_trimesh = trimesh.load("objects/dice.obj") mesh = Mesh.from_trimesh(dice_trimesh, smooth=False) node = Node(mesh=mesh, scale=np.array([0.75, 0.75, 0.75]), translation=np.array([0, 0.75, 0])) texture_image = generate_mnist_texture(mnist_images) primitive = node.mesh.primitives[0] primitive.material.baseColorTexture.source = texture_image primitive.material.baseColorTexture.sampler.minFilter = GL_LINEAR_MIPMAP_LINEAR directions = [-1.0, 0.0, 1.0] available_positions = [] for z in directions: for x in directions: available_positions.append((x, z)) xz = np.array(random.choice(available_positions)) if discrete_position == False: xz += np.random.uniform(-0.25, 0.25, size=xz.shape) if rotate_dice: yaw = np.random.uniform(0, math.pi * 2, size=1)[0] rotation = pyrender.quaternion.from_yaw(yaw) parent = Node(children=[node], rotation=rotation, translation=np.array([xz[0], 0, xz[1]])) else: parent = Node(children=[node], translation=np.array([xz[0], 0, xz[1]])) scene.add_node(parent)
def _set_axes(self, world, mesh): """ Use fixed scale for the axes instead of automatic. """ scale = self.viewer_flags['axes_scale'] if world: if 'scene' not in self._axes: n = Node(mesh=self._axis_mesh, scale=np.ones(3) * scale) self.render_scene.add_node(n) self._axes['scene'] = n else: if 'scene' in self._axes: self.scene.remove_node(self._axes['scene']) self._axes.pop('scene') if mesh: old_nodes = [] existing_axes = set([self._axes[k] for k in self._axes]) for node in self.scene.mesh_nodes: if node not in existing_axes: old_nodes.append(node) for node in old_nodes: if node in self._axes: continue n = Node(mesh=self._axis_mesh, scale=np.ones(3) * scale) self.render_scene.add_node(n, parent_node=node) self._axes[node] = n else: to_remove = set() for main_node in self._axes: if main_node in self.scene.mesh_nodes: self.scene.remove_node(self._axes[main_node]) to_remove.add(main_node) for main_node in to_remove: self._axes.pop(main_node)
def main(): # Initialize colors color_candidates = [] for n in range(args.num_colors): hue = n / args.num_colors saturation = 1 lightness = 1 red, green, blue = colorsys.hsv_to_rgb(hue, saturation, lightness) color_candidates.append((red, green, blue)) renderer = OffscreenRenderer(viewport_width=args.image_size, viewport_height=args.image_size) rad_step = math.pi / 18 total_frames = int(math.pi * 2 / rad_step) camera_distance = 2 fig = plt.figure(figsize=(3, 3)) ims = [] for num_cubes in range(1, 8): scene = build_scene(num_cubes, color_candidates)[0] camera = OrthographicCamera(xmag=0.9, ymag=0.9) camera_node = Node(camera=camera) scene.add_node(camera_node) current_rad = 0 for _ in range(total_frames): camera_position = np.array( (math.sin(current_rad), math.sin(math.pi / 6), math.cos(current_rad))) camera_position = camera_distance * camera_position / np.linalg.norm( camera_position) # Compute yaw and pitch yaw, pitch = compute_yaw_and_pitch(camera_position) camera_node.rotation = genearte_camera_quaternion(yaw, pitch) camera_node.translation = camera_position # Rendering flags = RenderFlags.SHADOWS_DIRECTIONAL if args.anti_aliasing: flags |= RenderFlags.ANTI_ALIASING image = renderer.render(scene, flags=flags)[0] im = plt.imshow(image, interpolation="none", animated=True) ims.append([im]) current_rad += rad_step renderer.delete() ani = animation.ArtistAnimation(fig, ims, interval=1 / 24, blit=True, repeat_delay=0) ani.save("shepard_metzler.gif", writer="imagemagick")
def place_objects(full_scene, masks_scene, colors, objects, max_num_objects=3, min_num_objects=1, discrete_position=False, rotate_object=False): # Place objects directions = [-1.5, 0.0, 1.5] available_positions = [] for z in directions: for x in directions: available_positions.append((x, z)) available_positions = np.array(available_positions) num_objects = random.choice(range(min_num_objects, max_num_objects + 1)) indices = np.random.choice(np.arange(len(available_positions)), replace=False, size=num_objects) parents = [] mask_parents = [] for xz in available_positions[indices]: object_ctor = random.choice(objects) node = object_ctor() node.mesh.primitives[0].color_0 = random.choice(colors) mask_node = object_ctor() mask_node.mesh.primitives[0].color_0 = list( np.random.uniform(0.05, 1., size=[3])) + [1.] if discrete_position == False: xz += np.random.uniform(-0.3, 0.3, size=xz.shape) if rotate_object: yaw = np.random.uniform(0, math.pi * 2, size=1)[0] rotation = pyrender.quaternion.from_yaw(yaw) parent = Node(children=[node], rotation=rotation, translation=np.array([xz[0], 0, xz[1]])) mask_parent = Node(children=[mask_node], rotation=rotation, translation=np.array([xz[0], 0, xz[1]])) else: parent = Node(children=[node], translation=np.array([xz[0], 0, xz[1]])) mask_parent = Node(children=[mask_node], translation=np.array([xz[0], 0, xz[1]])) parent.scale = [args.object_scale] * 3 mask_parent.scale = [args.object_scale] * 3 full_scene.add_node(parent) masks_scene.add_node(mask_parent) parents.append(parent) mask_parents.append(mask_parent) return parents, mask_parents
def build_scene(max_num_cubes, color_candidates, probabilities): num_cubes = np.random.choice(np.arange(1, max_num_cubes + 1), size=1, p=probabilities)[0] # Generate positions of each cube cube_position_array, barycenter = generate_block_positions(num_cubes) assert len(cube_position_array) == num_cubes # Place cubes scene = Scene(bg_color=np.array([0.0, 0.0, 0.0]), ambient_light=np.array([0.3, 0.3, 0.3, 1.0])) cube_nodes = [] for position in cube_position_array: mesh = trimesh.creation.box(extents=cube_size * np.ones(3)) mesh = Mesh.from_trimesh(mesh, smooth=False) node = Node(mesh=mesh, translation=np.array(([ position[0] - barycenter[0], position[1] - barycenter[1], position[2] - barycenter[2], ]))) scene.add_node(node) cube_nodes.append(node) # Generate positions of each cube cube_position_array, barycenter = generate_block_positions(num_cubes) for position, node in zip(cube_position_array, cube_nodes): color = np.array(random.choice(color_candidates)) vertex_colors = np.broadcast_to( color, node.mesh.primitives[0].positions.shape) node.mesh.primitives[0].color_0 = vertex_colors node.translation = np.array(([ position[0] - barycenter[0], position[1] - barycenter[1], position[2] - barycenter[2], ])) # Place a light light = DirectionalLight(color=np.ones(3), intensity=15.0) quaternion_yaw = pyrender.quaternion.from_yaw(math.pi / 4) quaternion_pitch = pyrender.quaternion.from_pitch(-math.pi / 5) quaternion = pyrender.quaternion.multiply(quaternion_pitch, quaternion_yaw) quaternion = quaternion / np.linalg.norm(quaternion) node = Node(light=light, rotation=quaternion, translation=np.array([1, 1, 1])) scene.add_node(node) return scene, cube_nodes
def _create_scene(self): self._scene = Scene() camera = PerspectiveCamera(yfov=0.833, znear=0.05, zfar=3.0, aspectRatio=1.0) cn = Node() cn.camera = camera pose_m = np.array([[0.0, 1.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0], [0.0, 0.0, -1.0, 0.88], [0.0, 0.0, 0.0, 1.0]]) pose_m[:, 1:3] *= -1.0 cn.matrix = pose_m self._scene.add_node(cn) self._scene.main_camera_node = cn
def _add_to_scene(self, obj): self._viewer.render_lock.acquire() n = Node(mesh=Mesh.from_trimesh(obj.mesh), matrix=obj.pose.matrix, name=obj.key) self._scene.add_node(n) self._viewer.render_lock.release()
def _create_raymond_lights(self): thetas = np.pi * np.array([1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0]) phis = np.pi * np.array([0.0, 2.0 / 3.0, 4.0 / 3.0]) nodes = [] for phi, theta in zip(phis, thetas): xp = np.sin(theta) * np.cos(phi) yp = np.sin(theta) * np.sin(phi) zp = np.cos(theta) z = np.array([xp, yp, zp]) z = z / np.linalg.norm(z) x = np.array([-z[1], z[0], 0.0]) if np.linalg.norm(x) == 0: x = np.array([1.0, 0.0, 0.0]) x = x / np.linalg.norm(x) y = np.cross(z, x) matrix = np.eye(4) matrix[:3, :3] = np.c_[x, y, z] nodes.append( Node( light=DirectionalLight(color=np.ones(3), intensity=1.0), matrix=matrix, ) ) return nodes
def make_normals_node(trimesh, node, normal_direction): normals_mesh = Mesh.from_trimesh(trimesh, smooth=False) normals_mesh.primitives[0].material = SpecularGlossinessMaterial( diffuseFactor=list(np.asarray(normal_direction) / 2 + 0.5) + [1.]) return Node(mesh=normals_mesh, rotation=node.rotation, translation=node.translation)
def __init__(self, render_scene=None, plane_grid_spacing=1., plane_grid_num_of_lines=10, spheres_count=(8, 8)) -> None: """ Base class for PyRender viewer and offscreen renderer. """ ViewerBase.__init__(self) self.spheres_count = spheres_count self.plane_grid_num_of_lines = plane_grid_num_of_lines self.plane_grid_spacing = plane_grid_spacing if render_scene is None: render_scene = PyRenderScene() render_scene.bg_color = np.array([0.75] * 3) if render_scene.main_camera_node is None: cam = PerspectiveCamera(yfov=np.deg2rad(60), aspectRatio=1.414, znear=0.005) cam_pose = np.eye(4) cam_pose[:3, 3] = RoboticTrackball.spherical_to_cartesian( 3., 0., np.deg2rad(45.), target=np.zeros(3)) cam_pose[:3, :3] = RoboticTrackball.look_at_rotation( eye=cam_pose[:3, 3], target=np.zeros(3), up=[0, 0, 1]) nc = Node(camera=cam, matrix=cam_pose) render_scene.add_node(nc) render_scene.main_camera_node = nc self.render_scene = render_scene self.nodes_and_actors = []
def actor_to_node(self, actor, flags): shapes = [ s for s in actor.get_atached_shapes() if PyRenderBase.has_shape_any_of_flags(s, flags) ] if len(shapes) == 0: return None return Node(children=[self.shape_to_node(s) for s in shapes])
def build_scene(floor_textures, wall_textures, fix_light_position=False): scene = Scene(bg_color=np.array([153 / 255, 226 / 255, 249 / 255]), ambient_light=np.array([0.5, 0.5, 0.5, 1.0])) floor_trimesh = trimesh.load("{}/floor.obj".format(object_directory)) mesh = Mesh.from_trimesh(floor_trimesh, smooth=False) node = Node(mesh=mesh, rotation=pyrender.quaternion.from_pitch(-math.pi / 2), translation=np.array([0, 0, 0])) texture_path = random.choice(floor_textures) set_random_texture(node, texture_path) scene.add_node(node) texture_path = random.choice(wall_textures) wall_trimesh = trimesh.load("{}/wall.obj".format(object_directory)) mesh = Mesh.from_trimesh(wall_trimesh, smooth=False) node = Node(mesh=mesh, translation=np.array([0, 1.15, -3.5])) set_random_texture(node, texture_path) scene.add_node(node) mesh = Mesh.from_trimesh(wall_trimesh, smooth=False) node = Node(mesh=mesh, rotation=pyrender.quaternion.from_yaw(math.pi), translation=np.array([0, 1.15, 3.5])) set_random_texture(node, texture_path) scene.add_node(node) mesh = Mesh.from_trimesh(wall_trimesh, smooth=False) node = Node(mesh=mesh, rotation=pyrender.quaternion.from_yaw(-math.pi / 2), translation=np.array([3.5, 1.15, 0])) set_random_texture(node, texture_path) scene.add_node(node) mesh = Mesh.from_trimesh(wall_trimesh, smooth=False) node = Node(mesh=mesh, rotation=pyrender.quaternion.from_yaw(math.pi / 2), translation=np.array([-3.5, 1.15, 0])) set_random_texture(node, texture_path) scene.add_node(node) light = DirectionalLight(color=np.ones(3), intensity=10) if fix_light_position == True: translation = np.array([1, 1, 1]) else: xz = np.random.uniform(-1, 1, size=2) translation = np.array([xz[0], 1, xz[1]]) yaw, pitch = compute_yaw_and_pitch(translation) node = Node(light=light, rotation=genearte_camera_quaternion(yaw, pitch), translation=translation) scene.add_node(node) return scene
def _create_node_from_mesh(mesh, name=None, pose=None, color=None, material=None, poses=None, wireframe=False, smooth=True): """Helper method that creates a pyrender.Node from a trimesh.Trimesh""" # Create default pose if pose is None: pose = np.eye(4) elif isinstance(pose, RigidTransform): pose = pose.matrix # Create vertex colors if needed if color is not None: color = np.asanyarray(color, dtype=np.float) if color.ndim == 1 or len(color) != len(mesh.vertices): color = np.repeat(color[np.newaxis, :], len(mesh.vertices), axis=0) mesh.visual.vertex_colors = color if material is None and mesh.visual.kind != 'texture': if color is not None: material = None else: material = MetallicRoughnessMaterial(baseColorFactor=np.array( [1.0, 1.0, 1.0, 1.0]), metallicFactor=0.2, roughnessFactor=0.8) m = Mesh.from_trimesh(mesh, material=material, poses=poses, wireframe=wireframe, smooth=smooth) return Node(mesh=m, name=name, matrix=pose)
def _create_node_from_points(points, name=None, pose=None, color=None, material=None, tube_radius=None, n_divs=20): """Helper method that creates a pyrender.Node from an array of points""" points = np.asanyarray(points) if points.ndim == 1: points = np.array([points]) if pose is None: pose = np.eye(4) else: pose = pose.matrix # Create vertex colors if needed if color is not None: color = np.asanyarray(color, dtype=np.float) if color.ndim == 1 or len(color) != len(points): color = np.repeat(color[np.newaxis, :], len(points), axis=0) if tube_radius is not None: poses = None mesh = trimesh.creation.uv_sphere(tube_radius, [n_divs, n_divs]) if color is not None: mesh.visual.vertex_colors = color[0] poses = np.tile(np.eye(4), (len(points), 1)).reshape(len(points), 4, 4) poses[:, :3, 3::4] = points[:, :, None] m = Mesh.from_trimesh(mesh, material=material, poses=poses) else: m = Mesh.from_points(points, colors=color) return Node(mesh=m, name=name, matrix=pose)
def _create_node_from_points(points, name=None, pose=None, color=None, material=None, radius=None, n_divs=20): """Helper method that creates a pyrender.Node from an array of points""" points = np.asanyarray(points) if points.ndim == 1: points = np.array([points]) if pose is None: pose = np.eye(4) else: pose = pose.matrix color = np.asanyarray(color, dtype=np.float) if color is not None else None # If color specified per point, use sprites if color is not None and color.ndim > 1: Visualizer3D._kwargs.update({"point_size": 1000 * radius}) m = Mesh.from_points(points, colors=color) # otherwise, we can make pretty spheres else: mesh = trimesh.creation.uv_sphere(radius, [n_divs, n_divs]) if color is not None: mesh.visual.vertex_colors = color poses = None poses = np.tile(np.eye(4), (len(points), 1)).reshape(len(points), 4, 4) poses[:, :3, 3::4] = points[:, :, None] m = Mesh.from_trimesh(mesh, material=material, poses=poses) return Node(mesh=m, name=name, matrix=pose)
def main(): # Load MNIST images mnist_images = load_mnist_images() renderer = OffscreenRenderer(viewport_width=args.image_size, viewport_height=args.image_size) plt.tight_layout() fig = plt.figure(figsize=(6, 3)) axis_perspective = fig.add_subplot(1, 2, 1) axis_orthogonal = fig.add_subplot(1, 2, 2) ims = [] scene = build_scene(floor_textures, wall_textures, fix_light_position=args.fix_light_position) place_dice(scene, mnist_images, discrete_position=args.discrete_position, rotate_dice=args.rotate_dice) camera_distance = 5 perspective_camera = PerspectiveCamera(yfov=math.pi / 4) perspective_camera_node = Node(camera=perspective_camera, translation=np.array([0, 1, 1])) orthographic_camera = OrthographicCamera(xmag=3, ymag=3) orthographic_camera_node = Node(camera=orthographic_camera) rad_step = math.pi / 36 total_frames = int(math.pi * 2 / rad_step) current_rad = 0 for _ in range(total_frames): scene.add_node(perspective_camera_node) # Perspective camera camera_xz = camera_distance * np.array( (math.sin(current_rad), math.cos(current_rad))) # Compute yaw and pitch camera_direction = np.array([camera_xz[0], 0, camera_xz[1]]) yaw, pitch = compute_yaw_and_pitch(camera_direction) perspective_camera_node.rotation = genearte_camera_quaternion( yaw, pitch) camera_position = np.array([camera_xz[0], 1, camera_xz[1]]) perspective_camera_node.translation = camera_position # Rendering flags = RenderFlags.SHADOWS_DIRECTIONAL if args.anti_aliasing: flags |= RenderFlags.ANTI_ALIASING image = renderer.render(scene, flags=flags)[0] im1 = axis_perspective.imshow(image, interpolation="none", animated=True) scene.remove_node(perspective_camera_node) # Orthographic camera scene.add_node(orthographic_camera_node) camera_direction = camera_distance * np.array( (math.sin(current_rad), math.sin( math.pi / 6), math.cos(current_rad))) yaw, pitch = compute_yaw_and_pitch(camera_direction) orthographic_camera_node.rotation = genearte_camera_quaternion( yaw, pitch) orthographic_camera_node.translation = np.array( [camera_direction[0], 4, camera_direction[2]]) image = renderer.render(scene, flags=flags)[0] im2 = axis_orthogonal.imshow(image, interpolation="none", animated=True) ims.append([im1, im2]) plt.pause(1e-8) current_rad += rad_step scene.remove_node(orthographic_camera_node) ani = animation.ArtistAnimation(fig, ims, interval=1 / 24, blit=True, repeat_delay=0) filename = "mnist_dice" if args.discrete_position: filename += "_discrete_position" if args.rotate_dice: filename += "_rotate_dice" if args.fix_light_position: filename += "_fix_light_position" filename += ".gif" ani.save(filename, writer="imagemagick")
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]) pts_mesh = create_2d_point_mesh(640, 480, [[0, 0], [320, 240], [640, 480]], point_size_px=15) duck_node = scene.add(duckmesh) dn = scene.add_hud_node(Node(name="hud", mesh=pts_mesh)) Viewer(scene, run_in_thread=False, viewer_flags={"use_direct_lighting": True}, viewport_size=(640, 480))
# ============================================================================== # Scene creation # ============================================================================== scene = Scene(ambient_light=np.array([0.02, 0.02, 0.02, 1.0])) # ============================================================================== # Adding objects to the scene # ============================================================================== # ------------------------------------------------------------------------------ # By manually creating nodes # ------------------------------------------------------------------------------ fuze_node = Node(mesh=fuze_mesh, translation=np.array( [0.1, 0.15, -np.min(fuze_trimesh.vertices[:, 2])])) scene.add_node(fuze_node) boxv_node = Node(mesh=boxv_mesh, translation=np.array([-0.1, 0.10, 0.05])) scene.add_node(boxv_node) boxf_node = Node(mesh=boxf_mesh, translation=np.array([-0.1, -0.10, 0.05])) scene.add_node(boxf_node) # ------------------------------------------------------------------------------ # By using the add() utility function # ------------------------------------------------------------------------------ drill_node = scene.add(drill_mesh, pose=drill_pose) bottle_node = scene.add(bottle_mesh, pose=bottle_pose) wood_node = scene.add(wood_mesh) direc_l_node = scene.add(direc_l, pose=cam_pose) spot_l_node = scene.add(spot_l, pose=cam_pose)
def test_offscreen_renderer(tmpdir): # Fuze trimesh fuze_trimesh = trimesh.load('examples/models/fuze.obj') fuze_mesh = Mesh.from_trimesh(fuze_trimesh) # Drill trimesh drill_trimesh = trimesh.load('examples/models/drill.obj') drill_mesh = Mesh.from_trimesh(drill_trimesh) drill_pose = np.eye(4) drill_pose[0, 3] = 0.1 drill_pose[2, 3] = -np.min(drill_trimesh.vertices[:, 2]) # Wood trimesh wood_trimesh = trimesh.load('examples/models/wood.obj') wood_mesh = Mesh.from_trimesh(wood_trimesh) # Water bottle trimesh bottle_gltf = trimesh.load('examples/models/WaterBottle.glb') bottle_trimesh = bottle_gltf.geometry[list(bottle_gltf.geometry.keys())[0]] bottle_mesh = Mesh.from_trimesh(bottle_trimesh) bottle_pose = np.array([ [1.0, 0.0, 0.0, 0.1], [0.0, 0.0, -1.0, -0.16], [0.0, 1.0, 0.0, 0.13], [0.0, 0.0, 0.0, 1.0], ]) boxv_trimesh = trimesh.creation.box(extents=0.1 * np.ones(3)) boxv_vertex_colors = np.random.uniform(size=(boxv_trimesh.vertices.shape)) boxv_trimesh.visual.vertex_colors = boxv_vertex_colors boxv_mesh = Mesh.from_trimesh(boxv_trimesh, smooth=False) boxf_trimesh = trimesh.creation.box(extents=0.1 * np.ones(3)) boxf_face_colors = np.random.uniform(size=boxf_trimesh.faces.shape) boxf_trimesh.visual.face_colors = boxf_face_colors # Instanced poses = np.tile(np.eye(4), (2, 1, 1)) poses[0, :3, 3] = np.array([-0.1, -0.10, 0.05]) poses[1, :3, 3] = np.array([-0.15, -0.10, 0.05]) boxf_mesh = Mesh.from_trimesh(boxf_trimesh, poses=poses, smooth=False) points = trimesh.creation.icosphere(radius=0.05).vertices point_colors = np.random.uniform(size=points.shape) points_mesh = Mesh.from_points(points, colors=point_colors) direc_l = DirectionalLight(color=np.ones(3), intensity=1.0) spot_l = SpotLight(color=np.ones(3), intensity=10.0, innerConeAngle=np.pi / 16, outerConeAngle=np.pi / 6) cam = PerspectiveCamera(yfov=(np.pi / 3.0)) cam_pose = np.array([[0.0, -np.sqrt(2) / 2, np.sqrt(2) / 2, 0.5], [1.0, 0.0, 0.0, 0.0], [0.0, np.sqrt(2) / 2, np.sqrt(2) / 2, 0.4], [0.0, 0.0, 0.0, 1.0]]) scene = Scene(ambient_light=np.array([0.02, 0.02, 0.02])) fuze_node = Node(mesh=fuze_mesh, translation=np.array( [0.1, 0.15, -np.min(fuze_trimesh.vertices[:, 2])])) scene.add_node(fuze_node) boxv_node = Node(mesh=boxv_mesh, translation=np.array([-0.1, 0.10, 0.05])) scene.add_node(boxv_node) boxf_node = Node(mesh=boxf_mesh) scene.add_node(boxf_node) _ = scene.add(drill_mesh, pose=drill_pose) _ = scene.add(bottle_mesh, pose=bottle_pose) _ = scene.add(wood_mesh) _ = scene.add(direc_l, pose=cam_pose) _ = scene.add(spot_l, pose=cam_pose) _ = scene.add(points_mesh) _ = scene.add(cam, pose=cam_pose) r = OffscreenRenderer(viewport_width=640, viewport_height=480) color, depth = r.render(scene) assert color.shape == (480, 640, 3) assert depth.shape == (480, 640) assert np.max(depth.data) > 0.05 assert np.count_nonzero(depth.data) > (0.2 * depth.size) r.delete()
def main(): try: os.makedirs(args.output_directory) except: pass last_file_number = args.initial_file_number + args.total_scenes // args.num_scenes_per_file - 1 initial_file_number = args.initial_file_number if os.path.isdir(args.output_directory): files = os.listdir(args.output_directory) for name in files: number = int(name.replace(".h5", "")) if number > last_file_number: continue if number < args.initial_file_number: continue if number < initial_file_number: continue initial_file_number = number + 1 total_scenes_to_render = args.total_scenes - args.num_scenes_per_file * ( initial_file_number - args.initial_file_number) assert args.num_scenes_per_file <= total_scenes_to_render # Colors colors = [] for n in range(args.num_colors): hue = n / args.num_colors saturation = 1 lightness = 1 red, green, blue = colorsys.hsv_to_rgb(hue, saturation, lightness) colors.append(np.array((red, green, blue, 1))) renderer = OffscreenRenderer(viewport_width=args.image_size, viewport_height=args.image_size) archiver = Archiver( directory=args.output_directory, num_scenes_per_file=args.num_scenes_per_file, image_size=(args.image_size, args.image_size), num_observations_per_scene=args.num_observations_per_scene, initial_file_number=initial_file_number) for scene_index in tqdm(range(total_scenes_to_render)): scene = build_scene(floor_textures, wall_textures, fix_light_position=args.fix_light_position) place_objects(scene, colors, objects, max_num_objects=args.max_num_objects, discrete_position=args.discrete_position, rotate_object=args.rotate_object) camera_distance = 4.5 camera = PerspectiveCamera(yfov=math.pi / 4) camera_node = Node(camera=camera, translation=np.array([0, 1, 1])) scene.add_node(camera_node) scene_data = SceneData((args.image_size, args.image_size), args.num_observations_per_scene) for observation_index in range(args.num_observations_per_scene): rand_position_xz = np.random.normal(size=2) rand_position_xz = camera_distance * rand_position_xz / np.linalg.norm( rand_position_xz) # Compute yaw and pitch camera_direction = np.array( [rand_position_xz[0], 0, rand_position_xz[1]]) yaw, pitch = compute_yaw_and_pitch(camera_direction) camera_node.rotation = genearte_camera_quaternion(yaw, pitch) camera_position = np.array( [rand_position_xz[0], 1, rand_position_xz[1]]) camera_node.translation = camera_position # Rendering flags = RenderFlags.SHADOWS_DIRECTIONAL if args.anti_aliasing: flags |= RenderFlags.ANTI_ALIASING image = renderer.render(scene, flags=flags)[0] scene_data.add(image, camera_position, math.cos(yaw), math.sin(yaw), math.cos(pitch), math.sin(pitch)) if args.visualize: plt.clf() plt.imshow(image) plt.pause(1e-10) archiver.add(scene_data) renderer.delete()
while True: r += delta_r frame += 1 t += 50 if t % 1000 == 0: delta_r *= -1 s = parametric_surface.doughnut(R, r, [50, 20]) doughnut_trimesh = trimesh.Trimesh( vertices=s.flat_vertices, faces=s.flat_triangular_mesh_indices, ) # for facet in doughnut_trimesh.facets: # doughnut_trimesh.visual.face_colors[facet] = trimesh.visual.random_color() mesh = pyrender.Mesh.from_trimesh(doughnut_trimesh, smooth=False) mesh_node = Node(mesh=mesh, translation=np.array([0.0, 0.0, 0.0])) scene = Scene(ambient_light=np.array([0.02, 0.02, 0.02, 1.0]), bg_color=[0.0, 0.0, 0.0]) cam_node = scene.add(cam, pose=cam_pose) scene.add_node(mesh_node) # v = Viewer(scene) color, depth = off_screen_renderer.render(scene) cv2.imshow('f', color) cv2.waitKey(1) end_time = time.time() print(frame / (end_time - start_time)) off_screen_renderer.delete()
os.makedirs(save_path) face_trimesh = trimesh.load('./result_mesh.obj') face_mesh = pyrender.Mesh.from_trimesh(face_trimesh) inx = 0 for x in np.arange(MIN_DEGREES, MAX_DEGREES + STEP_DEGREES, STEP_DEGREES): for y in np.arange(MIN_DEGREES, MAX_DEGREES + STEP_DEGREES, STEP_DEGREES): inx += 1 scene = pyrender.Scene() rotate_vec = np.array([x, y, 0.0, 1]) rotate_vec_norm = rotate_vec / np.linalg.norm(rotate_vec) face_node = Node(mesh=face_mesh, translation=np.array([0, 0, -2.5]), rotation=rotate_vec_norm) scene.add_node(face_node) camera = pyrender.PerspectiveCamera(yfov=np.pi / 3.0) camera_pose = np.array([ [1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0], ]) scene.add(camera, pose=camera_pose) light = pyrender.light.DirectionalLight(color=np.ones(3), intensity=5.0) scene.add(light, pose=camera_pose) r = pyrender.OffscreenRenderer(600, 600, point_size=1)
def main(): try: os.makedirs(args.output_directory) except: pass last_file_number = args.initial_file_number + args.total_scenes // args.num_scenes_per_file - 1 initial_file_number = args.initial_file_number if os.path.isdir(args.output_directory): files = os.listdir(args.output_directory) for name in files: number = int(name.replace(".h5", "")) if number > last_file_number: continue if number < args.initial_file_number: continue if number < initial_file_number: continue initial_file_number = number + 1 total_scenes_to_render = args.total_scenes - args.num_scenes_per_file * ( initial_file_number - args.initial_file_number) assert args.num_scenes_per_file <= total_scenes_to_render # Initialize colors color_candidates = [] for n in range(args.num_colors): hue = n / args.num_colors saturation = 1 lightness = 1 red, green, blue = colorsys.hsv_to_rgb(hue, saturation, lightness) color_candidates.append((red, green, blue)) scene, cube_nodes = build_scene(args.num_cubes, color_candidates) camera = OrthographicCamera(xmag=0.9, ymag=0.9) camera_node = Node(camera=camera) scene.add_node(camera_node) renderer = OffscreenRenderer( viewport_width=args.image_size, viewport_height=args.image_size) archiver = Archiver( directory=args.output_directory, num_scenes_per_file=args.num_scenes_per_file, image_size=(args.image_size, args.image_size), num_observations_per_scene=args.num_observations_per_scene, initial_file_number=initial_file_number) for scene_index in tqdm(range(total_scenes_to_render)): camera_distance = 2 scene_data = SceneData((args.image_size, args.image_size), args.num_observations_per_scene) for observation_index in range(args.num_observations_per_scene): # Generate random point on a sphere camera_position = np.random.normal(size=3) camera_position = camera_distance * camera_position / np.linalg.norm( camera_position) # Compute yaw and pitch yaw, pitch = compute_yaw_and_pitch(camera_position) camera_node.rotation = genearte_camera_quaternion(yaw, pitch) camera_node.translation = camera_position # Rendering flags = RenderFlags.SHADOWS_DIRECTIONAL if args.anti_aliasing: flags |= RenderFlags.ANTI_ALIASING image = renderer.render(scene, flags=flags)[0] scene_data.add(image, camera_position, math.cos(yaw), math.sin(yaw), math.cos(pitch), math.sin(pitch)) if args.visualize: plt.clf() plt.imshow(image) plt.pause(1e-10) archiver.add(scene_data) # Change cube color and position update_cube_color_and_position(cube_nodes, color_candidates) # Transfer changes to the vertex buffer on gpu udpate_vertex_buffer(cube_nodes) renderer.delete()
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)
RigidStatic.create_plane(material=Material( static_friction=0.1, dynamic_friction=0.1, restitution=0.5))) actor = RigidDynamic() actor.attach_shape(Shape.create_box([0.2] * 3, Material(restitution=1.))) actor.set_global_pose([0.5, 0.5, 1.0]) actor.set_mass(1.) scene.add_actor(actor) render = PyPhysxOffscreenRenderer() # Offscreen render has no lighting by default - that is opposite to the pyrender viewer. Therefore, we create some # lighting to get nice rendered pictures. render.render_scene.ambient_light = [0.1] * 3 render.render_scene.add_node( Node(light=PointLight(color=[0.2, 0.2, 1.0], intensity=3.0), matrix=np.eye(4))) render.add_physx_scene(scene) # add PyPhysX scene frames = [] rate = Rate(60) for _ in range( 20): # render 20 frames at 10 fps and store images into the list for _ in range(6): scene.simulate(rate.period()) # simulation runs at 60 Hz render.update() rgb, depth = render.get_rgb_and_depth() depth = np.clip((depth * 20), 0, 255).astype(dtype=np.uint8) frames.append( np.concatenate( [rgb, np.repeat(depth[:, :, np.newaxis], 3, axis=-1)], axis=1))
def main(): try: os.makedirs(args.output_directory) except: pass # Colors colors = [] for n in range(args.num_colors): hue = n / args.num_colors saturation = 1 lightness = 1 red, green, blue = colorsys.hsv_to_rgb(hue, saturation, lightness) colors.append(np.array((red, green, blue, 1))) renderer = OffscreenRenderer(viewport_width=args.image_size, viewport_height=args.image_size) archiver = Archiver( directory=args.output_directory, total_scenes=args.total_scenes, num_scenes_per_file=min(args.num_scenes_per_file, args.total_scenes), image_size=(args.image_size, args.image_size), num_observations_per_scene=args.num_observations_per_scene, initial_file_number=args.initial_file_number) for scene_index in tqdm(range(args.total_scenes)): scene = build_scene(floor_textures, wall_textures, fix_light_position=args.fix_light_position) place_objects(scene, colors, objects, max_num_objects=args.max_num_objects, discrete_position=args.discrete_position, rotate_object=args.rotate_object) camera_distance = 3 camera = PerspectiveCamera(yfov=math.pi / 4) camera_node = Node(camera=camera, translation=np.array([0, 1, 1])) scene.add_node(camera_node) scene_data = SceneData((args.image_size, args.image_size), args.num_observations_per_scene) for observation_index in range(args.num_observations_per_scene): # Sample camera position rand_position_xz = np.random.uniform(-3, 3, size=2) rand_lookat_xz = np.random.uniform(-6, 6, size=2) camera_position = np.array( [rand_position_xz[0], 1, rand_position_xz[1]]) # Compute yaw and pitch camera_direction = rand_position_xz - rand_lookat_xz camera_direction = np.array( [camera_direction[0], 0, camera_direction[1]]) yaw, pitch = compute_yaw_and_pitch(camera_direction) camera_node.rotation = genearte_camera_quaternion(yaw, pitch) camera_node.translation = camera_position # Rendering flags = RenderFlags.SHADOWS_DIRECTIONAL if args.anti_aliasing: flags |= RenderFlags.ANTI_ALIASING image = renderer.render(scene, flags=flags)[0] scene_data.add(image, camera_position, math.cos(yaw), math.sin(yaw), math.cos(pitch), math.sin(pitch)) if args.visualize: plt.clf() plt.imshow(image) plt.pause(1e-10) archiver.add(scene_data) renderer.delete()
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])
def main(): # Colors colors = [] for n in range(args.num_colors): hue = n / args.num_colors saturation = 1 lightness = 1 red, green, blue = colorsys.hsv_to_rgb(hue, saturation, lightness) colors.append(np.array((red, green, blue, 1))) floor_textures = [ "../textures/lg_floor_d.tga", "../textures/lg_style_01_floor_blue_d.tga", "../textures/lg_style_01_floor_orange_bright_d.tga", ] wall_textures = [ "../textures/lg_style_01_wall_cerise_d.tga", "../textures/lg_style_01_wall_green_bright_d.tga", "../textures/lg_style_01_wall_red_bright_d.tga", "../textures/lg_style_02_wall_yellow_d.tga", "../textures/lg_style_03_wall_orange_bright_d.tga", ] objects = [ pyrender.objects.Capsule, pyrender.objects.Cylinder, pyrender.objects.Icosahedron, pyrender.objects.Box, pyrender.objects.Sphere, ] renderer = OffscreenRenderer(viewport_width=args.image_size, viewport_height=args.image_size) plt.tight_layout() fig = plt.figure(figsize=(6, 3)) axis_perspective = fig.add_subplot(1, 2, 1) axis_orthogonal = fig.add_subplot(1, 2, 2) ims = [] scene = build_scene(floor_textures, wall_textures, fix_light_position=args.fix_light_position) place_objects(scene, colors, objects, min_num_objects=args.num_objects, max_num_objects=args.num_objects, discrete_position=args.discrete_position, rotate_object=args.rotate_object) camera_distance = 5 perspective_camera = PerspectiveCamera(yfov=math.pi / 4) perspective_camera_node = Node(camera=perspective_camera, translation=np.array([0, 1, 1])) orthographic_camera = OrthographicCamera(xmag=3, ymag=3) orthographic_camera_node = Node(camera=orthographic_camera) rad_step = math.pi / 36 total_frames = int(math.pi * 2 / rad_step) current_rad = 0 for _ in range(total_frames): scene.add_node(perspective_camera_node) # Perspective camera camera_xz = camera_distance * np.array( (math.sin(current_rad), math.cos(current_rad))) # Compute yaw and pitch camera_direction = np.array([camera_xz[0], 0, camera_xz[1]]) yaw, pitch = compute_yaw_and_pitch(camera_direction) perspective_camera_node.rotation = genearte_camera_quaternion( yaw, pitch) camera_position = np.array([camera_xz[0], 1, camera_xz[1]]) perspective_camera_node.translation = camera_position # Rendering flags = RenderFlags.SHADOWS_DIRECTIONAL if args.anti_aliasing: flags |= RenderFlags.ANTI_ALIASING image = renderer.render(scene, flags=flags)[0] im1 = axis_perspective.imshow(image, interpolation="none", animated=True) scene.remove_node(perspective_camera_node) # Orthographic camera scene.add_node(orthographic_camera_node) camera_direction = camera_distance * np.array( (math.sin(current_rad), math.sin( math.pi / 6), math.cos(current_rad))) yaw, pitch = compute_yaw_and_pitch(camera_direction) orthographic_camera_node.rotation = genearte_camera_quaternion( yaw, pitch) orthographic_camera_node.translation = np.array( [camera_direction[0], 4, camera_direction[2]]) image = renderer.render(scene, flags=flags)[0] im2 = axis_orthogonal.imshow(image, interpolation="none", animated=True) ims.append([im1, im2]) plt.pause(1e-8) current_rad += rad_step scene.remove_node(orthographic_camera_node) ani = animation.ArtistAnimation(fig, ims, interval=1 / 24, blit=True, repeat_delay=0) filename = "rooms" if args.discrete_position: filename += "_discrete_position" if args.rotate_object: filename += "_rotate_object" if args.fix_light_position: filename += "_fix_light_position" filename += ".gif" ani.save(filename, writer="imagemagick")