allow loading of pointclouds

This commit is contained in:
Andrea Pozzetti
2026-02-12 21:36:40 +01:00
parent 0b62eba7ce
commit abb8b65b49
2 changed files with 30 additions and 3 deletions
+25 -2
View File
@@ -199,10 +199,22 @@ def load_mesh_file(file_path: str) -> Tuple[Optional[trimesh.Trimesh], str]:
print(f"[load_mesh_file] Loading: {file_path}")
# Try to load with trimesh first (supports many formats)
loaded = trimesh.load(file_path, force='mesh')
# Don't force='mesh' so we can also load pointclouds
loaded = trimesh.load(file_path)
print(f"[load_mesh_file] Loaded type: {type(loaded).__name__}")
# Handle pointclouds (PLY files with only vertices, no faces)
if isinstance(loaded, trimesh.PointCloud):
print(f"[load_mesh_file] Loaded pointcloud: {len(loaded.vertices)} points")
# Store file metadata
loaded.metadata['file_path'] = file_path
loaded.metadata['file_name'] = os.path.basename(file_path)
loaded.metadata['file_format'] = os.path.splitext(file_path)[1].lower()
loaded.metadata['is_pointcloud'] = True
print(f"[load_mesh_file] ✓ Successfully loaded pointcloud: {len(loaded.vertices)} points")
return loaded, ""
# Handle case where trimesh.load returns a Scene instead of a mesh
if isinstance(loaded, trimesh.Scene):
print(f"[load_mesh_file] Converting Scene to single mesh (scene has {len(loaded.geometry)} geometries)")
@@ -211,9 +223,20 @@ def load_mesh_file(file_path: str) -> Tuple[Optional[trimesh.Trimesh], str]:
else:
mesh = loaded
if mesh is None or len(mesh.vertices) == 0 or len(mesh.faces) == 0:
if mesh is None or len(mesh.vertices) == 0:
return None, f"Failed to read mesh or mesh is empty: {file_path}"
# Check if it's actually a pointcloud (mesh with no faces)
if not hasattr(mesh, 'faces') or mesh.faces is None or len(mesh.faces) == 0:
# Convert to PointCloud
pointcloud = trimesh.PointCloud(vertices=mesh.vertices)
pointcloud.metadata['file_path'] = file_path
pointcloud.metadata['file_name'] = os.path.basename(file_path)
pointcloud.metadata['file_format'] = os.path.splitext(file_path)[1].lower()
pointcloud.metadata['is_pointcloud'] = True
print(f"[load_mesh_file] ✓ Successfully loaded as pointcloud: {len(pointcloud.vertices)} points")
return pointcloud, ""
print(f"[load_mesh_file] Initial mesh: {len(mesh.vertices)} vertices, {len(mesh.faces)} faces")
# Ensure mesh is properly triangulated
+5 -1
View File
@@ -195,7 +195,11 @@ class LoadMesh:
if loaded_mesh is None:
raise ValueError(f"Failed to load mesh: {error}")
print(f"[LoadMesh] Loaded: {len(loaded_mesh.vertices)} vertices, {len(loaded_mesh.faces)} faces")
# Handle both meshes and pointclouds
if hasattr(loaded_mesh, 'faces') and loaded_mesh.faces is not None:
print(f"[LoadMesh] Loaded: {len(loaded_mesh.vertices)} vertices, {len(loaded_mesh.faces)} faces")
else:
print(f"[LoadMesh] Loaded pointcloud: {len(loaded_mesh.vertices)} points")
# Extract texture
texture = self._extract_texture_image(loaded_mesh)