Spaces:
Runtime error
Runtime error
Upload app.py
Browse files
app.py
CHANGED
@@ -1,7 +1,88 @@
|
|
1 |
import multiprocessing
|
2 |
import objaverse
|
3 |
import random
|
4 |
-
import numpy
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
|
6 |
processes = multiprocessing.cpu_count()
|
7 |
|
@@ -11,4 +92,17 @@ random_object_uids = random.sample(uids, 100)
|
|
11 |
objects = objaverse.load_objects(
|
12 |
uids=random_object_uids,
|
13 |
download_processes=processes
|
14 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import multiprocessing
|
2 |
import objaverse
|
3 |
import random
|
4 |
+
import numpy
|
5 |
+
import trimesh
|
6 |
+
|
7 |
+
|
8 |
+
|
9 |
+
def model_to_pc(mesh: trimesh.Trimesh, n_sample_points=10000):
|
10 |
+
f32 = numpy.float32
|
11 |
+
rad = numpy.sqrt(mesh.area / (3 * n_sample_points))
|
12 |
+
for _ in range(24):
|
13 |
+
pcd, face_idx = trimesh.sample.sample_surface_even(mesh, n_sample_points, rad)
|
14 |
+
rad *= 0.85
|
15 |
+
if len(pcd) == n_sample_points:
|
16 |
+
break
|
17 |
+
else:
|
18 |
+
raise ValueError("Bad geometry, cannot finish sampling.", mesh.area)
|
19 |
+
if isinstance(mesh.visual, trimesh.visual.ColorVisuals):
|
20 |
+
rgba = mesh.visual.face_colors[face_idx]
|
21 |
+
elif isinstance(mesh.visual, trimesh.visual.TextureVisuals):
|
22 |
+
bc = trimesh.proximity.points_to_barycentric(mesh.triangles[face_idx], pcd)
|
23 |
+
if mesh.visual.uv is None or len(mesh.visual.uv) < mesh.faces[face_idx].max():
|
24 |
+
uv = numpy.zeros([len(bc), 2])
|
25 |
+
# st.warning("Invalid UV, filling with zeroes")
|
26 |
+
else:
|
27 |
+
uv = numpy.einsum('ntc,nt->nc', mesh.visual.uv[mesh.faces[face_idx]], bc)
|
28 |
+
material = mesh.visual.material
|
29 |
+
if hasattr(material, 'materials'):
|
30 |
+
if len(material.materials) == 0:
|
31 |
+
rgba = numpy.ones_like(pcd) * 0.8
|
32 |
+
texture = None
|
33 |
+
# st.warning("Empty MultiMaterial found, falling back to light grey")
|
34 |
+
else:
|
35 |
+
material = material.materials[0]
|
36 |
+
if hasattr(material, 'image'):
|
37 |
+
texture = material.image
|
38 |
+
if texture is None:
|
39 |
+
rgba = numpy.zeros([len(uv), len(material.main_color)]) + material.main_color
|
40 |
+
elif hasattr(material, 'baseColorTexture'):
|
41 |
+
texture = material.baseColorTexture
|
42 |
+
if texture is None:
|
43 |
+
rgba = numpy.zeros([len(uv), len(material.main_color)]) + material.main_color
|
44 |
+
else:
|
45 |
+
texture = None
|
46 |
+
rgba = numpy.ones_like(pcd) * 0.8
|
47 |
+
# st.warning("Unknown material, falling back to light grey")
|
48 |
+
if texture is not None:
|
49 |
+
rgba = trimesh.visual.uv_to_interpolated_color(uv, texture)
|
50 |
+
if rgba.max() > 1:
|
51 |
+
if rgba.max() > 255:
|
52 |
+
rgba = rgba.astype(f32) / rgba.max()
|
53 |
+
else:
|
54 |
+
rgba = rgba.astype(f32) / 255.0
|
55 |
+
return numpy.concatenate([numpy.array(pcd, f32), numpy.array(rgba, f32)[:, :3]], axis=-1)
|
56 |
+
|
57 |
+
|
58 |
+
def trimesh_to_pc(scene_or_mesh):
|
59 |
+
if isinstance(scene_or_mesh, trimesh.Scene):
|
60 |
+
meshes = []
|
61 |
+
for node_name in scene_or_mesh.graph.nodes_geometry:
|
62 |
+
# which geometry does this node refer to
|
63 |
+
transform, geometry_name = scene_or_mesh.graph[node_name]
|
64 |
+
|
65 |
+
# get the actual potential mesh instance
|
66 |
+
geometry = scene_or_mesh.geometry[geometry_name].copy()
|
67 |
+
if not hasattr(geometry, 'triangles'):
|
68 |
+
continue
|
69 |
+
geometry: trimesh.Trimesh
|
70 |
+
geometry = geometry.apply_transform(transform)
|
71 |
+
meshes.append(geometry)
|
72 |
+
total_area = sum(geometry.area for geometry in meshes)
|
73 |
+
if total_area < 1e-6:
|
74 |
+
raise ValueError("Bad geometry: total area too small (< 1e-6)")
|
75 |
+
pcs = []
|
76 |
+
for geometry in meshes:
|
77 |
+
pcs.append(model_to_pc(geometry, max(1, round(geometry.area / total_area * 10000))))
|
78 |
+
if not len(pcs):
|
79 |
+
raise ValueError("Unsupported mesh object: no triangles found")
|
80 |
+
return numpy.concatenate(pcs)
|
81 |
+
else:
|
82 |
+
assert isinstance(scene_or_mesh, trimesh.Trimesh)
|
83 |
+
return model_to_pc(scene_or_mesh, 10000)
|
84 |
+
|
85 |
+
|
86 |
|
87 |
processes = multiprocessing.cpu_count()
|
88 |
|
|
|
92 |
objects = objaverse.load_objects(
|
93 |
uids=random_object_uids,
|
94 |
download_processes=processes
|
95 |
+
)
|
96 |
+
|
97 |
+
pc_list = []
|
98 |
+
for objaid in random_object_uids:
|
99 |
+
objamodel = objaverse.load_objects([objaid])[objaid]
|
100 |
+
pc = trimesh_to_pc(trimesh.load(objamodel))
|
101 |
+
pc_list.append(pc.reshape([1, -1, pc.shape[-1]]))
|
102 |
+
|
103 |
+
pc_list = numpy.concatenate(pc_list, axis=0)
|
104 |
+
|
105 |
+
numpy.save("pc.npy", pc_list)
|
106 |
+
|
107 |
+
print("Done")
|
108 |
+
|