Script to preprocess shapenet like dataset.
This script allows to interactively go through a ShapeNet dataset and decide
whether to keep or remove a mesh. All textures are removed, only the obj file
and a converted SDF volume are stored in the output folder.
Object3D
Representation of a 3D object.
Source code in sdfest/vae/scripts/process_shapenet.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 | class Object3D:
"""Representation of a 3D object."""
def __init__(self, mesh_path: str):
"""Initialize the 3D object.
Args:
mesh_path: the full file path of the mesh
"""
self.mesh_path = mesh_path
self.simplified_mesh = None
self.sdf_volume = None
self.reconstructed_mesh = None
def convert_to_sdf(self, cells_per_dim, padding):
self.sdf_volume = sdf_utils.mesh_to_sdf(
self.simplified_mesh, cells_per_dim, padding
)
return self
def load_mesh(self):
loaded_obj = trimesh.load(self.mesh_path, process=False)
if isinstance(loaded_obj, Trimesh):
self.simplified_mesh = Trimesh(
loaded_obj.vertices,
loaded_obj.faces,
vertex_normals=loaded_obj.vertex_normals,
visual=trimesh.visual.TextureVisuals(material=SimpleMaterial()),
)
elif isinstance(loaded_obj, Scene):
mesh = trimesh.util.concatenate(
tuple(
trimesh.Trimesh(
vertices=g.vertices,
faces=g.faces,
vertex_normals=g.vertex_normals,
)
for g in loaded_obj.geometry.values()
)
)
self.simplified_mesh = Trimesh(
mesh.vertices,
mesh.faces,
vertex_normals=mesh.vertex_normals,
visual=trimesh.visual.TextureVisuals(material=SimpleMaterial()),
)
else:
print(f"Not supported: {type(loaded_obj)}")
return False
return True
def reconstruct_from_sdf(self):
level = 1.0 / self.sdf_volume.shape[-1]
self.reconstructed_mesh = sdf_utils.mesh_from_sdf(self.sdf_volume, level)
return self
|
__init__(mesh_path)
Initialize the 3D object.
Parameters:
Name |
Type |
Description |
Default |
mesh_path |
str
|
the full file path of the mesh
|
required
|
Source code in sdfest/vae/scripts/process_shapenet.py
28
29
30
31
32
33
34
35
36
37 | def __init__(self, mesh_path: str):
"""Initialize the 3D object.
Args:
mesh_path: the full file path of the mesh
"""
self.mesh_path = mesh_path
self.simplified_mesh = None
self.sdf_volume = None
self.reconstructed_mesh = None
|
trimesh_decision_viewer(mesh, return_dict)
View a trimesh with pyrender adding support to press left and right.
Source code in sdfest/vae/scripts/process_shapenet.py
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 | def trimesh_decision_viewer(mesh, return_dict):
"""View a trimesh with pyrender adding support to press left and right."""
def on_press(key):
nonlocal inp
try:
inp = key.char # single-char keys
except AttributeError:
inp = key.name
pyrender_mesh = pyrender.Mesh.from_trimesh(mesh)
scene = pyrender.Scene(ambient_light=[0.3, 0.3, 0.3, 1.0])
scene.add(pyrender_mesh)
v = pyrender.Viewer(scene, run_in_thread=True, use_raymond_lighting=True)
inp = None
from pynput import keyboard
decision = None
listener = keyboard.Listener(on_press=on_press)
listener.start() # start to listen on a separate thread
while True:
time.sleep(0.1)
if inp == "left":
decision = "remove"
break
elif inp == "right":
decision = "keep"
break
elif inp == "down":
decision = "stop"
break
# TODO: listener.stop() hangs randomly (especially under load)
v.close_external()
return_dict["decision"] = decision
return decision
|