|
26 | 26 | TexturedSoftPhongShader,
|
27 | 27 | )
|
28 | 28 | from pytorch3d.renderer.mesh.texturing import Textures
|
29 |
| -from pytorch3d.structures.meshes import Meshes |
| 29 | +from pytorch3d.structures.meshes import Meshes, join_mesh |
30 | 30 | from pytorch3d.utils.ico_sphere import ico_sphere
|
31 | 31 |
|
32 | 32 |
|
@@ -176,7 +176,7 @@ def test_simple_sphere_batched(self):
|
176 | 176 | # Init renderer
|
177 | 177 | rasterizer = MeshRasterizer(cameras=cameras, raster_settings=raster_settings)
|
178 | 178 | shaders = {
|
179 |
| - "phong": HardGouraudShader, |
| 179 | + "phong": HardPhongShader, |
180 | 180 | "gouraud": HardGouraudShader,
|
181 | 181 | "flat": HardFlatShader,
|
182 | 182 | }
|
@@ -369,3 +369,70 @@ def test_texture_map(self):
|
369 | 369 | )
|
370 | 370 |
|
371 | 371 | self.assertClose(rgb, image_ref, atol=0.05)
|
| 372 | + |
| 373 | + def test_joined_spheres(self): |
| 374 | + """ |
| 375 | + Test a list of Meshes can be joined as a single mesh and |
| 376 | + the single mesh is rendered correctly with Phong, Gouraud |
| 377 | + and Flat Shaders. |
| 378 | + """ |
| 379 | + device = torch.device("cuda:0") |
| 380 | + |
| 381 | + # Init mesh with vertex textures. |
| 382 | + # Initialize a list containing two ico spheres of different sizes. |
| 383 | + sphere_list = [ico_sphere(3, device), ico_sphere(4, device)] |
| 384 | + # [(42 verts, 80 faces), (162 verts, 320 faces)] |
| 385 | + # The scale the vertices need to be set at to resize the spheres |
| 386 | + scales = [0.25, 1] |
| 387 | + # The distance the spheres ought to be offset horizontally to prevent overlap. |
| 388 | + offsets = [1.2, -0.3] |
| 389 | + # Initialize a list containing the adjusted sphere meshes. |
| 390 | + sphere_mesh_list = [] |
| 391 | + for i in range(len(sphere_list)): |
| 392 | + verts = sphere_list[i].verts_padded() * scales[i] |
| 393 | + verts[0, :, 0] += offsets[i] |
| 394 | + sphere_mesh_list.append( |
| 395 | + Meshes(verts=verts, faces=sphere_list[i].faces_padded()) |
| 396 | + ) |
| 397 | + joined_sphere_mesh = join_mesh(sphere_mesh_list) |
| 398 | + joined_sphere_mesh.textures = Textures( |
| 399 | + verts_rgb=torch.ones_like(joined_sphere_mesh.verts_padded()) |
| 400 | + ) |
| 401 | + |
| 402 | + # Init rasterizer settings |
| 403 | + R, T = look_at_view_transform(2.7, 0.0, 0.0) |
| 404 | + cameras = OpenGLPerspectiveCameras(device=device, R=R, T=T) |
| 405 | + raster_settings = RasterizationSettings( |
| 406 | + image_size=512, blur_radius=0.0, faces_per_pixel=1 |
| 407 | + ) |
| 408 | + |
| 409 | + # Init shader settings |
| 410 | + materials = Materials(device=device) |
| 411 | + lights = PointLights(device=device) |
| 412 | + lights.location = torch.tensor([0.0, 0.0, +2.0], device=device)[None] |
| 413 | + blend_params = BlendParams(1e-4, 1e-4, (0, 0, 0)) |
| 414 | + |
| 415 | + # Init renderer |
| 416 | + rasterizer = MeshRasterizer(cameras=cameras, raster_settings=raster_settings) |
| 417 | + shaders = { |
| 418 | + "phong": HardPhongShader, |
| 419 | + "gouraud": HardGouraudShader, |
| 420 | + "flat": HardFlatShader, |
| 421 | + } |
| 422 | + for (name, shader_init) in shaders.items(): |
| 423 | + shader = shader_init( |
| 424 | + lights=lights, |
| 425 | + cameras=cameras, |
| 426 | + materials=materials, |
| 427 | + blend_params=blend_params, |
| 428 | + ) |
| 429 | + renderer = MeshRenderer(rasterizer=rasterizer, shader=shader) |
| 430 | + image = renderer(joined_sphere_mesh) |
| 431 | + rgb = image[..., :3].squeeze().cpu() |
| 432 | + if DEBUG: |
| 433 | + file_name = "DEBUG_joined_spheres_%s.png" % name |
| 434 | + Image.fromarray((rgb.numpy() * 255).astype(np.uint8)).save( |
| 435 | + DATA_DIR / file_name |
| 436 | + ) |
| 437 | + image_ref = load_rgb_image("test_joined_spheres_%s.png" % name, DATA_DIR) |
| 438 | + self.assertClose(rgb, image_ref, atol=0.05) |
0 commit comments