@@ -15,7 +15,8 @@ def make_mesh_texture_atlas(
15
15
material_properties : Dict ,
16
16
texture_images : Dict ,
17
17
face_material_names ,
18
- faces_verts_uvs : torch .Tensor ,
18
+ faces_uvs : torch .Tensor ,
19
+ verts_uvs : torch .Tensor ,
19
20
texture_size : int ,
20
21
texture_wrap : Optional [str ],
21
22
) -> torch .Tensor :
@@ -31,8 +32,9 @@ def make_mesh_texture_atlas(
31
32
face_material_names: numpy array of the material name corresponding to each
32
33
face. Faces which don't have an associated material will be an empty string.
33
34
For these faces, a uniform white texture is assigned.
34
- faces_verts_uvs: LongTensor of shape (F, 3, 2) giving the uv coordinates for each
35
- vertex in the face.
35
+ faces_uvs: LongTensor of shape (F, 3,) giving the index into the verts_uvs for
36
+ each face in the mesh.
37
+ verts_uvs: FloatTensor of shape (V, 2) giving the uv coordinates for each vertex.
36
38
texture_size: the resolution of the per face texture map returned by this function.
37
39
Each face will have a texture map of shape (texture_size, texture_size, 3).
38
40
texture_wrap: string, one of ["repeat", "clamp", None]
@@ -47,50 +49,55 @@ def make_mesh_texture_atlas(
47
49
"""
48
50
# Create an R x R texture map per face in the mesh
49
51
R = texture_size
50
- F = faces_verts_uvs .shape [0 ]
52
+ F = faces_uvs .shape [0 ]
51
53
52
54
# Initialize the per face texture map to a white color.
53
55
# TODO: allow customization of this base color?
54
- # pyre-fixme[16]: `Tensor` has no attribute `new_ones`.
55
- atlas = faces_verts_uvs .new_ones (size = (F , R , R , 3 ))
56
+ atlas = torch .ones (size = (F , R , R , 3 ), dtype = torch .float32 , device = faces_uvs .device )
56
57
57
58
# Check for empty materials.
58
59
if not material_properties and not texture_images :
59
60
return atlas
60
61
62
+ # Iterate through the material properties - not
63
+ # all materials have texture images so this is
64
+ # done first separately to the texture interpolation.
65
+ for material_name , props in material_properties .items ():
66
+ # Bool to indicate which faces use this texture map.
67
+ faces_material_ind = torch .from_numpy (face_material_names == material_name ).to (
68
+ faces_uvs .device
69
+ )
70
+ if faces_material_ind .sum () > 0 :
71
+ # For these faces, update the base color to the
72
+ # diffuse material color.
73
+ if "diffuse_color" not in props :
74
+ continue
75
+ atlas [faces_material_ind , ...] = props ["diffuse_color" ][None , :]
76
+
77
+ # If there are vertex texture coordinates, create an (F, 3, 2)
78
+ # tensor of the vertex textures per face.
79
+ faces_verts_uvs = verts_uvs [faces_uvs ] if len (verts_uvs ) > 0 else None
80
+
81
+ # Some meshes only have material properties and no texture image.
82
+ # In this case, return the atlas here.
83
+ if faces_verts_uvs is None :
84
+ return atlas
85
+
61
86
if texture_wrap == "repeat" :
62
87
# If texture uv coordinates are outside the range [0, 1] follow
63
88
# the convention GL_REPEAT in OpenGL i.e the integer part of the coordinate
64
89
# will be ignored and a repeating pattern is formed.
65
90
# Shapenet data uses this format see:
66
91
# https://shapenet.org/qaforum/index.php?qa=15&qa_1=why-is-the-texture-coordinate-in-the-obj-file-not-in-the-range # noqa: B950
67
- # pyre-fixme[16]: `ByteTensor` has no attribute `any`.
68
92
if (faces_verts_uvs > 1 ).any () or (faces_verts_uvs < 0 ).any ():
69
93
msg = "Texture UV coordinates outside the range [0, 1]. \
70
94
The integer part will be ignored to form a repeating pattern."
71
95
warnings .warn (msg )
72
- # pyre-fixme[9]: faces_verts_uvs has type `Tensor`; used as `int`.
73
- # pyre-fixme[58]: `%` is not supported for operand types `Tensor` and `int`.
74
96
faces_verts_uvs = faces_verts_uvs % 1
75
97
elif texture_wrap == "clamp" :
76
98
# Clamp uv coordinates to the [0, 1] range.
77
99
faces_verts_uvs = faces_verts_uvs .clamp (0.0 , 1.0 )
78
100
79
- # Iterate through the material properties - not
80
- # all materials have texture images so this has to be
81
- # done separately to the texture interpolation.
82
- for material_name , props in material_properties .items ():
83
- # Bool to indicate which faces use this texture map.
84
- faces_material_ind = torch .from_numpy (face_material_names == material_name ).to (
85
- faces_verts_uvs .device
86
- )
87
- if faces_material_ind .sum () > 0 :
88
- # For these faces, update the base color to the
89
- # diffuse material color.
90
- if "diffuse_color" not in props :
91
- continue
92
- atlas [faces_material_ind , ...] = props ["diffuse_color" ][None , :]
93
-
94
101
# Iterate through the materials used in this mesh. Update the
95
102
# texture atlas for the faces which use this material.
96
103
# Faces without texture are white.
0 commit comments