mirror of
https://github.com/facebookresearch/pytorch3d.git
synced 2025-08-02 20:02:49 +08:00
avoid running tests twice
Summary: Avoid test files explicitly importing TestCase objects from each other, because doing so causes the tests to be discovered twice by unittest discover. This means moving a few static functions out of their classes. I noticed this while trying to fix failures from yesterday. Reviewed By: nikhilaravi Differential Revision: D28194679 fbshipit-source-id: ac6e6585603bd4ef9c098cdd56891d94f8923ba6
This commit is contained in:
parent
e3624b4e9d
commit
0ca839cc32
@ -6,7 +6,7 @@ import torch
|
|||||||
from common_testing import TestCaseMixin
|
from common_testing import TestCaseMixin
|
||||||
from pytorch3d.loss import mesh_edge_loss
|
from pytorch3d.loss import mesh_edge_loss
|
||||||
from pytorch3d.structures import Meshes
|
from pytorch3d.structures import Meshes
|
||||||
from test_sample_points_from_meshes import TestSamplePoints
|
from test_sample_points_from_meshes import init_meshes
|
||||||
|
|
||||||
|
|
||||||
class TestMeshEdgeLoss(TestCaseMixin, unittest.TestCase):
|
class TestMeshEdgeLoss(TestCaseMixin, unittest.TestCase):
|
||||||
@ -92,7 +92,7 @@ class TestMeshEdgeLoss(TestCaseMixin, unittest.TestCase):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def mesh_edge_loss(num_meshes: int = 10, max_v: int = 100, max_f: int = 300):
|
def mesh_edge_loss(num_meshes: int = 10, max_v: int = 100, max_f: int = 300):
|
||||||
meshes = TestSamplePoints.init_meshes(num_meshes, max_v, max_f, device="cuda:0")
|
meshes = init_meshes(num_meshes, max_v, max_f, device="cuda:0")
|
||||||
torch.cuda.synchronize()
|
torch.cuda.synchronize()
|
||||||
|
|
||||||
def compute_loss():
|
def compute_loss():
|
||||||
|
@ -10,128 +10,126 @@ from common_testing import TestCaseMixin
|
|||||||
from pytorch3d.structures.meshes import Meshes
|
from pytorch3d.structures.meshes import Meshes
|
||||||
|
|
||||||
|
|
||||||
|
def init_mesh(
|
||||||
|
num_meshes: int = 10,
|
||||||
|
max_v: int = 100,
|
||||||
|
max_f: int = 300,
|
||||||
|
lists_to_tensors: bool = False,
|
||||||
|
device: str = "cpu",
|
||||||
|
requires_grad: bool = False,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Function to generate a Meshes object of N meshes with
|
||||||
|
random numbers of vertices and faces.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
num_meshes: Number of meshes to generate.
|
||||||
|
max_v: Max number of vertices per mesh.
|
||||||
|
max_f: Max number of faces per mesh.
|
||||||
|
lists_to_tensors: Determines whether the generated meshes should be
|
||||||
|
constructed from lists (=False) or
|
||||||
|
a tensor (=True) of faces/verts.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Meshes object.
|
||||||
|
"""
|
||||||
|
device = torch.device(device)
|
||||||
|
|
||||||
|
verts_list = []
|
||||||
|
faces_list = []
|
||||||
|
|
||||||
|
# Randomly generate numbers of faces and vertices in each mesh.
|
||||||
|
if lists_to_tensors:
|
||||||
|
# If we define faces/verts with tensors, f/v has to be the
|
||||||
|
# same for each mesh in the batch.
|
||||||
|
f = torch.randint(1, max_f, size=(1,), dtype=torch.int32)
|
||||||
|
v = torch.randint(3, high=max_v, size=(1,), dtype=torch.int32)
|
||||||
|
f = f.repeat(num_meshes)
|
||||||
|
v = v.repeat(num_meshes)
|
||||||
|
else:
|
||||||
|
# For lists of faces and vertices, we can sample different v/f
|
||||||
|
# per mesh.
|
||||||
|
f = torch.randint(max_f, size=(num_meshes,), dtype=torch.int32)
|
||||||
|
v = torch.randint(3, high=max_v, size=(num_meshes,), dtype=torch.int32)
|
||||||
|
|
||||||
|
# Generate the actual vertices and faces.
|
||||||
|
for i in range(num_meshes):
|
||||||
|
verts = torch.rand(
|
||||||
|
(v[i], 3),
|
||||||
|
dtype=torch.float32,
|
||||||
|
device=device,
|
||||||
|
requires_grad=requires_grad,
|
||||||
|
)
|
||||||
|
faces = torch.randint(v[i], size=(f[i], 3), dtype=torch.int64, device=device)
|
||||||
|
verts_list.append(verts)
|
||||||
|
faces_list.append(faces)
|
||||||
|
|
||||||
|
if lists_to_tensors:
|
||||||
|
verts_list = torch.stack(verts_list)
|
||||||
|
faces_list = torch.stack(faces_list)
|
||||||
|
|
||||||
|
return Meshes(verts=verts_list, faces=faces_list)
|
||||||
|
|
||||||
|
|
||||||
|
def init_simple_mesh(device: str = "cpu"):
|
||||||
|
"""
|
||||||
|
Returns a Meshes data structure of simple mesh examples.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Meshes object.
|
||||||
|
"""
|
||||||
|
device = torch.device(device)
|
||||||
|
|
||||||
|
verts = [
|
||||||
|
torch.tensor(
|
||||||
|
[[0.1, 0.3, 0.5], [0.5, 0.2, 0.1], [0.6, 0.8, 0.7]],
|
||||||
|
dtype=torch.float32,
|
||||||
|
device=device,
|
||||||
|
),
|
||||||
|
torch.tensor(
|
||||||
|
[[0.1, 0.3, 0.3], [0.6, 0.7, 0.8], [0.2, 0.3, 0.4], [0.1, 0.5, 0.3]],
|
||||||
|
dtype=torch.float32,
|
||||||
|
device=device,
|
||||||
|
),
|
||||||
|
torch.tensor(
|
||||||
|
[
|
||||||
|
[0.7, 0.3, 0.6],
|
||||||
|
[0.2, 0.4, 0.8],
|
||||||
|
[0.9, 0.5, 0.2],
|
||||||
|
[0.2, 0.3, 0.4],
|
||||||
|
[0.9, 0.3, 0.8],
|
||||||
|
],
|
||||||
|
dtype=torch.float32,
|
||||||
|
device=device,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
faces = [
|
||||||
|
torch.tensor([[0, 1, 2]], dtype=torch.int64, device=device),
|
||||||
|
torch.tensor([[0, 1, 2], [1, 2, 3]], dtype=torch.int64, device=device),
|
||||||
|
torch.tensor(
|
||||||
|
[
|
||||||
|
[1, 2, 0],
|
||||||
|
[0, 1, 3],
|
||||||
|
[2, 3, 1],
|
||||||
|
[4, 3, 2],
|
||||||
|
[4, 0, 1],
|
||||||
|
[4, 3, 1],
|
||||||
|
[4, 2, 1],
|
||||||
|
],
|
||||||
|
dtype=torch.int64,
|
||||||
|
device=device,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
return Meshes(verts=verts, faces=faces)
|
||||||
|
|
||||||
|
|
||||||
class TestMeshes(TestCaseMixin, unittest.TestCase):
|
class TestMeshes(TestCaseMixin, unittest.TestCase):
|
||||||
def setUp(self) -> None:
|
def setUp(self) -> None:
|
||||||
np.random.seed(42)
|
np.random.seed(42)
|
||||||
torch.manual_seed(42)
|
torch.manual_seed(42)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def init_mesh(
|
|
||||||
num_meshes: int = 10,
|
|
||||||
max_v: int = 100,
|
|
||||||
max_f: int = 300,
|
|
||||||
lists_to_tensors: bool = False,
|
|
||||||
device: str = "cpu",
|
|
||||||
requires_grad: bool = False,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
Function to generate a Meshes object of N meshes with
|
|
||||||
random numbers of vertices and faces.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
num_meshes: Number of meshes to generate.
|
|
||||||
max_v: Max number of vertices per mesh.
|
|
||||||
max_f: Max number of faces per mesh.
|
|
||||||
lists_to_tensors: Determines whether the generated meshes should be
|
|
||||||
constructed from lists (=False) or
|
|
||||||
a tensor (=True) of faces/verts.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Meshes object.
|
|
||||||
"""
|
|
||||||
device = torch.device(device)
|
|
||||||
|
|
||||||
verts_list = []
|
|
||||||
faces_list = []
|
|
||||||
|
|
||||||
# Randomly generate numbers of faces and vertices in each mesh.
|
|
||||||
if lists_to_tensors:
|
|
||||||
# If we define faces/verts with tensors, f/v has to be the
|
|
||||||
# same for each mesh in the batch.
|
|
||||||
f = torch.randint(1, max_f, size=(1,), dtype=torch.int32)
|
|
||||||
v = torch.randint(3, high=max_v, size=(1,), dtype=torch.int32)
|
|
||||||
f = f.repeat(num_meshes)
|
|
||||||
v = v.repeat(num_meshes)
|
|
||||||
else:
|
|
||||||
# For lists of faces and vertices, we can sample different v/f
|
|
||||||
# per mesh.
|
|
||||||
f = torch.randint(max_f, size=(num_meshes,), dtype=torch.int32)
|
|
||||||
v = torch.randint(3, high=max_v, size=(num_meshes,), dtype=torch.int32)
|
|
||||||
|
|
||||||
# Generate the actual vertices and faces.
|
|
||||||
for i in range(num_meshes):
|
|
||||||
verts = torch.rand(
|
|
||||||
(v[i], 3),
|
|
||||||
dtype=torch.float32,
|
|
||||||
device=device,
|
|
||||||
requires_grad=requires_grad,
|
|
||||||
)
|
|
||||||
faces = torch.randint(
|
|
||||||
v[i], size=(f[i], 3), dtype=torch.int64, device=device
|
|
||||||
)
|
|
||||||
verts_list.append(verts)
|
|
||||||
faces_list.append(faces)
|
|
||||||
|
|
||||||
if lists_to_tensors:
|
|
||||||
verts_list = torch.stack(verts_list)
|
|
||||||
faces_list = torch.stack(faces_list)
|
|
||||||
|
|
||||||
return Meshes(verts=verts_list, faces=faces_list)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def init_simple_mesh(device: str = "cpu"):
|
|
||||||
"""
|
|
||||||
Returns a Meshes data structure of simple mesh examples.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Meshes object.
|
|
||||||
"""
|
|
||||||
device = torch.device(device)
|
|
||||||
|
|
||||||
verts = [
|
|
||||||
torch.tensor(
|
|
||||||
[[0.1, 0.3, 0.5], [0.5, 0.2, 0.1], [0.6, 0.8, 0.7]],
|
|
||||||
dtype=torch.float32,
|
|
||||||
device=device,
|
|
||||||
),
|
|
||||||
torch.tensor(
|
|
||||||
[[0.1, 0.3, 0.3], [0.6, 0.7, 0.8], [0.2, 0.3, 0.4], [0.1, 0.5, 0.3]],
|
|
||||||
dtype=torch.float32,
|
|
||||||
device=device,
|
|
||||||
),
|
|
||||||
torch.tensor(
|
|
||||||
[
|
|
||||||
[0.7, 0.3, 0.6],
|
|
||||||
[0.2, 0.4, 0.8],
|
|
||||||
[0.9, 0.5, 0.2],
|
|
||||||
[0.2, 0.3, 0.4],
|
|
||||||
[0.9, 0.3, 0.8],
|
|
||||||
],
|
|
||||||
dtype=torch.float32,
|
|
||||||
device=device,
|
|
||||||
),
|
|
||||||
]
|
|
||||||
faces = [
|
|
||||||
torch.tensor([[0, 1, 2]], dtype=torch.int64, device=device),
|
|
||||||
torch.tensor([[0, 1, 2], [1, 2, 3]], dtype=torch.int64, device=device),
|
|
||||||
torch.tensor(
|
|
||||||
[
|
|
||||||
[1, 2, 0],
|
|
||||||
[0, 1, 3],
|
|
||||||
[2, 3, 1],
|
|
||||||
[4, 3, 2],
|
|
||||||
[4, 0, 1],
|
|
||||||
[4, 3, 1],
|
|
||||||
[4, 2, 1],
|
|
||||||
],
|
|
||||||
dtype=torch.int64,
|
|
||||||
device=device,
|
|
||||||
),
|
|
||||||
]
|
|
||||||
return Meshes(verts=verts, faces=faces)
|
|
||||||
|
|
||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
mesh = TestMeshes.init_simple_mesh("cuda:0")
|
mesh = init_simple_mesh("cuda:0")
|
||||||
|
|
||||||
# Check that faces/verts per mesh are set in init:
|
# Check that faces/verts per mesh are set in init:
|
||||||
self.assertClose(mesh._num_faces_per_mesh.cpu(), torch.tensor([1, 2, 7]))
|
self.assertClose(mesh._num_faces_per_mesh.cpu(), torch.tensor([1, 2, 7]))
|
||||||
@ -168,7 +166,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
|
|||||||
# Check if correct errors are raised when verts/faces are on
|
# Check if correct errors are raised when verts/faces are on
|
||||||
# different devices
|
# different devices
|
||||||
|
|
||||||
mesh = TestMeshes.init_mesh(10, 10, 100)
|
mesh = init_mesh(10, 10, 100)
|
||||||
verts_list = mesh.verts_list() # all tensors on cpu
|
verts_list = mesh.verts_list() # all tensors on cpu
|
||||||
verts_list = [
|
verts_list = [
|
||||||
v.to("cuda:0") if random.uniform(0, 1) > 0.5 else v for v in verts_list
|
v.to("cuda:0") if random.uniform(0, 1) > 0.5 else v for v in verts_list
|
||||||
@ -192,7 +190,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
|
|||||||
# Define the test mesh object either as a list or tensor of faces/verts.
|
# Define the test mesh object either as a list or tensor of faces/verts.
|
||||||
for lists_to_tensors in (False, True):
|
for lists_to_tensors in (False, True):
|
||||||
N = 10
|
N = 10
|
||||||
mesh = TestMeshes.init_mesh(N, 100, 300, lists_to_tensors=lists_to_tensors)
|
mesh = init_mesh(N, 100, 300, lists_to_tensors=lists_to_tensors)
|
||||||
verts_list = mesh.verts_list()
|
verts_list = mesh.verts_list()
|
||||||
faces_list = mesh.faces_list()
|
faces_list = mesh.faces_list()
|
||||||
|
|
||||||
@ -361,7 +359,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
|
|||||||
|
|
||||||
def test_clone(self):
|
def test_clone(self):
|
||||||
N = 5
|
N = 5
|
||||||
mesh = TestMeshes.init_mesh(N, 10, 100)
|
mesh = init_mesh(N, 10, 100)
|
||||||
for force in [0, 1]:
|
for force in [0, 1]:
|
||||||
if force:
|
if force:
|
||||||
# force mesh to have computed attributes
|
# force mesh to have computed attributes
|
||||||
@ -386,7 +384,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
|
|||||||
|
|
||||||
def test_detach(self):
|
def test_detach(self):
|
||||||
N = 5
|
N = 5
|
||||||
mesh = TestMeshes.init_mesh(N, 10, 100, requires_grad=True)
|
mesh = init_mesh(N, 10, 100, requires_grad=True)
|
||||||
for force in [0, 1]:
|
for force in [0, 1]:
|
||||||
if force:
|
if force:
|
||||||
# force mesh to have computed attributes
|
# force mesh to have computed attributes
|
||||||
@ -425,7 +423,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
|
|||||||
|
|
||||||
# Note that we don't test with random meshes for this case, as the
|
# Note that we don't test with random meshes for this case, as the
|
||||||
# definition of Laplacian is defined for simple graphs (aka valid meshes)
|
# definition of Laplacian is defined for simple graphs (aka valid meshes)
|
||||||
meshes = TestMeshes.init_simple_mesh("cuda:0")
|
meshes = init_simple_mesh("cuda:0")
|
||||||
|
|
||||||
lapl_naive = naive_laplacian_packed(meshes)
|
lapl_naive = naive_laplacian_packed(meshes)
|
||||||
lapl = meshes.laplacian_packed().to_dense()
|
lapl = meshes.laplacian_packed().to_dense()
|
||||||
@ -443,7 +441,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
|
|||||||
return Meshes(verts=new_verts_list, faces=new_faces_list)
|
return Meshes(verts=new_verts_list, faces=new_faces_list)
|
||||||
|
|
||||||
N = 5
|
N = 5
|
||||||
mesh = TestMeshes.init_mesh(N, 30, 100, lists_to_tensors=True)
|
mesh = init_mesh(N, 30, 100, lists_to_tensors=True)
|
||||||
all_v = mesh.verts_packed().size(0)
|
all_v = mesh.verts_packed().size(0)
|
||||||
verts_per_mesh = mesh.num_verts_per_mesh()
|
verts_per_mesh = mesh.num_verts_per_mesh()
|
||||||
for force, deform_shape in itertools.product([False, True], [(all_v, 3), 3]):
|
for force, deform_shape in itertools.product([False, True], [(all_v, 3), 3]):
|
||||||
@ -577,7 +575,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
|
|||||||
N = 5
|
N = 5
|
||||||
for test in ["tensor", "scalar"]:
|
for test in ["tensor", "scalar"]:
|
||||||
for force in (False, True):
|
for force in (False, True):
|
||||||
mesh = TestMeshes.init_mesh(N, 10, 100, lists_to_tensors=True)
|
mesh = init_mesh(N, 10, 100, lists_to_tensors=True)
|
||||||
if force:
|
if force:
|
||||||
# force mesh to have computed attributes
|
# force mesh to have computed attributes
|
||||||
mesh.verts_packed()
|
mesh.verts_packed()
|
||||||
@ -686,7 +684,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
|
|||||||
|
|
||||||
def test_extend_list(self):
|
def test_extend_list(self):
|
||||||
N = 10
|
N = 10
|
||||||
mesh = TestMeshes.init_mesh(5, 10, 100)
|
mesh = init_mesh(5, 10, 100)
|
||||||
for force in [0, 1]:
|
for force in [0, 1]:
|
||||||
if force:
|
if force:
|
||||||
# force some computes to happen
|
# force some computes to happen
|
||||||
@ -721,7 +719,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
|
|||||||
mesh.extend(N=-1)
|
mesh.extend(N=-1)
|
||||||
|
|
||||||
def test_to(self):
|
def test_to(self):
|
||||||
mesh = TestMeshes.init_mesh(5, 10, 100, device=torch.device("cuda:0"))
|
mesh = init_mesh(5, 10, 100, device=torch.device("cuda:0"))
|
||||||
device = torch.device("cuda:1")
|
device = torch.device("cuda:1")
|
||||||
|
|
||||||
new_mesh = mesh.to(device)
|
new_mesh = mesh.to(device)
|
||||||
@ -729,7 +727,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
|
|||||||
self.assertTrue(mesh.device == torch.device("cuda:0"))
|
self.assertTrue(mesh.device == torch.device("cuda:0"))
|
||||||
|
|
||||||
def test_split_mesh(self):
|
def test_split_mesh(self):
|
||||||
mesh = TestMeshes.init_mesh(5, 10, 100)
|
mesh = init_mesh(5, 10, 100)
|
||||||
split_sizes = [2, 3]
|
split_sizes = [2, 3]
|
||||||
split_meshes = mesh.split(split_sizes)
|
split_meshes = mesh.split(split_sizes)
|
||||||
self.assertTrue(len(split_meshes[0]) == 2)
|
self.assertTrue(len(split_meshes[0]) == 2)
|
||||||
@ -756,9 +754,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
|
|||||||
N = 10
|
N = 10
|
||||||
for lists_to_tensors in (False, True):
|
for lists_to_tensors in (False, True):
|
||||||
for force in (True, False):
|
for force in (True, False):
|
||||||
mesh = TestMeshes.init_mesh(
|
mesh = init_mesh(N, 100, 300, lists_to_tensors=lists_to_tensors)
|
||||||
N, 100, 300, lists_to_tensors=lists_to_tensors
|
|
||||||
)
|
|
||||||
num_verts_per_mesh = mesh.num_verts_per_mesh()
|
num_verts_per_mesh = mesh.num_verts_per_mesh()
|
||||||
if force:
|
if force:
|
||||||
# force mesh to have computed attributes
|
# force mesh to have computed attributes
|
||||||
@ -1166,7 +1162,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
|
|||||||
num_meshes = 10
|
num_meshes = 10
|
||||||
max_v = 100
|
max_v = 100
|
||||||
max_f = 300
|
max_f = 300
|
||||||
mesh_cpu = TestMeshes.init_mesh(num_meshes, max_v, max_f, device="cpu")
|
mesh_cpu = init_mesh(num_meshes, max_v, max_f, device="cpu")
|
||||||
device = torch.device("cuda:0")
|
device = torch.device("cuda:0")
|
||||||
mesh_cuda = mesh_cpu.to(device)
|
mesh_cuda = mesh_cpu.to(device)
|
||||||
|
|
||||||
@ -1187,7 +1183,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
|
|||||||
def compute_packed_with_init(
|
def compute_packed_with_init(
|
||||||
num_meshes: int = 10, max_v: int = 100, max_f: int = 300, device: str = "cpu"
|
num_meshes: int = 10, max_v: int = 100, max_f: int = 300, device: str = "cpu"
|
||||||
):
|
):
|
||||||
mesh = TestMeshes.init_mesh(num_meshes, max_v, max_f, device=device)
|
mesh = init_mesh(num_meshes, max_v, max_f, device=device)
|
||||||
torch.cuda.synchronize()
|
torch.cuda.synchronize()
|
||||||
|
|
||||||
def compute_packed():
|
def compute_packed():
|
||||||
@ -1200,7 +1196,7 @@ class TestMeshes(TestCaseMixin, unittest.TestCase):
|
|||||||
def compute_padded_with_init(
|
def compute_padded_with_init(
|
||||||
num_meshes: int = 10, max_v: int = 100, max_f: int = 300, device: str = "cpu"
|
num_meshes: int = 10, max_v: int = 100, max_f: int = 300, device: str = "cpu"
|
||||||
):
|
):
|
||||||
mesh = TestMeshes.init_mesh(num_meshes, max_v, max_f, device=device)
|
mesh = init_mesh(num_meshes, max_v, max_f, device=device)
|
||||||
torch.cuda.synchronize()
|
torch.cuda.synchronize()
|
||||||
|
|
||||||
def compute_padded():
|
def compute_padded():
|
||||||
|
@ -33,41 +33,41 @@ DEBUG = False
|
|||||||
DATA_DIR = get_tests_dir() / "data"
|
DATA_DIR = get_tests_dir() / "data"
|
||||||
|
|
||||||
|
|
||||||
|
def init_meshes(
|
||||||
|
num_meshes: int = 10,
|
||||||
|
num_verts: int = 1000,
|
||||||
|
num_faces: int = 3000,
|
||||||
|
device: str = "cpu",
|
||||||
|
add_texture: bool = False,
|
||||||
|
):
|
||||||
|
device = torch.device(device)
|
||||||
|
verts_list = []
|
||||||
|
faces_list = []
|
||||||
|
texts_list = []
|
||||||
|
for _ in range(num_meshes):
|
||||||
|
verts = torch.rand((num_verts, 3), dtype=torch.float32, device=device)
|
||||||
|
faces = torch.randint(
|
||||||
|
num_verts, size=(num_faces, 3), dtype=torch.int64, device=device
|
||||||
|
)
|
||||||
|
texts = torch.rand((num_verts, 3), dtype=torch.float32, device=device)
|
||||||
|
verts_list.append(verts)
|
||||||
|
faces_list.append(faces)
|
||||||
|
texts_list.append(texts)
|
||||||
|
|
||||||
|
# create textures
|
||||||
|
textures = None
|
||||||
|
if add_texture:
|
||||||
|
textures = TexturesVertex(texts_list)
|
||||||
|
meshes = Meshes(verts=verts_list, faces=faces_list, textures=textures)
|
||||||
|
|
||||||
|
return meshes
|
||||||
|
|
||||||
|
|
||||||
class TestSamplePoints(TestCaseMixin, unittest.TestCase):
|
class TestSamplePoints(TestCaseMixin, unittest.TestCase):
|
||||||
def setUp(self) -> None:
|
def setUp(self) -> None:
|
||||||
super().setUp()
|
super().setUp()
|
||||||
torch.manual_seed(1)
|
torch.manual_seed(1)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def init_meshes(
|
|
||||||
num_meshes: int = 10,
|
|
||||||
num_verts: int = 1000,
|
|
||||||
num_faces: int = 3000,
|
|
||||||
device: str = "cpu",
|
|
||||||
add_texture: bool = False,
|
|
||||||
):
|
|
||||||
device = torch.device(device)
|
|
||||||
verts_list = []
|
|
||||||
faces_list = []
|
|
||||||
texts_list = []
|
|
||||||
for _ in range(num_meshes):
|
|
||||||
verts = torch.rand((num_verts, 3), dtype=torch.float32, device=device)
|
|
||||||
faces = torch.randint(
|
|
||||||
num_verts, size=(num_faces, 3), dtype=torch.int64, device=device
|
|
||||||
)
|
|
||||||
texts = torch.rand((num_verts, 3), dtype=torch.float32, device=device)
|
|
||||||
verts_list.append(verts)
|
|
||||||
faces_list.append(faces)
|
|
||||||
texts_list.append(texts)
|
|
||||||
|
|
||||||
# create textures
|
|
||||||
textures = None
|
|
||||||
if add_texture:
|
|
||||||
textures = TexturesVertex(texts_list)
|
|
||||||
meshes = Meshes(verts=verts_list, faces=faces_list, textures=textures)
|
|
||||||
|
|
||||||
return meshes
|
|
||||||
|
|
||||||
def test_all_empty_meshes(self):
|
def test_all_empty_meshes(self):
|
||||||
"""
|
"""
|
||||||
Check sample_points_from_meshes raises an exception if all meshes are
|
Check sample_points_from_meshes raises an exception if all meshes are
|
||||||
@ -298,9 +298,7 @@ class TestSamplePoints(TestCaseMixin, unittest.TestCase):
|
|||||||
def test_outputs(self):
|
def test_outputs(self):
|
||||||
|
|
||||||
for add_texture in (True, False):
|
for add_texture in (True, False):
|
||||||
meshes = TestSamplePoints.init_meshes(
|
meshes = init_meshes(device=torch.device("cuda:0"), add_texture=add_texture)
|
||||||
device=torch.device("cuda:0"), add_texture=add_texture
|
|
||||||
)
|
|
||||||
out1 = sample_points_from_meshes(meshes, num_samples=100)
|
out1 = sample_points_from_meshes(meshes, num_samples=100)
|
||||||
self.assertTrue(torch.is_tensor(out1))
|
self.assertTrue(torch.is_tensor(out1))
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ from pytorch3d.renderer.mesh.textures import (
|
|||||||
pack_rectangles,
|
pack_rectangles,
|
||||||
)
|
)
|
||||||
from pytorch3d.structures import Meshes, list_to_packed, packed_to_list
|
from pytorch3d.structures import Meshes, list_to_packed, packed_to_list
|
||||||
from test_meshes import TestMeshes
|
from test_meshes import init_mesh
|
||||||
|
|
||||||
|
|
||||||
def tryindex(self, index, tex, meshes, source):
|
def tryindex(self, index, tex, meshes, source):
|
||||||
@ -173,7 +173,7 @@ class TestTexturesVertex(TestCaseMixin, unittest.TestCase):
|
|||||||
|
|
||||||
def test_extend(self):
|
def test_extend(self):
|
||||||
B = 10
|
B = 10
|
||||||
mesh = TestMeshes.init_mesh(B, 30, 50)
|
mesh = init_mesh(B, 30, 50)
|
||||||
V = mesh._V
|
V = mesh._V
|
||||||
tex_uv = TexturesVertex(verts_features=torch.randn((B, V, 3)))
|
tex_uv = TexturesVertex(verts_features=torch.randn((B, V, 3)))
|
||||||
tex_mesh = Meshes(
|
tex_mesh = Meshes(
|
||||||
@ -379,7 +379,7 @@ class TestTexturesAtlas(TestCaseMixin, unittest.TestCase):
|
|||||||
|
|
||||||
def test_extend(self):
|
def test_extend(self):
|
||||||
B = 10
|
B = 10
|
||||||
mesh = TestMeshes.init_mesh(B, 30, 50)
|
mesh = init_mesh(B, 30, 50)
|
||||||
F = mesh._F
|
F = mesh._F
|
||||||
tex_uv = TexturesAtlas(atlas=torch.randn((B, F, 2, 2, 3)))
|
tex_uv = TexturesAtlas(atlas=torch.randn((B, F, 2, 2, 3)))
|
||||||
tex_mesh = Meshes(
|
tex_mesh = Meshes(
|
||||||
@ -667,7 +667,7 @@ class TestTexturesUV(TestCaseMixin, unittest.TestCase):
|
|||||||
|
|
||||||
def test_extend(self):
|
def test_extend(self):
|
||||||
B = 5
|
B = 5
|
||||||
mesh = TestMeshes.init_mesh(B, 30, 50)
|
mesh = init_mesh(B, 30, 50)
|
||||||
V = mesh._V
|
V = mesh._V
|
||||||
num_faces = mesh.num_faces_per_mesh()
|
num_faces = mesh.num_faces_per_mesh()
|
||||||
num_verts = mesh.num_verts_per_mesh()
|
num_verts = mesh.num_verts_per_mesh()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user