Commit d57daa6f authored by Patrick Labatut's avatar Patrick Labatut Committed by Facebook GitHub Bot
Browse files

Address black + isort fbsource linter warnings

Summary: Address black + isort fbsource linter warnings from D20558374 (previous diff)

Reviewed By: nikhilaravi

Differential Revision: D20558373

fbshipit-source-id: d3607de4a01fb24c0d5269634563a7914bddf1c8
parent eb512ffd
# Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
import unittest
import torch
import torch
from pytorch3d.renderer.compositing import (
alpha_composite,
norm_weighted_sum,
......@@ -37,9 +37,7 @@ class TestAccumulatePoints(unittest.TestCase):
continue
alpha = alphas[b, k, j, i]
output[b, c, j, i] += (
features[c, n_idx] * alpha * t_alpha
)
output[b, c, j, i] += features[c, n_idx] * alpha * t_alpha
t_alpha = (1 - alpha) * t_alpha
return output
......@@ -105,17 +103,13 @@ class TestAccumulatePoints(unittest.TestCase):
continue
alpha = alphas[b, k, j, i]
output[b, c, j, i] += (
features[c, n_idx] * alpha / t_alpha
)
output[b, c, j, i] += features[c, n_idx] * alpha / t_alpha
return output
def test_python(self):
device = torch.device("cpu")
self._simple_alphacomposite(
self.accumulate_alphacomposite_python, device
)
self._simple_alphacomposite(self.accumulate_alphacomposite_python, device)
self._simple_wsum(self.accumulate_weightedsum_python, device)
self._simple_wsumnorm(self.accumulate_weightedsumnorm_python, device)
......@@ -138,9 +132,7 @@ class TestAccumulatePoints(unittest.TestCase):
self._python_vs_cpu_vs_cuda(
self.accumulate_weightedsumnorm_python, norm_weighted_sum
)
self._python_vs_cpu_vs_cuda(
self.accumulate_weightedsum_python, weighted_sum
)
self._python_vs_cpu_vs_cuda(self.accumulate_weightedsum_python, weighted_sum)
def _python_vs_cpu_vs_cuda(self, accumulate_func_python, accumulate_func):
torch.manual_seed(231)
......@@ -208,15 +200,11 @@ class TestAccumulatePoints(unittest.TestCase):
grads2 = [gradsi.grad.data.clone().cpu() for gradsi in grads2]
for i in range(0, len(grads1)):
self.assertTrue(
torch.allclose(grads1[i].cpu(), grads2[i].cpu(), atol=1e-6)
)
self.assertTrue(torch.allclose(grads1[i].cpu(), grads2[i].cpu(), atol=1e-6))
def _simple_wsum(self, accum_func, device):
# Initialise variables
features = torch.Tensor(
[[0.1, 0.4, 0.6, 0.9], [0.1, 0.4, 0.6, 0.9]]
).to(device)
features = torch.Tensor([[0.1, 0.4, 0.6, 0.9], [0.1, 0.4, 0.6, 0.9]]).to(device)
alphas = torch.Tensor(
[
......@@ -285,15 +273,11 @@ class TestAccumulatePoints(unittest.TestCase):
]
).to(device)
self.assertTrue(
torch.allclose(result.cpu(), true_result.cpu(), rtol=1e-3)
)
self.assertTrue(torch.allclose(result.cpu(), true_result.cpu(), rtol=1e-3))
def _simple_wsumnorm(self, accum_func, device):
# Initialise variables
features = torch.Tensor(
[[0.1, 0.4, 0.6, 0.9], [0.1, 0.4, 0.6, 0.9]]
).to(device)
features = torch.Tensor([[0.1, 0.4, 0.6, 0.9], [0.1, 0.4, 0.6, 0.9]]).to(device)
alphas = torch.Tensor(
[
......@@ -362,15 +346,11 @@ class TestAccumulatePoints(unittest.TestCase):
]
).to(device)
self.assertTrue(
torch.allclose(result.cpu(), true_result.cpu(), rtol=1e-3)
)
self.assertTrue(torch.allclose(result.cpu(), true_result.cpu(), rtol=1e-3))
def _simple_alphacomposite(self, accum_func, device):
# Initialise variables
features = torch.Tensor(
[[0.1, 0.4, 0.6, 0.9], [0.1, 0.4, 0.6, 0.9]]
).to(device)
features = torch.Tensor([[0.1, 0.4, 0.6, 0.9], [0.1, 0.4, 0.6, 0.9]]).to(device)
alphas = torch.Tensor(
[
......
# Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
import unittest
import torch
import torch
from pytorch3d.ops import cubify
......@@ -33,9 +33,7 @@ class TestCubify(unittest.TestCase):
# 1st-check
verts, faces = meshes.get_mesh_verts_faces(0)
self.assertTrue(
torch.allclose(faces.max(), torch.tensor([verts.size(0) - 1]))
)
self.assertTrue(torch.allclose(faces.max(), torch.tensor([verts.size(0) - 1])))
self.assertTrue(
torch.allclose(
verts,
......@@ -80,9 +78,7 @@ class TestCubify(unittest.TestCase):
)
# 2nd-check
verts, faces = meshes.get_mesh_verts_faces(1)
self.assertTrue(
torch.allclose(faces.max(), torch.tensor([verts.size(0) - 1]))
)
self.assertTrue(torch.allclose(faces.max(), torch.tensor([verts.size(0) - 1])))
self.assertTrue(
torch.allclose(
verts,
......@@ -275,9 +271,7 @@ class TestCubify(unittest.TestCase):
@staticmethod
def cubify_with_init(batch_size: int, V: int):
device = torch.device("cuda:0")
voxels = torch.rand(
(batch_size, V, V, V), dtype=torch.float32, device=device
)
voxels = torch.rand((batch_size, V, V, V), dtype=torch.float32, device=device)
torch.cuda.synchronize()
def convert():
......
......@@ -2,13 +2,12 @@
import unittest
import torch
import torch
from common_testing import TestCaseMixin
from pytorch3d.ops import mesh_face_areas_normals
from pytorch3d.structures.meshes import Meshes
from common_testing import TestCaseMixin
class TestFaceAreasNormals(TestCaseMixin, unittest.TestCase):
def setUp(self) -> None:
......@@ -27,10 +26,7 @@ class TestFaceAreasNormals(TestCaseMixin, unittest.TestCase):
faces_list = []
for _ in range(num_meshes):
verts = torch.rand(
(num_verts, 3),
dtype=torch.float32,
device=device,
requires_grad=True,
(num_verts, 3), dtype=torch.float32, device=device, requires_grad=True
)
faces = torch.randint(
num_verts, size=(num_faces, 3), dtype=torch.int64, device=device
......@@ -55,9 +51,7 @@ class TestFaceAreasNormals(TestCaseMixin, unittest.TestCase):
v02 = vertices_faces[:, 2] - vertices_faces[:, 0]
normals = torch.cross(v01, v02, dim=1) # (F, 3)
face_areas = normals.norm(dim=-1) / 2
face_normals = torch.nn.functional.normalize(
normals, p=2, dim=1, eps=1e-6
)
face_normals = torch.nn.functional.normalize(normals, p=2, dim=1, eps=1e-6)
return face_areas, face_normals
def _test_face_areas_normals_helper(self, device, dtype=torch.float32):
......@@ -76,10 +70,7 @@ class TestFaceAreasNormals(TestCaseMixin, unittest.TestCase):
verts_torch = verts.detach().clone().to(dtype)
verts_torch.requires_grad = True
faces_torch = faces.detach().clone()
(
areas_torch,
normals_torch,
) = TestFaceAreasNormals.face_areas_normals_python(
(areas_torch, normals_torch) = TestFaceAreasNormals.face_areas_normals_python(
verts_torch, faces_torch
)
self.assertClose(areas_torch, areas, atol=1e-7)
......
# Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
import unittest
import torch
import torch.nn as nn
from common_testing import TestCaseMixin
from pytorch3d import _C
from pytorch3d.ops.graph_conv import (
GraphConv,
gather_scatter,
gather_scatter_python,
)
from pytorch3d.ops.graph_conv import GraphConv, gather_scatter, gather_scatter_python
from pytorch3d.structures.meshes import Meshes
from pytorch3d.utils import ico_sphere
from common_testing import TestCaseMixin
class TestGraphConv(TestCaseMixin, unittest.TestCase):
def test_undirected(self):
......@@ -89,8 +84,7 @@ class TestGraphConv(TestCaseMixin, unittest.TestCase):
w1 = torch.tensor([[-1, -1, -1]], dtype=dtype)
expected_y = torch.tensor(
[[1 + 2 + 3 - 4 - 5 - 6 - 7 - 8 - 9], [4 + 5 + 6], [7 + 8 + 9]],
dtype=dtype,
[[1 + 2 + 3 - 4 - 5 - 6 - 7 - 8 - 9], [4 + 5 + 6], [7 + 8 + 9]], dtype=dtype
)
conv = GraphConv(3, 1, directed=True).to(dtype)
......@@ -126,17 +120,13 @@ class TestGraphConv(TestCaseMixin, unittest.TestCase):
def test_cpu_cuda_tensor_error(self):
device = torch.device("cuda:0")
verts = torch.tensor(
[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
dtype=torch.float32,
device=device,
[[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=torch.float32, device=device
)
edges = torch.tensor([[0, 1], [0, 2]])
conv = GraphConv(3, 1, directed=True).to(torch.float32)
with self.assertRaises(Exception) as err:
conv(verts, edges)
self.assertTrue(
"tensors must be on the same device." in str(err.exception)
)
self.assertTrue("tensors must be on the same device." in str(err.exception))
def test_gather_scatter(self):
"""
......@@ -178,12 +168,10 @@ class TestGraphConv(TestCaseMixin, unittest.TestCase):
backend: str = "cuda",
):
device = torch.device("cuda") if backend == "cuda" else "cpu"
verts_list = torch.tensor(
num_verts * [[0.11, 0.22, 0.33]], device=device
).view(-1, 3)
faces_list = torch.tensor(num_faces * [[1, 2, 3]], device=device).view(
verts_list = torch.tensor(num_verts * [[0.11, 0.22, 0.33]], device=device).view(
-1, 3
)
faces_list = torch.tensor(num_faces * [[1, 2, 3]], device=device).view(-1, 3)
meshes = Meshes(num_meshes * [verts_list], num_meshes * [faces_list])
gconv = GraphConv(gconv_dim, gconv_dim, directed=directed)
gconv.to(device)
......@@ -191,9 +179,7 @@ class TestGraphConv(TestCaseMixin, unittest.TestCase):
total_verts = meshes.verts_packed().shape[0]
# Features.
x = torch.randn(
total_verts, gconv_dim, device=device, requires_grad=True
)
x = torch.randn(total_verts, gconv_dim, device=device, requires_grad=True)
torch.cuda.synchronize()
def run_graph_conv():
......
......@@ -2,8 +2,8 @@
import unittest
from itertools import product
import torch
import torch
from pytorch3d.ops.knn import _knn_points_idx_naive, knn_points_idx
......
# Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
import numpy as np
import unittest
import torch
import numpy as np
import torch
from common_testing import TestCaseMixin
from pytorch3d.renderer.lighting import DirectionalLights, PointLights
from pytorch3d.transforms import RotateAxisAngle
from common_testing import TestCaseMixin
class TestLights(TestCaseMixin, unittest.TestCase):
def test_init_lights(self):
......@@ -56,9 +55,7 @@ class TestLights(TestCaseMixin, unittest.TestCase):
self.assertSeparate(new_prop, prop)
def test_lights_accessor(self):
d_light = DirectionalLights(
ambient_color=((0.0, 0.0, 0.0), (1.0, 1.0, 1.0))
)
d_light = DirectionalLights(ambient_color=((0.0, 0.0, 0.0), (1.0, 1.0, 1.0)))
p_light = PointLights(ambient_color=((0.0, 0.0, 0.0), (1.0, 1.0, 1.0)))
for light in [d_light, p_light]:
# Update element
......@@ -96,14 +93,12 @@ class TestLights(TestCaseMixin, unittest.TestCase):
"""
with self.assertRaises(ValueError):
DirectionalLights(
ambient_color=torch.randn(10, 3),
diffuse_color=torch.randn(15, 3),
ambient_color=torch.randn(10, 3), diffuse_color=torch.randn(15, 3)
)
with self.assertRaises(ValueError):
PointLights(
ambient_color=torch.randn(10, 3),
diffuse_color=torch.randn(15, 3),
ambient_color=torch.randn(10, 3), diffuse_color=torch.randn(15, 3)
)
def test_initialize_lights_dimensions_fail(self):
......@@ -138,8 +133,7 @@ class TestDiffuseLighting(TestCaseMixin, unittest.TestCase):
normals = torch.tensor([0, 0, 1], dtype=torch.float32)
normals = normals[None, None, :]
expected_output = torch.tensor(
[1 / np.sqrt(2), 1 / np.sqrt(2), 1 / np.sqrt(2)],
dtype=torch.float32,
[1 / np.sqrt(2), 1 / np.sqrt(2), 1 / np.sqrt(2)], dtype=torch.float32
)
expected_output = expected_output.view(1, 1, 3).repeat(3, 1, 1)
light = DirectionalLights(diffuse_color=color, direction=direction)
......@@ -169,13 +163,10 @@ class TestDiffuseLighting(TestCaseMixin, unittest.TestCase):
points = torch.tensor([0, 0, 0], dtype=torch.float32)
normals = torch.tensor([0, 0, 1], dtype=torch.float32)
expected_output = torch.tensor(
[1 / np.sqrt(2), 1 / np.sqrt(2), 1 / np.sqrt(2)],
dtype=torch.float32,
[1 / np.sqrt(2), 1 / np.sqrt(2), 1 / np.sqrt(2)], dtype=torch.float32
)
expected_output = expected_output.view(-1, 1, 3)
light = PointLights(
diffuse_color=color[None, :], location=location[None, :]
)
light = PointLights(diffuse_color=color[None, :], location=location[None, :])
output_light = light.diffuse(
points=points[None, None, :], normals=normals[None, None, :]
)
......@@ -184,9 +175,7 @@ class TestDiffuseLighting(TestCaseMixin, unittest.TestCase):
# Change light direction to be 90 degrees apart from normal direction.
location = torch.tensor([0, 1, 0], dtype=torch.float32)
expected_output = torch.zeros_like(expected_output)
light = PointLights(
diffuse_color=color[None, :], location=location[None, :]
)
light = PointLights(diffuse_color=color[None, :], location=location[None, :])
output_light = light.diffuse(
points=points[None, None, :], normals=normals[None, None, :]
)
......@@ -204,8 +193,7 @@ class TestDiffuseLighting(TestCaseMixin, unittest.TestCase):
)
normals = torch.tensor([0, 0, 1], dtype=torch.float32)
expected_out = torch.tensor(
[1 / np.sqrt(2), 1 / np.sqrt(2), 1 / np.sqrt(2)],
dtype=torch.float32,
[1 / np.sqrt(2), 1 / np.sqrt(2), 1 / np.sqrt(2)], dtype=torch.float32
)
# Reshape
......@@ -231,8 +219,7 @@ class TestDiffuseLighting(TestCaseMixin, unittest.TestCase):
)
normals = torch.tensor([0, 0, 1], dtype=torch.float32)
expected_out = torch.tensor(
[1 / np.sqrt(2), 1 / np.sqrt(2), 1 / np.sqrt(2)],
dtype=torch.float32,
[1 / np.sqrt(2), 1 / np.sqrt(2), 1 / np.sqrt(2)], dtype=torch.float32
)
# Reshape
......@@ -258,9 +245,7 @@ class TestDiffuseLighting(TestCaseMixin, unittest.TestCase):
device = torch.device("cuda:0")
color = torch.tensor([1, 1, 1], dtype=torch.float32, device=device)
direction = torch.tensor(
[0, 1 / np.sqrt(2), 1 / np.sqrt(2)],
dtype=torch.float32,
device=device,
[0, 1 / np.sqrt(2), 1 / np.sqrt(2)], dtype=torch.float32, device=device
)
normals = torch.tensor([0, 0, 1], dtype=torch.float32, device=device)
normals = normals.view(1, 1, 1, 1, 3).expand(N, H, W, K, -1)
......@@ -373,9 +358,7 @@ class TestSpecularLighting(TestCaseMixin, unittest.TestCase):
normals = torch.tensor([0, 1, 0], dtype=torch.float32)
expected_output = torch.tensor([1.0, 0.0, 1.0], dtype=torch.float32)
expected_output = expected_output.view(-1, 1, 3)
lights = PointLights(
specular_color=color[None, :], location=location[None, :]
)
lights = PointLights(specular_color=color[None, :], location=location[None, :])
output_light = lights.specular(
points=points[None, None, :],
normals=normals[None, None, :],
......@@ -528,8 +511,7 @@ class TestSpecularLighting(TestCaseMixin, unittest.TestCase):
mesh_to_vert_idx = torch.tensor(mesh_to_vert_idx, dtype=torch.int64)
color = torch.tensor([[1, 1, 1], [1, 0, 1]], dtype=torch.float32)
direction = torch.tensor(
[[-1 / np.sqrt(2), 1 / np.sqrt(2), 0], [-1, 1, 0]],
dtype=torch.float32,
[[-1 / np.sqrt(2), 1 / np.sqrt(2), 0], [-1, 1, 0]], dtype=torch.float32
)
camera_position = torch.tensor(
[
......
# Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
import unittest
import torch
from pytorch3d.renderer.materials import Materials
import torch
from common_testing import TestCaseMixin
from pytorch3d.renderer.materials import Materials
class TestMaterials(TestCaseMixin, unittest.TestCase):
......@@ -64,8 +63,7 @@ class TestMaterials(TestCaseMixin, unittest.TestCase):
"""
with self.assertRaises(ValueError):
Materials(
ambient_color=torch.randn(10, 3),
diffuse_color=torch.randn(15, 3),
ambient_color=torch.randn(10, 3), diffuse_color=torch.randn(15, 3)
)
def test_initialize_materials_dimensions_fail(self):
......@@ -80,16 +78,12 @@ class TestMaterials(TestCaseMixin, unittest.TestCase):
Materials(shininess=torch.randn(10, 2))
def test_initialize_materials_mixed_inputs(self):
mat = Materials(
ambient_color=torch.randn(1, 3), diffuse_color=((1, 1, 1),)
)
mat = Materials(ambient_color=torch.randn(1, 3), diffuse_color=((1, 1, 1),))
self.assertTrue(mat.ambient_color.shape == (1, 3))
self.assertTrue(mat.diffuse_color.shape == (1, 3))
def test_initialize_materials_mixed_inputs_broadcast(self):
mat = Materials(
ambient_color=torch.randn(10, 3), diffuse_color=((1, 1, 1),)
)
mat = Materials(ambient_color=torch.randn(10, 3), diffuse_color=((1, 1, 1),))
self.assertTrue(mat.ambient_color.shape == (10, 3))
self.assertTrue(mat.diffuse_color.shape == (10, 3))
self.assertTrue(mat.specular_color.shape == (10, 3))
......
# Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
import unittest
import torch
import torch
from common_testing import TestCaseMixin
from pytorch3d.loss import mesh_edge_loss
from pytorch3d.structures import Meshes
from common_testing import TestCaseMixin
from test_sample_points_from_meshes import TestSamplePoints
......@@ -27,9 +26,7 @@ class TestMeshEdgeLoss(TestCaseMixin, unittest.TestCase):
mesh = Meshes(verts=verts_list, faces=faces_list)
loss = mesh_edge_loss(mesh, target_length=target_length)
self.assertClose(
loss, torch.tensor([0.0], dtype=torch.float32, device=device)
)
self.assertClose(loss, torch.tensor([0.0], dtype=torch.float32, device=device))
self.assertTrue(loss.requires_grad)
@staticmethod
......@@ -53,9 +50,7 @@ class TestMeshEdgeLoss(TestCaseMixin, unittest.TestCase):
num_edges = mesh_edges.size(0)
for e in range(num_edges):
v0, v1 = verts_edges[e, 0], verts_edges[e, 1]
predlosses[b] += (
(v0 - v1).norm(dim=0, p=2) - target_length
) ** 2.0
predlosses[b] += ((v0 - v1).norm(dim=0, p=2) - target_length) ** 2.0
if num_edges > 0:
predlosses[b] = predlosses[b] / num_edges
......@@ -96,12 +91,8 @@ class TestMeshEdgeLoss(TestCaseMixin, unittest.TestCase):
self.assertClose(loss, predloss)
@staticmethod
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"
)
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")
torch.cuda.synchronize()
def compute_loss():
......
......@@ -2,8 +2,8 @@
import unittest
import torch
import torch
from pytorch3d.loss.mesh_laplacian_smoothing import mesh_laplacian_smoothing
from pytorch3d.structures.meshes import Meshes
......@@ -56,9 +56,7 @@ class TestLaplacianSmoothing(unittest.TestCase):
V = verts_packed.shape[0]
L = torch.zeros((V, V), dtype=torch.float32, device=meshes.device)
inv_areas = torch.zeros(
(V, 1), dtype=torch.float32, device=meshes.device
)
inv_areas = torch.zeros((V, 1), dtype=torch.float32, device=meshes.device)
for f in faces_packed:
v0 = verts_packed[f[0], :]
......@@ -69,9 +67,7 @@ class TestLaplacianSmoothing(unittest.TestCase):
C = (v0 - v1).norm()
s = 0.5 * (A + B + C)
face_area = (
(s * (s - A) * (s - B) * (s - C)).clamp_(min=1e-12).sqrt()
)
face_area = (s * (s - A) * (s - B) * (s - C)).clamp_(min=1e-12).sqrt()
inv_areas[f[0]] += face_area
inv_areas[f[1]] += face_area
inv_areas[f[2]] += face_area
......@@ -114,16 +110,13 @@ class TestLaplacianSmoothing(unittest.TestCase):
return loss.sum() / len(meshes)
@staticmethod
def init_meshes(
num_meshes: int = 10, num_verts: int = 1000, num_faces: int = 3000
):
def init_meshes(num_meshes: int = 10, num_verts: int = 1000, num_faces: int = 3000):
device = torch.device("cuda:0")
verts_list = []
faces_list = []
for _ in range(num_meshes):
verts = (
torch.rand((num_verts, 3), dtype=torch.float32, device=device)
* 2.0
torch.rand((num_verts, 3), dtype=torch.float32, device=device) * 2.0
- 1.0
) # verts in the space of [-1, 1]
faces = torch.stack(
......@@ -148,9 +141,7 @@ class TestLaplacianSmoothing(unittest.TestCase):
# feats in list
out = mesh_laplacian_smoothing(meshes, method="uniform")
naive_out = TestLaplacianSmoothing.laplacian_smoothing_naive_uniform(
meshes
)
naive_out = TestLaplacianSmoothing.laplacian_smoothing_naive_uniform(meshes)
self.assertTrue(torch.allclose(out, naive_out))
......@@ -190,9 +181,7 @@ class TestLaplacianSmoothing(unittest.TestCase):
verts_list = []
faces_list = []
for _ in range(num_meshes):
verts = torch.rand(
(num_verts, 3), dtype=torch.float32, device=device
)
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
)
......
......@@ -2,8 +2,8 @@
import unittest
import torch
import torch
from pytorch3d.loss.mesh_normal_consistency import mesh_normal_consistency
from pytorch3d.structures.meshes import Meshes
from pytorch3d.utils.ico_sphere import ico_sphere
......@@ -33,17 +33,14 @@ class TestMeshNormalConsistency(unittest.TestCase):
return faces
@staticmethod
def init_meshes(
num_meshes: int = 10, num_verts: int = 1000, num_faces: int = 3000
):
def init_meshes(num_meshes: int = 10, num_verts: int = 1000, num_faces: int = 3000):
device = torch.device("cuda:0")
valid_faces = TestMeshNormalConsistency.init_faces(num_verts).to(device)
verts_list = []
faces_list = []
for _ in range(num_meshes):
verts = (
torch.rand((num_verts, 3), dtype=torch.float32, device=device)
* 2.0
torch.rand((num_verts, 3), dtype=torch.float32, device=device) * 2.0
- 1.0
) # verts in the space of [-1, 1]
"""
......@@ -105,8 +102,7 @@ class TestMeshNormalConsistency(unittest.TestCase):
(
1
- torch.cosine_similarity(
normals[i].view(1, 3),
-normals[j].view(1, 3),
normals[i].view(1, 3), -normals[j].view(1, 3)
)
)
)
......@@ -137,9 +133,7 @@ class TestMeshNormalConsistency(unittest.TestCase):
device = torch.device("cuda:0")
# mesh1 shown above
verts1 = torch.rand((4, 3), dtype=torch.float32, device=device)
faces1 = torch.tensor(
[[0, 1, 2], [2, 1, 3]], dtype=torch.int64, device=device
)
faces1 = torch.tensor([[0, 1, 2], [2, 1, 3]], dtype=torch.int64, device=device)
# mesh2 is a cuboid with 8 verts, 12 faces and 18 edges
verts2 = torch.tensor(
......@@ -181,9 +175,7 @@ class TestMeshNormalConsistency(unittest.TestCase):
[[0, 1, 2], [2, 1, 3], [2, 1, 4]], dtype=torch.int64, device=device
)
meshes = Meshes(
verts=[verts1, verts2, verts3], faces=[faces1, faces2, faces3]
)
meshes = Meshes(verts=[verts1, verts2, verts3], faces=[faces1, faces2, faces3])
# mesh1: normal consistency computation
n0 = (verts1[1] - verts1[2]).cross(verts1[3] - verts1[2])
......
......@@ -2,8 +2,8 @@
import unittest
import torch
import torch
from pytorch3d.renderer.mesh.utils import _clip_barycentric_coordinates
......
This diff is collapsed.
......@@ -2,8 +2,8 @@
import unittest
from itertools import product
import torch
import torch
from pytorch3d import _C
......@@ -33,9 +33,7 @@ class TestNearestNeighborPoints(unittest.TestCase):
# to the cpp or cuda versions of the function
# depending on the input type.
idx1 = _C.nn_points_idx(x, y)
idx2 = TestNearestNeighborPoints.nn_points_idx_naive(
x, y
)
idx2 = TestNearestNeighborPoints.nn_points_idx_naive(x, y)
self.assertTrue(idx1.size(1) == P1)
self.assertTrue(torch.all(idx1 == idx2))
......
......@@ -4,14 +4,13 @@ import os
import unittest
from io import StringIO
from pathlib import Path
import torch
import torch
from common_testing import TestCaseMixin
from pytorch3d.io import load_obj, load_objs_as_meshes, save_obj
from pytorch3d.structures import Meshes, Textures, join_meshes
from pytorch3d.utils import torus
from common_testing import TestCaseMixin
class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
def test_load_obj_simple(self):
......@@ -34,12 +33,7 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
tex_maps = aux.texture_images
expected_verts = torch.tensor(
[
[0.1, 0.2, 0.3],
[0.2, 0.3, 0.4],
[0.3, 0.4, 0.5],
[0.4, 0.5, 0.6],
],
[[0.1, 0.2, 0.3], [0.2, 0.3, 0.4], [0.3, 0.4, 0.5], [0.4, 0.5, 0.6]],
dtype=torch.float32,
)
expected_faces = torch.tensor(
......@@ -124,12 +118,8 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
[[0.749279, 0.501284], [0.999110, 0.501077], [0.999455, 0.750380]],
dtype=torch.float32,
)
expected_faces_normals_idx = torch.tensor(
[[1, 1, 1]], dtype=torch.int64
)
expected_faces_textures_idx = torch.tensor(
[[0, 0, 1]], dtype=torch.int64
)
expected_faces_normals_idx = torch.tensor([[1, 1, 1]], dtype=torch.int64)
expected_faces_textures_idx = torch.tensor([[0, 0, 1]], dtype=torch.int64)
self.assertTrue(torch.all(verts == expected_verts))
self.assertTrue(torch.all(faces.verts_idx == expected_faces))
......@@ -153,23 +143,13 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
]
)
obj_file = StringIO(obj_file)
expected_faces_normals_idx = torch.tensor(
[[0, 0, 1]], dtype=torch.int64
)
expected_faces_normals_idx = torch.tensor([[0, 0, 1]], dtype=torch.int64)
expected_normals = torch.tensor(
[
[0.000000, 0.000000, -1.000000],
[-1.000000, -0.000000, -0.000000],
],
[[0.000000, 0.000000, -1.000000], [-1.000000, -0.000000, -0.000000]],
dtype=torch.float32,
)
expected_verts = torch.tensor(
[
[0.1, 0.2, 0.3],
[0.2, 0.3, 0.4],
[0.3, 0.4, 0.5],
[0.4, 0.5, 0.6],
],
[[0.1, 0.2, 0.3], [0.2, 0.3, 0.4], [0.3, 0.4, 0.5], [0.4, 0.5, 0.6]],
dtype=torch.float32,
)
verts, faces, aux = load_obj(obj_file)
......@@ -198,19 +178,12 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
]
)
obj_file = StringIO(obj_file)
expected_faces_textures_idx = torch.tensor(
[[0, 0, 1]], dtype=torch.int64
)
expected_faces_textures_idx = torch.tensor([[0, 0, 1]], dtype=torch.int64)
expected_textures = torch.tensor(
[[0.999110, 0.501077], [0.999455, 0.750380]], dtype=torch.float32
)
expected_verts = torch.tensor(
[
[0.1, 0.2, 0.3],
[0.2, 0.3, 0.4],
[0.3, 0.4, 0.5],
[0.4, 0.5, 0.6],
],
[[0.1, 0.2, 0.3], [0.2, 0.3, 0.4], [0.3, 0.4, 0.5], [0.4, 0.5, 0.6]],
dtype=torch.float32,
)
verts, faces, aux = load_obj(obj_file)
......@@ -257,9 +230,7 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
with self.assertRaises(ValueError) as err:
load_obj(obj_file)
self.assertTrue(
"Vertex properties are inconsistent" in str(err.exception)
)
self.assertTrue("Vertex properties are inconsistent" in str(err.exception))
def test_load_obj_error_too_many_vertex_properties(self):
obj_file = "\n".join(["f 2/1/1/3"])
......@@ -267,9 +238,7 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
with self.assertRaises(ValueError) as err:
load_obj(obj_file)
self.assertTrue(
"Face vertices can ony have 3 properties" in str(err.exception)
)
self.assertTrue("Face vertices can ony have 3 properties" in str(err.exception))
def test_load_obj_error_invalid_vertex_indices(self):
obj_file = "\n".join(
......@@ -320,7 +289,9 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
verts = torch.FloatTensor([[0.1, 0.2, 0.3, 0.4]]) # (V, 4)
faces = torch.LongTensor([[0, 1, 2]])
save_obj(StringIO(), verts, faces)
expected_message = "Argument 'verts' should either be empty or of shape (num_verts, 3)."
expected_message = (
"Argument 'verts' should either be empty or of shape (num_verts, 3)."
)
self.assertTrue(expected_message, error.exception)
# Invalid faces shape
......@@ -328,7 +299,9 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
verts = torch.FloatTensor([[0.1, 0.2, 0.3]])
faces = torch.LongTensor([[0, 1, 2, 3]]) # (F, 4)
save_obj(StringIO(), verts, faces)
expected_message = "Argument 'faces' should either be empty or of shape (num_faces, 3)."
expected_message = (
"Argument 'faces' should either be empty or of shape (num_faces, 3)."
)
self.assertTrue(expected_message, error.exception)
def test_save_obj_invalid_indices(self):
......@@ -395,12 +368,7 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
def test_save_obj(self):
verts = torch.tensor(
[
[0.01, 0.2, 0.301],
[0.2, 0.03, 0.408],
[0.3, 0.4, 0.05],
[0.6, 0.7, 0.8],
],
[[0.01, 0.2, 0.301], [0.2, 0.03, 0.408], [0.3, 0.4, 0.05], [0.6, 0.7, 0.8]],
dtype=torch.float32,
)
faces = torch.tensor(
......@@ -424,9 +392,7 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
self.assertEqual(actual_file, expected_file)
def test_load_mtl(self):
DATA_DIR = (
Path(__file__).resolve().parent.parent / "docs/tutorials/data"
)
DATA_DIR = Path(__file__).resolve().parent.parent / "docs/tutorials/data"
obj_filename = "cow_mesh/cow.obj"
filename = os.path.join(DATA_DIR, obj_filename)
verts, faces, aux = load_obj(filename)
......@@ -452,19 +418,13 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
# Check all keys and values in dictionary are the same.
for n1, n2 in zip(materials.keys(), expected_materials.keys()):
self.assertTrue(n1 == n2)
for k1, k2 in zip(
materials[n1].keys(), expected_materials[n2].keys()
):
for k1, k2 in zip(materials[n1].keys(), expected_materials[n2].keys()):
self.assertTrue(
torch.allclose(
materials[n1][k1], expected_materials[n2][k2]
)
torch.allclose(materials[n1][k1], expected_materials[n2][k2])
)
def test_load_mtl_noload(self):
DATA_DIR = (
Path(__file__).resolve().parent.parent / "docs/tutorials/data"
)
DATA_DIR = Path(__file__).resolve().parent.parent / "docs/tutorials/data"
obj_filename = "cow_mesh/cow.obj"
filename = os.path.join(DATA_DIR, obj_filename)
verts, faces, aux = load_obj(filename, load_textures=False)
......@@ -490,12 +450,7 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
verts, faces, aux = load_obj(obj_file)
expected_verts = torch.tensor(
[
[0.1, 0.2, 0.3],
[0.2, 0.3, 0.4],
[0.3, 0.4, 0.5],
[0.4, 0.5, 0.6],
],
[[0.1, 0.2, 0.3], [0.2, 0.3, 0.4], [0.3, 0.4, 0.5], [0.4, 0.5, 0.6]],
dtype=torch.float32,
)
expected_faces = torch.tensor([[0, 1, 2], [0, 1, 3]], dtype=torch.int64)
......@@ -514,12 +469,7 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
verts, faces, aux = load_obj(filename)
expected_verts = torch.tensor(
[
[0.1, 0.2, 0.3],
[0.2, 0.3, 0.4],
[0.3, 0.4, 0.5],
[0.4, 0.5, 0.6],
],
[[0.1, 0.2, 0.3], [0.2, 0.3, 0.4], [0.3, 0.4, 0.5], [0.4, 0.5, 0.6]],
dtype=torch.float32,
)
expected_faces = torch.tensor([[0, 1, 2], [0, 1, 3]], dtype=torch.int64)
......@@ -533,12 +483,7 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
verts, faces, aux = load_obj(filename, load_textures=False)
expected_verts = torch.tensor(
[
[0.1, 0.2, 0.3],
[0.2, 0.3, 0.4],
[0.3, 0.4, 0.5],
[0.4, 0.5, 0.6],
],
[[0.1, 0.2, 0.3], [0.2, 0.3, 0.4], [0.3, 0.4, 0.5], [0.4, 0.5, 0.6]],
dtype=torch.float32,
)
expected_faces = torch.tensor([[0, 1, 2], [0, 1, 3]], dtype=torch.int64)
......@@ -555,12 +500,7 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
verts, faces, aux = load_obj(filename)
expected_verts = torch.tensor(
[
[0.1, 0.2, 0.3],
[0.2, 0.3, 0.4],
[0.3, 0.4, 0.5],
[0.4, 0.5, 0.6],
],
[[0.1, 0.2, 0.3], [0.2, 0.3, 0.4], [0.3, 0.4, 0.5], [0.4, 0.5, 0.6]],
dtype=torch.float32,
)
expected_faces = torch.tensor([[0, 1, 2], [0, 1, 3]], dtype=torch.int64)
......@@ -574,12 +514,7 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
verts, faces, aux = load_obj(filename, load_textures=False)
expected_verts = torch.tensor(
[
[0.1, 0.2, 0.3],
[0.2, 0.3, 0.4],
[0.3, 0.4, 0.5],
[0.4, 0.5, 0.6],
],
[[0.1, 0.2, 0.3], [0.2, 0.3, 0.4], [0.3, 0.4, 0.5], [0.4, 0.5, 0.6]],
dtype=torch.float32,
)
expected_faces = torch.tensor([[0, 1, 2], [0, 1, 3]], dtype=torch.int64)
......@@ -607,33 +542,24 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
check_item(mesh.verts_padded(), mesh3.verts_padded())
check_item(mesh.faces_padded(), mesh3.faces_padded())
if mesh.textures is not None:
check_item(mesh.textures.maps_padded(), mesh3.textures.maps_padded())
check_item(
mesh.textures.maps_padded(), mesh3.textures.maps_padded()
mesh.textures.faces_uvs_padded(), mesh3.textures.faces_uvs_padded()
)
check_item(
mesh.textures.faces_uvs_padded(),
mesh3.textures.faces_uvs_padded(),
mesh.textures.verts_uvs_padded(), mesh3.textures.verts_uvs_padded()
)
check_item(
mesh.textures.verts_uvs_padded(),
mesh3.textures.verts_uvs_padded(),
)
check_item(
mesh.textures.verts_rgb_padded(),
mesh3.textures.verts_rgb_padded(),
mesh.textures.verts_rgb_padded(), mesh3.textures.verts_rgb_padded()
)
DATA_DIR = (
Path(__file__).resolve().parent.parent / "docs/tutorials/data"
)
DATA_DIR = Path(__file__).resolve().parent.parent / "docs/tutorials/data"
obj_filename = DATA_DIR / "cow_mesh/cow.obj"
mesh = load_objs_as_meshes([obj_filename])
mesh3 = load_objs_as_meshes([obj_filename, obj_filename, obj_filename])
check_triple(mesh, mesh3)
self.assertTupleEqual(
mesh.textures.maps_padded().shape, (1, 1024, 1024, 3)
)
self.assertTupleEqual(mesh.textures.maps_padded().shape, (1, 1024, 1024, 3))
mesh_notex = load_objs_as_meshes([obj_filename], load_textures=False)
mesh3_notex = load_objs_as_meshes(
......@@ -655,9 +581,7 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
teapot_obj = DATA_DIR / "teapot.obj"
mesh_teapot = load_objs_as_meshes([teapot_obj])
teapot_verts, teapot_faces = mesh_teapot.get_mesh_verts_faces(0)
mix_mesh = load_objs_as_meshes(
[obj_filename, teapot_obj], load_textures=False
)
mix_mesh = load_objs_as_meshes([obj_filename, teapot_obj], load_textures=False)
self.assertEqual(len(mix_mesh), 2)
self.assertClose(mix_mesh.verts_list()[0], mesh.verts_list()[0])
self.assertClose(mix_mesh.faces_list()[0], mesh.faces_list()[0])
......@@ -671,15 +595,11 @@ class TestMeshObjIO(TestCaseMixin, unittest.TestCase):
self.assertClose(cow3_tea.faces_list()[3], mesh_teapot.faces_list()[0])
@staticmethod
def _bm_save_obj(
verts: torch.Tensor, faces: torch.Tensor, decimal_places: int
):
def _bm_save_obj(verts: torch.Tensor, faces: torch.Tensor, decimal_places: int):
return lambda: save_obj(StringIO(), verts, faces, decimal_places)
@staticmethod
def _bm_load_obj(
verts: torch.Tensor, faces: torch.Tensor, decimal_places: int
):
def _bm_load_obj(verts: torch.Tensor, faces: torch.Tensor, decimal_places: int):
f = StringIO()
save_obj(f, verts, faces, decimal_places)
s = f.getvalue()
......
# Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
import unittest
import torch
import torch
from common_testing import TestCaseMixin
from pytorch3d.ops import packed_to_padded, padded_to_packed
from pytorch3d.structures.meshes import Meshes
from common_testing import TestCaseMixin
class TestPackedToPadded(TestCaseMixin, unittest.TestCase):
def setUp(self) -> None:
......@@ -25,9 +24,7 @@ class TestPackedToPadded(TestCaseMixin, unittest.TestCase):
verts_list = []
faces_list = []
for _ in range(num_meshes):
verts = torch.rand(
(num_verts, 3), dtype=torch.float32, device=device
)
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
)
......@@ -47,9 +44,7 @@ class TestPackedToPadded(TestCaseMixin, unittest.TestCase):
if D == 0:
inputs_padded = torch.zeros((num_meshes, max_size), device=device)
else:
inputs_padded = torch.zeros(
(num_meshes, max_size, D), device=device
)
inputs_padded = torch.zeros((num_meshes, max_size, D), device=device)
for m in range(num_meshes):
s = first_idxs[m]
if m == num_meshes - 1:
......@@ -92,13 +87,9 @@ class TestPackedToPadded(TestCaseMixin, unittest.TestCase):
max_faces = meshes.num_faces_per_mesh().max().item()
if D == 0:
values = torch.rand(
(faces.shape[0],), device=device, requires_grad=True
)
values = torch.rand((faces.shape[0],), device=device, requires_grad=True)
else:
values = torch.rand(
(faces.shape[0], D), device=device, requires_grad=True
)
values = torch.rand((faces.shape[0], D), device=device, requires_grad=True)
values_torch = values.detach().clone()
values_torch.requires_grad = True
values_padded = packed_to_padded(
......@@ -120,10 +111,7 @@ class TestPackedToPadded(TestCaseMixin, unittest.TestCase):
values_padded_torch.backward(grad_inputs)
grad_outputs_torch1 = values_torch.grad
grad_outputs_torch2 = TestPackedToPadded.padded_to_packed_python(
grad_inputs,
mesh_to_faces_packed_first_idx,
values.size(0),
device=device,
grad_inputs, mesh_to_faces_packed_first_idx, values.size(0), device=device
)
self.assertClose(grad_outputs, grad_outputs_torch1)
self.assertClose(grad_outputs, grad_outputs_torch2)
......@@ -165,9 +153,7 @@ class TestPackedToPadded(TestCaseMixin, unittest.TestCase):
values_torch = values.detach().clone()
values_torch.requires_grad = True
values_packed = padded_to_packed(
values,
mesh_to_faces_packed_first_idx,
num_faces_per_mesh.sum().item(),
values, mesh_to_faces_packed_first_idx, num_faces_per_mesh.sum().item()
)
values_packed_torch = TestPackedToPadded.padded_to_packed_python(
values_torch,
......@@ -180,9 +166,7 @@ class TestPackedToPadded(TestCaseMixin, unittest.TestCase):
# check backward
if D == 0:
grad_inputs = torch.rand(
(num_faces_per_mesh.sum().item()), device=device
)
grad_inputs = torch.rand((num_faces_per_mesh.sum().item()), device=device)
else:
grad_inputs = torch.rand(
(num_faces_per_mesh.sum().item(), D), device=device
......@@ -192,10 +176,7 @@ class TestPackedToPadded(TestCaseMixin, unittest.TestCase):
values_packed_torch.backward(grad_inputs)
grad_outputs_torch1 = values_torch.grad
grad_outputs_torch2 = TestPackedToPadded.packed_to_padded_python(
grad_inputs,
mesh_to_faces_packed_first_idx,
values.size(1),
device=device,
grad_inputs, mesh_to_faces_packed_first_idx, values.size(1), device=device
)
self.assertClose(grad_outputs, grad_outputs_torch1)
self.assertClose(grad_outputs, grad_outputs_torch2)
......@@ -219,34 +200,24 @@ class TestPackedToPadded(TestCaseMixin, unittest.TestCase):
self._test_padded_to_packed_helper(16, "cuda:0")
def test_invalid_inputs_shapes(self, device="cuda:0"):
with self.assertRaisesRegex(
ValueError, "input can only be 2-dimensional."
):
with self.assertRaisesRegex(ValueError, "input can only be 2-dimensional."):
values = torch.rand((100, 50, 2), device=device)
first_idxs = torch.tensor([0, 80], dtype=torch.int64, device=device)
packed_to_padded(values, first_idxs, 100)
with self.assertRaisesRegex(
ValueError, "input can only be 3-dimensional."
):
with self.assertRaisesRegex(ValueError, "input can only be 3-dimensional."):
values = torch.rand((100,), device=device)
first_idxs = torch.tensor([0, 80], dtype=torch.int64, device=device)
padded_to_packed(values, first_idxs, 20)
with self.assertRaisesRegex(
ValueError, "input can only be 3-dimensional."
):
with self.assertRaisesRegex(ValueError, "input can only be 3-dimensional."):
values = torch.rand((100, 50, 2, 2), device=device)
first_idxs = torch.tensor([0, 80], dtype=torch.int64, device=device)
padded_to_packed(values, first_idxs, 20)
@staticmethod
def packed_to_padded_with_init(
num_meshes: int,
num_verts: int,
num_faces: int,
num_d: int,
device: str = "cpu",
num_meshes: int, num_verts: int, num_faces: int, num_d: int, device: str = "cpu"
):
meshes = TestPackedToPadded.init_meshes(
num_meshes, num_verts, num_faces, device
......@@ -268,11 +239,7 @@ class TestPackedToPadded(TestCaseMixin, unittest.TestCase):
@staticmethod
def packed_to_padded_with_init_torch(
num_meshes: int,
num_verts: int,
num_faces: int,
num_d: int,
device: str = "cpu",
num_meshes: int, num_verts: int, num_faces: int, num_d: int, device: str = "cpu"
):
meshes = TestPackedToPadded.init_meshes(
num_meshes, num_verts, num_faces, device
......
......@@ -3,13 +3,12 @@
import struct
import unittest
from io import BytesIO, StringIO
import torch
import torch
from common_testing import TestCaseMixin
from pytorch3d.io.ply_io import _load_ply_raw, load_ply, save_ply
from pytorch3d.utils import torus
from common_testing import TestCaseMixin
class TestMeshPlyIO(TestCaseMixin, unittest.TestCase):
def test_raw_load_simple_ascii(self):
......@@ -155,14 +154,7 @@ class TestMeshPlyIO(TestCaseMixin, unittest.TestCase):
def test_load_simple_binary(self):
for big_endian in [True, False]:
verts = (
"0 0 0 "
"0 0 1 "
"0 1 1 "
"0 1 0 "
"1 0 0 "
"1 0 1 "
"1 1 1 "
"1 1 0"
"0 0 0 " "0 0 1 " "0 1 1 " "0 1 0 " "1 0 0 " "1 0 1 " "1 1 1 " "1 1 0"
).split()
faces = (
"4 0 1 2 3 "
......@@ -176,9 +168,7 @@ class TestMeshPlyIO(TestCaseMixin, unittest.TestCase):
"3 4 5 1"
).split()
short_one = b"\00\01" if big_endian else b"\01\00"
mixed_data = b"\00\00" b"\03\03" + (
short_one + b"\00\01\01\01" b"\00\02"
)
mixed_data = b"\00\00" b"\03\03" + (short_one + b"\00\01\01\01" b"\00\02")
minus_one_data = b"\xff" * 14
endian_char = ">" if big_endian else "<"
format = (
......@@ -306,9 +296,7 @@ class TestMeshPlyIO(TestCaseMixin, unittest.TestCase):
lines2 = lines.copy()
lines2[8] = "1 2"
with self.assertRaisesRegex(
ValueError, "Inconsistent data for vertex."
):
with self.assertRaisesRegex(ValueError, "Inconsistent data for vertex."):
_load_ply_raw(StringIO("\n".join(lines2)))
lines2 = lines[:-1]
......@@ -344,9 +332,7 @@ class TestMeshPlyIO(TestCaseMixin, unittest.TestCase):
lines2 = lines.copy()
lines2.insert(4, "element bad 1")
with self.assertRaisesRegex(
ValueError, "Found an element with no properties."
):
with self.assertRaisesRegex(ValueError, "Found an element with no properties."):
_load_ply_raw(StringIO("\n".join(lines2)))
lines2 = lines.copy()
......@@ -369,25 +355,19 @@ class TestMeshPlyIO(TestCaseMixin, unittest.TestCase):
lines2 = lines.copy()
lines2.insert(4, "property double y")
with self.assertRaisesRegex(
ValueError, "Too little data for an element."
):
with self.assertRaisesRegex(ValueError, "Too little data for an element."):
_load_ply_raw(StringIO("\n".join(lines2)))
lines2[-2] = "3.3 4.2"
_load_ply_raw(StringIO("\n".join(lines2)))
lines2[-2] = "3.3 4.3 2"
with self.assertRaisesRegex(
ValueError, "Too much data for an element."
):
with self.assertRaisesRegex(ValueError, "Too much data for an element."):
_load_ply_raw(StringIO("\n".join(lines2)))
# Now make the ply file actually be readable as a Mesh
with self.assertRaisesRegex(
ValueError, "The ply file has no face element."
):
with self.assertRaisesRegex(ValueError, "The ply file has no face element."):
load_ply(StringIO("\n".join(lines)))
lines2 = lines.copy()
......@@ -398,9 +378,7 @@ class TestMeshPlyIO(TestCaseMixin, unittest.TestCase):
lines2.insert(5, "property float z")
lines2.insert(5, "property float y")
lines2[-2] = "0 0 0"
with self.assertRaisesRegex(
ValueError, "Faces must have at least 3 vertices."
):
with self.assertRaisesRegex(ValueError, "Faces must have at least 3 vertices."):
load_ply(StringIO("\n".join(lines2)))
# Good one
......@@ -408,17 +386,11 @@ class TestMeshPlyIO(TestCaseMixin, unittest.TestCase):
load_ply(StringIO("\n".join(lines2)))
@staticmethod
def _bm_save_ply(
verts: torch.Tensor, faces: torch.Tensor, decimal_places: int
):
return lambda: save_ply(
StringIO(), verts, faces, decimal_places=decimal_places
)
def _bm_save_ply(verts: torch.Tensor, faces: torch.Tensor, decimal_places: int):
return lambda: save_ply(StringIO(), verts, faces, decimal_places=decimal_places)
@staticmethod
def _bm_load_ply(
verts: torch.Tensor, faces: torch.Tensor, decimal_places: int
):
def _bm_load_ply(verts: torch.Tensor, faces: torch.Tensor, decimal_places: int):
f = StringIO()
save_ply(f, verts, faces, decimal_places)
s = f.getvalue()
......
This diff is collapsed.
......@@ -2,8 +2,9 @@
import functools
import unittest
import torch
import torch
from common_testing import TestCaseMixin
from pytorch3d import _C
from pytorch3d.renderer.mesh.rasterize_meshes import (
rasterize_meshes,
......@@ -12,20 +13,14 @@ from pytorch3d.renderer.mesh.rasterize_meshes import (
from pytorch3d.structures import Meshes
from pytorch3d.utils import ico_sphere
from common_testing import TestCaseMixin
class TestRasterizeMeshes(TestCaseMixin, unittest.TestCase):
def test_simple_python(self):
device = torch.device("cpu")
self._simple_triangle_raster(
rasterize_meshes_python, device, bin_size=-1
)
self._simple_triangle_raster(rasterize_meshes_python, device, bin_size=-1)
self._simple_blurry_raster(rasterize_meshes_python, device, bin_size=-1)
self._test_behind_camera(rasterize_meshes_python, device, bin_size=-1)
self._test_perspective_correct(
rasterize_meshes_python, device, bin_size=-1
)
self._test_perspective_correct(rasterize_meshes_python, device, bin_size=-1)
def test_simple_cpu_naive(self):
device = torch.device("cpu")
......@@ -350,9 +345,7 @@ class TestRasterizeMeshes(TestCaseMixin, unittest.TestCase):
fn1 = functools.partial(rasterize_meshes, meshes1, **kwargs)
fn2 = functools.partial(rasterize_meshes_python, meshes2, **kwargs)
args = ()
self._compare_impls(
fn1, fn2, args, args, verts1, verts2, compare_grads=True
)
self._compare_impls(fn1, fn2, args, args, verts1, verts2, compare_grads=True)
def test_cpp_vs_cuda_perspective_correct(self):
meshes = ico_sphere(2, device=torch.device("cpu"))
......@@ -367,9 +360,7 @@ class TestRasterizeMeshes(TestCaseMixin, unittest.TestCase):
fn1 = functools.partial(rasterize_meshes, meshes1, **kwargs)
fn2 = functools.partial(rasterize_meshes, meshes2, bin_size=0, **kwargs)
args = ()
self._compare_impls(
fn1, fn2, args, args, verts1, verts2, compare_grads=True
)
self._compare_impls(fn1, fn2, args, args, verts1, verts2, compare_grads=True)
def test_cuda_naive_vs_binned_perspective_correct(self):
meshes = ico_sphere(2, device=torch.device("cuda"))
......@@ -384,9 +375,7 @@ class TestRasterizeMeshes(TestCaseMixin, unittest.TestCase):
fn1 = functools.partial(rasterize_meshes, meshes1, bin_size=0, **kwargs)
fn2 = functools.partial(rasterize_meshes, meshes2, bin_size=8, **kwargs)
args = ()
self._compare_impls(
fn1, fn2, args, args, verts1, verts2, compare_grads=True
)
self._compare_impls(fn1, fn2, args, args, verts1, verts2, compare_grads=True)
def _compare_impls(
self,
......@@ -433,9 +422,7 @@ class TestRasterizeMeshes(TestCaseMixin, unittest.TestCase):
grad_verts2 = grad_var2.grad.data.clone().cpu()
self.assertClose(grad_verts1, grad_verts2, rtol=1e-3)
def _test_perspective_correct(
self, rasterize_meshes_fn, device, bin_size=None
):
def _test_perspective_correct(self, rasterize_meshes_fn, device, bin_size=None):
# fmt: off
verts = torch.tensor([
[-0.4, -0.4, 10], # noqa: E241, E201
......@@ -542,12 +529,8 @@ class TestRasterizeMeshes(TestCaseMixin, unittest.TestCase):
zbuf_f_bary = w0_f * z0 + w1_f * z1 + w2_f * z2
zbuf_t_bary = w0_t * z0 + w1_t * z1 + w2_t * z2
mask = idx_expected != -1
zbuf_f_bary_diff = (
(zbuf_f_bary[mask] - zbuf_f_expected[mask]).abs().max()
)
zbuf_t_bary_diff = (
(zbuf_t_bary[mask] - zbuf_t_expected[mask]).abs().max()
)
zbuf_f_bary_diff = (zbuf_f_bary[mask] - zbuf_f_expected[mask]).abs().max()
zbuf_t_bary_diff = (zbuf_t_bary[mask] - zbuf_t_expected[mask]).abs().max()
self.assertLess(zbuf_f_bary_diff, 1e-4)
self.assertLess(zbuf_t_bary_diff, 1e-4)
......@@ -719,9 +702,7 @@ class TestRasterizeMeshes(TestCaseMixin, unittest.TestCase):
# k = 1, second closest point.
expected_p2face_k1 = expected_p2face_k0.clone()
expected_p2face_k1[0, :] = (
torch.ones_like(expected_p2face_k1[0, :]) * -1
)
expected_p2face_k1[0, :] = torch.ones_like(expected_p2face_k1[0, :]) * -1
# fmt: off
expected_p2face_k1[1, :] = torch.tensor(
......@@ -763,9 +744,7 @@ class TestRasterizeMeshes(TestCaseMixin, unittest.TestCase):
# Coordinate conventions +Y up, +Z in, +X left
if bin_size == -1:
# simple python, no bin_size
p2face, zbuf, bary, pix_dists = raster_fn(
meshes, image_size, 0.0, 2
)
p2face, zbuf, bary, pix_dists = raster_fn(meshes, image_size, 0.0, 2)
else:
p2face, zbuf, bary, pix_dists = raster_fn(
meshes, image_size, 0.0, 2, bin_size
......@@ -914,9 +893,7 @@ class TestRasterizeMeshes(TestCaseMixin, unittest.TestCase):
# Expected faces using axes convention +Y down, + X right, + Z in
bin_faces_expected = (
torch.ones(
(1, 2, 2, max_faces_per_bin), dtype=torch.int32, device=device
)
torch.ones((1, 2, 2, max_faces_per_bin), dtype=torch.int32, device=device)
* -1
)
bin_faces_expected[0, 0, 0, 0] = torch.tensor([1])
......@@ -979,12 +956,7 @@ class TestRasterizeMeshes(TestCaseMixin, unittest.TestCase):
def rasterize():
rasterize_meshes(
meshes_batch,
image_size,
blur_radius,
8,
bin_size,
max_faces_per_bin,
meshes_batch, image_size, blur_radius, 8, bin_size, max_faces_per_bin
)
torch.cuda.synchronize()
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment