File size: 5,456 Bytes
391cab6
 
 
792ccb0
 
d6f2056
 
 
11091e3
 
 
792ccb0
d6f2056
ed99f8a
d6f2056
a9248a7
792ccb0
fdfd1d3
 
 
 
 
 
 
 
792ccb0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
391cab6
 
 
11091e3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8b3fde2
 
bde404d
4ed50e7
ed99f8a
 
11091e3
391cab6
 
11091e3
391cab6
792ccb0
 
d6f2056
a9248a7
d6f2056
 
11091e3
 
792ccb0
fdb7fbb
 
fdfd1d3
11091e3
ed99f8a
fdb7fbb
 
792ccb0
11091e3
 
d6f2056
792ccb0
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
80
81
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import multiprocessing
import objaverse
import random
import numpy
import trimesh
import huggingface_hub
from huggingface_hub import Repository
import os
import pickle
import json
from tqdm import tqdm

DATASET_REPO_URL = "https://huggingface.co/datasets/Gary3410/object_tmp"
DATA_FILENAME = "object_tmp_4.pkl"
DATA_FILE = os.path.join("data", DATA_FILENAME)


def random_sampling(points, num_samples):
    # 如果点云数量小于采样数量,允许重复选择点
    if len(points) < num_samples:
        indices = numpy.random.choice(len(points), num_samples, replace=True)
    else:
        indices = numpy.random.choice(len(points), num_samples, replace=False)
    sampled_points = points[indices]
    return sampled_points

def model_to_pc(mesh: trimesh.Trimesh, n_sample_points=10000):
    f32 = numpy.float32
    rad = numpy.sqrt(mesh.area / (3 * n_sample_points))
    for _ in range(24):
        pcd, face_idx = trimesh.sample.sample_surface_even(mesh, n_sample_points, rad)
        rad *= 0.85
        if len(pcd) == n_sample_points:
            break
    else:
        raise ValueError("Bad geometry, cannot finish sampling.", mesh.area)
    if isinstance(mesh.visual, trimesh.visual.ColorVisuals):
        rgba = mesh.visual.face_colors[face_idx]
    elif isinstance(mesh.visual, trimesh.visual.TextureVisuals):
        bc = trimesh.proximity.points_to_barycentric(mesh.triangles[face_idx], pcd)
        if mesh.visual.uv is None or len(mesh.visual.uv) < mesh.faces[face_idx].max():
            uv = numpy.zeros([len(bc), 2])
            # st.warning("Invalid UV, filling with zeroes")
        else:
            uv = numpy.einsum('ntc,nt->nc', mesh.visual.uv[mesh.faces[face_idx]], bc)
        material = mesh.visual.material
        if hasattr(material, 'materials'):
            if len(material.materials) == 0:
                rgba = numpy.ones_like(pcd) * 0.8
                texture = None
                # st.warning("Empty MultiMaterial found, falling back to light grey")
            else:
                material = material.materials[0]
        if hasattr(material, 'image'):
            texture = material.image
            if texture is None:
                rgba = numpy.zeros([len(uv), len(material.main_color)]) + material.main_color
        elif hasattr(material, 'baseColorTexture'):
            texture = material.baseColorTexture
            if texture is None:
                rgba = numpy.zeros([len(uv), len(material.main_color)]) + material.main_color
        else:
            texture = None
            rgba = numpy.ones_like(pcd) * 0.8
            # st.warning("Unknown material, falling back to light grey")
        if texture is not None:
            rgba = trimesh.visual.uv_to_interpolated_color(uv, texture)
    if rgba.max() > 1:
        if rgba.max() > 255:
            rgba = rgba.astype(f32) / rgba.max()
        else:
            rgba = rgba.astype(f32) / 255.0
    return numpy.concatenate([numpy.array(pcd, f32), numpy.array(rgba, f32)[:, :3]], axis=-1)


def trimesh_to_pc(scene_or_mesh):
    if isinstance(scene_or_mesh, trimesh.Scene):
        meshes = []
        for node_name in scene_or_mesh.graph.nodes_geometry:
            # which geometry does this node refer to
            transform, geometry_name = scene_or_mesh.graph[node_name]

            # get the actual potential mesh instance
            geometry = scene_or_mesh.geometry[geometry_name].copy()
            if not hasattr(geometry, 'triangles'):
                continue
            geometry: trimesh.Trimesh
            geometry = geometry.apply_transform(transform)
            meshes.append(geometry)
        total_area = sum(geometry.area for geometry in meshes)
        if total_area < 1e-6:
            raise ValueError("Bad geometry: total area too small (< 1e-6)")
        pcs = []
        for geometry in meshes:
            pcs.append(model_to_pc(geometry, max(1, round(geometry.area / total_area * 10000))))
        if not len(pcs):
            raise ValueError("Unsupported mesh object: no triangles found")
        return numpy.concatenate(pcs)
    else:
        assert isinstance(scene_or_mesh, trimesh.Trimesh)
        return model_to_pc(scene_or_mesh, 10000)



processes = multiprocessing.cpu_count()

# uids = objaverse.load_uids()
# random_object_uids = random.sample(uids, 100)
uids = []
object_id_tmp_dict = {}

# 解析json文件
with open('object_id.json','r') as file:
    str = file.read()
    obj_data = json.loads(str)

for ints_key in obj_data.keys():
    ints_dict_one = obj_data[ints_key]
    ints_id_dict = ints_dict_one["obj_id"]
    for ints_one in ints_id_dict.keys():
        uid_one = ints_id_dict[ints_one]
        uids.append(uid_one)

uids = list(set(uids))
uids = sorted(uids)

# uids = uids[:809]
# uids = uids[809:1619]
# uids = uids[1619:]
uids = uids[:2]


objects = objaverse.load_objects(
    uids=uids,
    download_processes=processes
)

repo = Repository(
    local_dir="data", clone_from=DATASET_REPO_URL, use_auth_token="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"
)


for objaid in tqdm(uids):
    objamodel = objaverse.load_objects([objaid])[objaid]
    try:
        pc = trimesh_to_pc(trimesh.load(objamodel))
        pc = random_sampling(pc, num_samples=5000)
        object_id_tmp_dict[objaid] = pc
        print(pc.shape)
    except:
        continue

with open(DATA_FILE, 'wb') as file:
    pickle.dump(object_id_tmp_dict, file)
commit_url = repo.push_to_hub()

print("Done")