Skip to content

Commit c75ca04

Browse files
nikhilaravifacebook-github-bot
authored andcommitted
Bug fix in rendering clipped meshes
Summary: There was a bug when `z_clip_value` is not None but there are no faces which are actually visible in the image due to culling. In `rasterize_meshes.py` a function `convert_clipped_rasterization_to_original_faces` is called to convert the clipped face indices etc back to the unclipped versions, but the case where there is no clipping was not handled correctly. Fixes Github Issue #632 Reviewed By: bottler Differential Revision: D29116150 fbshipit-source-id: fae82a0b4848c84b3ed7c7b04ef5c9848352cf5c
1 parent bc8361f commit c75ca04

File tree

2 files changed

+29
-18
lines changed

2 files changed

+29
-18
lines changed

pytorch3d/renderer/mesh/clip.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -638,8 +638,11 @@ def convert_clipped_rasterization_to_original_faces(
638638
"""
639639
faces_clipped_to_unclipped_idx = clipped_faces.faces_clipped_to_unclipped_idx
640640

641-
# If no clipping or culling then return inputs
642-
if faces_clipped_to_unclipped_idx is None:
641+
# If no clipping then return inputs
642+
if (
643+
faces_clipped_to_unclipped_idx is None
644+
or faces_clipped_to_unclipped_idx.numel() == 0
645+
):
643646
return pix_to_face_clipped, bary_coords_clipped
644647

645648
device = pix_to_face_clipped.device

tests/test_render_meshes_clipped.py

+24-16
Original file line numberDiff line numberDiff line change
@@ -657,22 +657,30 @@ def test_case_4_no_duplicates(self):
657657

658658
def test_mesh_outside_frustrum(self):
659659
"""
660-
Test the case where the mesh is completely outside the view
660+
Test cases:
661+
1. Where the mesh is completely outside the view
661662
frustrum so all faces are culled and z_clip_value = None.
663+
2. Where the part of the mesh is in the view frustrum but
664+
the z_clip value = 5.0 so all the visible faces are behind
665+
the clip plane so are culled instead of clipped.
662666
"""
663667
device = "cuda:0"
664-
mesh = torus(20.0, 85.0, 32, 16, device=device)
665-
tex = TexturesVertex(verts_features=torch.rand_like(mesh.verts_padded()))
666-
mesh.textures = tex
667-
raster_settings = RasterizationSettings(image_size=512, cull_to_frustum=True)
668-
R, T = look_at_view_transform(1.0, 0.0, 0.0)
669-
cameras = PerspectiveCameras(device=device, R=R, T=T)
670-
renderer = MeshRenderer(
671-
rasterizer=MeshRasterizer(cameras=cameras, raster_settings=raster_settings),
672-
shader=SoftPhongShader(cameras=cameras, device=device),
673-
)
674-
images = renderer(mesh)
675-
676-
# Mesh is completely outside the view frustrum
677-
# The image should be white.
678-
self.assertClose(images[0, ..., :3], torch.ones_like(images[0, ..., :3]))
668+
mesh1 = torus(20.0, 85.0, 32, 16, device=device)
669+
mesh2 = torus(2.0, 3.0, 32, 16, device=device)
670+
for (mesh, z_clip) in [(mesh1, None), (mesh2, 5.0)]:
671+
tex = TexturesVertex(verts_features=torch.rand_like(mesh.verts_padded()))
672+
mesh.textures = tex
673+
raster_settings = RasterizationSettings(
674+
image_size=512, cull_to_frustum=True, z_clip_value=z_clip
675+
)
676+
R, T = look_at_view_transform(3.0, 0.0, 0.0)
677+
cameras = PerspectiveCameras(device=device, R=R, T=T)
678+
renderer = MeshRenderer(
679+
rasterizer=MeshRasterizer(
680+
cameras=cameras, raster_settings=raster_settings
681+
),
682+
shader=SoftPhongShader(cameras=cameras, device=device),
683+
)
684+
images = renderer(mesh)
685+
# The image should be white.
686+
self.assertClose(images[0, ..., :3], torch.ones_like(images[0, ..., :3]))

0 commit comments

Comments
 (0)