mirror of
https://github.com/facebookresearch/pytorch3d.git
synced 2025-12-19 22:00:35 +08:00
Deduplicate texture maps when joining
Summary: If you join several meshes which have TexturesUV textures using join_meshes_as_scene then we amalgamate all the texture images in to a single one. This now checks if some of the images are equal (i.e. the tensors are the same tensor, in the `is` sense; they have the same `id` in Python) and only uses one copy if they are. I have an example of a massive scene made of several textured meshes with some shared, where this makes the difference between fitting the data on the GPU and not. Reviewed By: theschnitz Differential Revision: D25982364 fbshipit-source-id: a8228805f38475c796302e27328a340d9b56c8ef
This commit is contained in:
committed by
Facebook GitHub Bot
parent
cd5af2521a
commit
e12a08133f
@@ -652,6 +652,9 @@ class TestRenderMeshes(TestCaseMixin, unittest.TestCase):
|
||||
verts_shifted2 = verts.clone()
|
||||
verts_shifted2 *= 0.5
|
||||
verts_shifted2[:, 1] -= 7
|
||||
verts_shifted3 = verts.clone()
|
||||
verts_shifted3 *= 0.5
|
||||
verts_shifted3[:, 1] -= 700
|
||||
|
||||
[faces] = plain_torus.faces_list()
|
||||
nocolor = torch.zeros((100, 100), device=device)
|
||||
@@ -697,7 +700,11 @@ class TestRenderMeshes(TestCaseMixin, unittest.TestCase):
|
||||
mesh1 = Meshes(verts=[verts], faces=[faces], textures=textures1)
|
||||
mesh2 = Meshes(verts=[verts_shifted1], faces=[faces], textures=textures2)
|
||||
mesh3 = Meshes(verts=[verts_shifted2], faces=[faces], textures=textures3)
|
||||
mesh = join_meshes_as_scene([mesh1, mesh2, mesh3])
|
||||
# mesh4 is like mesh1 but outside the field of view. It is here to test
|
||||
# that having another texture with the same map doesn't produce
|
||||
# two copies in the joined map.
|
||||
mesh4 = Meshes(verts=[verts_shifted3], faces=[faces], textures=textures1)
|
||||
mesh = join_meshes_as_scene([mesh1, mesh2, mesh3, mesh4])
|
||||
|
||||
output = renderer(mesh)[0, ..., :3].cpu()
|
||||
output1 = renderer(mesh1)[0, ..., :3].cpu()
|
||||
|
||||
@@ -12,7 +12,11 @@ from pytorch3d.renderer.mesh.textures import (
|
||||
TexturesUV,
|
||||
TexturesVertex,
|
||||
_list_to_padded_wrapper,
|
||||
)
|
||||
from pytorch3d.renderer.mesh.utils import (
|
||||
Rectangle,
|
||||
pack_rectangles,
|
||||
pack_unique_rectangles,
|
||||
)
|
||||
from pytorch3d.structures import Meshes, list_to_packed, packed_to_list
|
||||
from test_meshes import init_mesh
|
||||
@@ -873,21 +877,24 @@ class TestRectanglePacking(TestCaseMixin, unittest.TestCase):
|
||||
mask = torch.zeros(total, dtype=torch.bool)
|
||||
seen_x_bound = False
|
||||
seen_y_bound = False
|
||||
for (in_x, in_y), loc in zip(sizes, res.locations):
|
||||
self.assertGreaterEqual(loc[0], 0)
|
||||
self.assertGreaterEqual(loc[1], 0)
|
||||
placed_x, placed_y = (in_y, in_x) if loc[2] else (in_x, in_y)
|
||||
upper_x = placed_x + loc[0]
|
||||
upper_y = placed_y + loc[1]
|
||||
for (in_x, in_y), (out_x, out_y, flipped, is_first) in zip(
|
||||
sizes, res.locations
|
||||
):
|
||||
self.assertTrue(is_first)
|
||||
self.assertGreaterEqual(out_x, 0)
|
||||
self.assertGreaterEqual(out_y, 0)
|
||||
placed_x, placed_y = (in_y, in_x) if flipped else (in_x, in_y)
|
||||
upper_x = placed_x + out_x
|
||||
upper_y = placed_y + out_y
|
||||
self.assertGreaterEqual(total[0], upper_x)
|
||||
if total[0] == upper_x:
|
||||
seen_x_bound = True
|
||||
self.assertGreaterEqual(total[1], upper_y)
|
||||
if total[1] == upper_y:
|
||||
seen_y_bound = True
|
||||
already_taken = torch.sum(mask[loc[0] : upper_x, loc[1] : upper_y])
|
||||
already_taken = torch.sum(mask[out_x:upper_x, out_y:upper_y])
|
||||
self.assertEqual(already_taken, 0)
|
||||
mask[loc[0] : upper_x, loc[1] : upper_y] = 1
|
||||
mask[out_x:upper_x, out_y:upper_y] = 1
|
||||
self.assertTrue(seen_x_bound)
|
||||
self.assertTrue(seen_y_bound)
|
||||
|
||||
@@ -930,3 +937,29 @@ class TestRectanglePacking(TestCaseMixin, unittest.TestCase):
|
||||
for j in range(vals.shape[0]):
|
||||
sizes.append((int(vals[j, 0]), int(vals[j, 1])))
|
||||
self.wrap_pack(sizes)
|
||||
|
||||
def test_all_identical(self):
|
||||
sizes = [Rectangle(xsize=61, ysize=82, identifier=1729)] * 3
|
||||
total_size, locations = pack_unique_rectangles(sizes)
|
||||
self.assertEqual(total_size, (61, 82))
|
||||
self.assertEqual(len(locations), 3)
|
||||
for i, (x, y, is_flipped, is_first) in enumerate(locations):
|
||||
self.assertEqual(x, 0)
|
||||
self.assertEqual(y, 0)
|
||||
self.assertFalse(is_flipped)
|
||||
self.assertEqual(is_first, i == 0)
|
||||
|
||||
def test_one_different_id(self):
|
||||
sizes = [Rectangle(xsize=61, ysize=82, identifier=220)] * 3
|
||||
sizes.extend([Rectangle(xsize=61, ysize=82, identifier=284)] * 3)
|
||||
total_size, locations = pack_unique_rectangles(sizes)
|
||||
self.assertEqual(total_size, (82, 122))
|
||||
self.assertEqual(len(locations), 6)
|
||||
for i, (x, y, is_flipped, is_first) in enumerate(locations):
|
||||
self.assertTrue(is_flipped)
|
||||
self.assertEqual(is_first, i % 3 == 0)
|
||||
self.assertEqual(x, 0)
|
||||
if i < 3:
|
||||
self.assertEqual(y, 61)
|
||||
else:
|
||||
self.assertEqual(y, 0)
|
||||
|
||||
Reference in New Issue
Block a user