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 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 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 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")