@@ -15,7 +15,8 @@ def make_mesh_texture_atlas(
1515 material_properties : Dict ,
1616 texture_images : Dict ,
1717 face_material_names ,
18- faces_verts_uvs : torch .Tensor ,
18+ faces_uvs : torch .Tensor ,
19+ verts_uvs : torch .Tensor ,
1920 texture_size : int ,
2021 texture_wrap : Optional [str ],
2122) -> torch .Tensor :
@@ -31,8 +32,9 @@ def make_mesh_texture_atlas(
3132 face_material_names: numpy array of the material name corresponding to each
3233 face. Faces which don't have an associated material will be an empty string.
3334 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.
3638 texture_size: the resolution of the per face texture map returned by this function.
3739 Each face will have a texture map of shape (texture_size, texture_size, 3).
3840 texture_wrap: string, one of ["repeat", "clamp", None]
@@ -47,50 +49,55 @@ def make_mesh_texture_atlas(
4749 """
4850 # Create an R x R texture map per face in the mesh
4951 R = texture_size
50- F = faces_verts_uvs .shape [0 ]
52+ F = faces_uvs .shape [0 ]
5153
5254 # Initialize the per face texture map to a white color.
5355 # 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 )
5657
5758 # Check for empty materials.
5859 if not material_properties and not texture_images :
5960 return atlas
6061
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+
6186 if texture_wrap == "repeat" :
6287 # If texture uv coordinates are outside the range [0, 1] follow
6388 # the convention GL_REPEAT in OpenGL i.e the integer part of the coordinate
6489 # will be ignored and a repeating pattern is formed.
6590 # Shapenet data uses this format see:
6691 # 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`.
6892 if (faces_verts_uvs > 1 ).any () or (faces_verts_uvs < 0 ).any ():
6993 msg = "Texture UV coordinates outside the range [0, 1]. \
7094 The integer part will be ignored to form a repeating pattern."
7195 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`.
7496 faces_verts_uvs = faces_verts_uvs % 1
7597 elif texture_wrap == "clamp" :
7698 # Clamp uv coordinates to the [0, 1] range.
7799 faces_verts_uvs = faces_verts_uvs .clamp (0.0 , 1.0 )
78100
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-
94101 # Iterate through the materials used in this mesh. Update the
95102 # texture atlas for the faces which use this material.
96103 # Faces without texture are white.
0 commit comments