-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathblender_load_meshes.py
157 lines (106 loc) · 4.96 KB
/
blender_load_meshes.py
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
import bpy
import numpy as np
import sys
import math
import os
import csv
import argparse
import re
# Add current directory to system path to be able to import scripts with python
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
from mesh_properties_io import unpack_mesh_properties
from blender_utils import *
ROOT_FOLDER = os.path.dirname(os.path.realpath(__file__))
MESHES_FOLDER = os.path.join(ROOT_FOLDER, 'meshes')
OUT_FOLDER = os.path.join(ROOT_FOLDER, 'out')
BLENDER_CAMERA_DATA_PATH = os.path.join(ROOT_FOLDER, 'data', 'blender_cameras.csv')
def load_exported_ply_result(ply_file):
# Load mesh file
bpy.ops.import_mesh.ply(filepath=ply_file)
ob = bpy.context.object
ob.rotation_euler[0] = math.radians(90) # Correct axis orientations
mesh = ob.data
bpy.ops.object.select_all(action='DESELECT')
bpy.context.view_layer.objects.active = ob
ob.select_set(True)
bpy.ops.object.transform_apply() # Apply all transforms
sharpness_by_vertex, vertex_is_seam, label_by_poly, degree_by_poly = unpack_mesh_properties(mesh)
label_color_layer = mesh.vertex_colors['Col']
set_per_face_colors(ob, np.column_stack([label_by_poly, degree_by_poly, np.zeros(len(label_by_poly))]), label_color_layer.name)
mark_sharp(ob, sharpness_by_vertex)
mark_seam(ob, vertex_is_seam)
# Shade smooth
bpy.ops.object.shade_smooth()
# UVs
uv_unwrap(ob)
bpy.ops.object.select_all(action='DESELECT')
# MATERIALS
# All materials will be loaded from a materials.blend file located in the same folder
# Set default material
ob.active_material = get_or_load_mat("rainbow-labels")
return ob
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('-m', '--mesh', help='Pattern to select sketch(es)', type=str, default=".+")
parser.add_argument('--blend-file', help='Name of the output blend file', type=str, default=None)
parser.add_argument('--turntables', help='Prepare for turntable animations', dest='turntables', action='store_true', default=False)
parser.add_argument('--materials', help='Name of the material(s) to load. They should be defined in data/materials.blend file.', type=str, default=[], required=False, nargs='+')
# get the args passed to blender after "--", all of which are ignored by
# blender so scripts may receive their own arguments
argv = sys.argv
if "--" not in argv:
argv = [] # as if no args are passed
else:
argv = argv[argv.index("--") + 1:] # get all args after "--"
args = parser.parse_args(argv)
result_meshes_folder = MESHES_FOLDER
blend_file_name = "all_meshes"
if args.blend_file is not None:
blend_file_name = args.blend_file
blend_file_path = os.path.join(OUT_FOLDER, f"{blend_file_name}.blend")
# Init blender
setup_scene(os.path.join(ROOT_FOLDER, 'data/interior.exr'))
camera_data_per_mesh = {}
with open(BLENDER_CAMERA_DATA_PATH, mode='r', encoding='utf-8-sig') as csv_file:
metadata = csv.DictReader(csv_file, delimiter=";")
for row in metadata:
camera_data_per_mesh[row['mesh_name']] = row
files = []
for item in os.listdir(result_meshes_folder):
if os.path.isfile(os.path.join(result_meshes_folder, item)) and os.path.splitext(item)[1] == '.ply' and re.match(args.mesh, item):
files.append(item)
for f in sorted(files):
mesh_name, extension = os.path.splitext(f)
if mesh_name in camera_data_per_mesh:
camera_data = camera_data_per_mesh[mesh_name]
else:
camera_data = None
# Create a collection with the name of the mesh
collection = bpy.data.collections.new(mesh_name)
bpy.context.scene.collection.children.link(collection)
# Position camera
if camera_data is not None:
for i in [1,2]:
cam1_loc = eval(camera_data[f'cam{i}_loc'])
cam1_rot = eval(camera_data[f'cam{i}_rot'])
cam1_obj = create_camera(f"{mesh_name}_camera{i}", cam1_loc, cam1_rot)
set_collection(cam1_obj, collection)
else:
# Create a default camera
cam_obj = create_camera(f"{mesh_name}_camera", (0, 0, 0.5), (0, 0, 0))
set_collection(cam_obj, collection)
# Load mesh
result_mesh_path = os.path.join(result_meshes_folder, f)
mesh_object = load_exported_ply_result(result_mesh_path)
name = f"{mesh_name}_result"
mesh_object.name = name
set_collection(mesh_object, collection)
# Add more materials
for material_name in args.materials:
mesh_object.data.materials.append(get_or_load_mat(material_name))
# Hide collection so that the blender file is easier to navigate
hide_col(collection)
bpy.ops.wm.save_mainfile(filepath=blend_file_path)
if args.turntables:
add_turntables(nb_frames=240)
bpy.ops.wm.save_mainfile(filepath=blend_file_path)