| 3240 | |
| 3241 | |
| 3242 | class Mesh: |
| 3243 | def __init__( |
| 3244 | self, |
| 3245 | mesh: T.Union[o3d.geometry.TriangleMesh, str], |
| 3246 | scale: T.Optional[float] = 1., |
| 3247 | center_w: T.Optional[T.List[float]] = (0., 0., 0.), |
| 3248 | preprocess_mesh: bool = True, |
| 3249 | ): |
| 3250 | if isinstance(mesh, str): |
| 3251 | # load mesh |
| 3252 | mesh: o3d.geometry.TriangleMesh = o3d.io.read_triangle_mesh( |
| 3253 | mesh, enable_post_processing=True) |
| 3254 | |
| 3255 | # preprocess mesh (clean uv, shift to center, rescale to [-scale, scale]) |
| 3256 | mesh = mesh_utils.preprocess_mesh( |
| 3257 | mesh=mesh, |
| 3258 | scale=scale, |
| 3259 | center_w=center_w, |
| 3260 | clean=preprocess_mesh |
| 3261 | ) |
| 3262 | |
| 3263 | self.scale = np.max(mesh.get_axis_aligned_bounding_box().get_half_extent()) |
| 3264 | self.center_w = mesh.get_axis_aligned_bounding_box().get_center() |
| 3265 | self.mesh = mesh |
| 3266 | |
| 3267 | # for ray tracing |
| 3268 | mesh_t = o3d.t.geometry.TriangleMesh.from_legacy(self.mesh) |
| 3269 | self.scene = o3d.t.geometry.RaycastingScene() |
| 3270 | self.scene.add_triangles(mesh_t) |
| 3271 | |
| 3272 | def replace_texture(self, texture_imgs: T.List[np.ndarray]): |
| 3273 | """ |
| 3274 | Replace the texture maps in the o3d mesh. |
| 3275 | |
| 3276 | Args: |
| 3277 | texture_imgs: |
| 3278 | a list of texture maps (may be in a different shape than the o3d textures) |
| 3279 | # method: |
| 3280 | # 'crop_resize': if a new texture is larger in dimension -> crop; if smaller -> resize. |
| 3281 | """ |
| 3282 | |
| 3283 | texture_maps = self.mesh.textures |
| 3284 | num_textures = len(texture_maps) |
| 3285 | |
| 3286 | if len(texture_imgs) != num_textures and len(texture_maps) > 0: |
| 3287 | warnings.warn(f'num of texture_imgs {len(texture_imgs)} != number of need {num_textures}') |
| 3288 | return |
| 3289 | |
| 3290 | new_textures = [] |
| 3291 | for i in range(len(texture_maps)): |
| 3292 | new_textures.append(o3d.geometry.Image(texture_imgs[i])) |
| 3293 | self.mesh.textures = new_textures |
| 3294 | |
| 3295 | def get_rgbd_image( |
| 3296 | self, |
| 3297 | camera: Camera, |
| 3298 | render_normal_w: bool = True, |
| 3299 | device: torch.device = torch.device('cpu'), |
no outgoing calls
no test coverage detected