@@ -87,6 +87,31 @@ def apply_transformation(meshio_mesh, obj, depsgraph):
87
87
# multiply everything together (with custom transform matrix)
88
88
obj .matrix_world = rigid_body_transformation @ eval_transform_matrix
89
89
90
+ # function to create a single custom Blender mesh attribute
91
+ def create_or_retrieve_attribute (mesh , k , v ):
92
+ if k not in mesh .attributes :
93
+ if len (v ) == 0 :
94
+ return mesh .attributes .new (k , "FLOAT" , "POINT" )
95
+ if len (v .shape ) == 1 :
96
+ # one dimensional attribute
97
+ return mesh .attributes .new (k , "FLOAT" , "POINT" )
98
+ if len (v .shape ) == 2 :
99
+ dim = v .shape [1 ]
100
+ if dim > 3 :
101
+ show_message_box ('higher than 3 dimensional attribue, ignored' )
102
+ return None
103
+ if dim == 1 :
104
+ return mesh .attributes .new (k , "FLOAT" , "POINT" )
105
+ if dim == 2 :
106
+ return mesh .attributes .new (k , "FLOAT2" , "POINT" )
107
+ if dim == 3 :
108
+ return mesh .attributes .new (k , "FLOAT_VECTOR" , "POINT" )
109
+ if len (v .shape ) > 2 :
110
+ show_message_box ('more than 2 dimensional tensor, ignored' )
111
+ return None
112
+ else :
113
+ return mesh .attributes [k ]
114
+
90
115
def update_mesh (meshio_mesh , mesh ):
91
116
# extract information from the meshio mesh
92
117
mesh_vertices = meshio_mesh .points
@@ -141,30 +166,18 @@ def update_mesh(meshio_mesh, mesh):
141
166
mesh .update ()
142
167
mesh .validate ()
143
168
169
+ if bpy .context .scene .BSEQ .use_imported_normals :
170
+ if "obj:vn" in meshio_mesh .point_data :
171
+ mesh .BSEQ .split_norm_att_name = "bseq_obj:vn"
172
+ elif "normals" in meshio_mesh .point_data and len (meshio_mesh .point_data ["normals" ]) == len (mesh .vertices ):
173
+ mesh .BSEQ .split_norm_att_name = "bseq_normals"
174
+ elif "obj:vn" in meshio_mesh .field_data and "obj:vn_face_idx" in meshio_mesh .cell_data :
175
+ mesh .BSEQ .split_norm_att_name = "obj:vn"
176
+
144
177
# copy attributes
145
178
for k , v in meshio_mesh .point_data .items ():
146
179
k = "bseq_" + k
147
- attribute = None
148
- if k not in mesh .attributes :
149
- if len (v .shape ) == 1 :
150
- # one dimensional attribute
151
- attribute = mesh .attributes .new (k , "FLOAT" , "POINT" )
152
- if len (v .shape ) == 2 :
153
- dim = v .shape [1 ]
154
- if dim > 3 :
155
- show_message_box ('higher than 3 dimensional attribue, ignored' )
156
- continue
157
- if dim == 1 :
158
- attribute = mesh .attributes .new (k , "FLOAT" , "POINT" )
159
- if dim == 2 :
160
- attribute = mesh .attributes .new (k , "FLOAT2" , "POINT" )
161
- if dim == 3 :
162
- attribute = mesh .attributes .new (k , "FLOAT_VECTOR" , "POINT" )
163
- if len (v .shape ) > 2 :
164
- show_message_box ('more than 2 dimensional tensor, ignored' )
165
- continue
166
- else :
167
- attribute = mesh .attributes [k ]
180
+ attribute = create_or_retrieve_attribute (mesh , k , v )
168
181
name_string = None
169
182
if attribute .data_type == "FLOAT" :
170
183
name_string = "value"
@@ -173,36 +186,20 @@ def update_mesh(meshio_mesh, mesh):
173
186
174
187
attribute .data .foreach_set (name_string , v .ravel ())
175
188
176
- # # set as split norm
177
- # if mesh.BSEQ.split_norm_att_name and mesh.BSEQ.split_norm_att_name == k:
178
- # mesh.use_auto_smooth = True
179
- # mesh.normals_split_custom_set_from_vertices(v)
180
-
181
- # I want to set normals if the scene property use_imported_normals is true and the normals are either in point_data["obj:vn"] or field_data["obj:vn"]
182
- if bpy .context .scene .BSEQ .use_imported_normals :
183
- print ("use_imported_normals" )
184
- # print all the keys in point_data, field_data, cell_data
185
- print ("point_data" , meshio_mesh .point_data .keys ())
186
- print ("field_data" , meshio_mesh .field_data .keys ())
187
- print ("cell_data" , meshio_mesh .cell_data .keys ())
188
-
189
- mesh .use_auto_smooth = True
190
-
191
-
192
- if "obj:vn" in meshio_mesh .point_data and len (meshio_mesh .point_data ["obj:vn" ]) == len (mesh .vertices ):
193
- print ("obj:vn in point_data" , len (mesh .loops ))
194
- # vert_norms = [tuple(x) for x in meshio_mesh.point_data["obj:vn"]]
195
-
196
- mesh .normals_split_custom_set_from_vertices (meshio_mesh .point_data ["obj:vn" ])
189
+ # set as split normal per vertex
190
+ if mesh .BSEQ .split_norm_att_name and mesh .BSEQ .split_norm_att_name == k :
191
+ mesh .use_auto_smooth = True
192
+ mesh .normals_split_custom_set_from_vertices (v )
197
193
198
- for i in range (len (mesh .vertices )):
199
- print (mesh .vertices [i ].normal )
200
- elif "obj:vn" in meshio_mesh .field_data and "obj:vn_face_idx" in meshio_mesh .cell_data :
201
- print ("obj:vn in field_data" )
202
- indices = meshio_mesh .cell_data ["obj:vn_face_idx" ][0 ]
203
- indices = [item for sublist in indices for item in sublist ]
204
- vert_norms = [meshio_mesh .field_data ["obj:vn" ][i - 1 ] for i in indices ]
205
- mesh .normals_split_custom_set (vert_norms )
194
+ for k , v in meshio_mesh .field_data .items ():
195
+ if k not in mesh .attributes :
196
+ attribute = create_or_retrieve_attribute (mesh , k , [])
197
+
198
+ # set split normal per loop per vertex
199
+ if mesh .BSEQ .split_norm_att_name and mesh .BSEQ .split_norm_att_name == k :
200
+ # Currently hard-coded for .obj files
201
+ indices = [item for sublist in meshio_mesh .cell_data ["obj:vn_face_idx" ][0 ] for item in sublist ]
202
+ mesh .normals_split_custom_set ([meshio_mesh .field_data ["obj:vn" ][i - 1 ] for i in indices ])
206
203
207
204
# function to create a single meshio object
208
205
def create_meshio_obj (filepath ):
@@ -223,7 +220,6 @@ def create_meshio_obj(filepath):
223
220
bpy .ops .object .select_all (action = "DESELECT" )
224
221
bpy .context .view_layer .objects .active = object
225
222
226
-
227
223
def create_obj (fileseq , root_path , transform_matrix = Matrix ([[1 , 0 , 0 , 0 ], [0 , 1 , 0 , 0 ], [0 , 0 , 1 , 0 ], [0 , 0 , 0 , 1 ]])):
228
224
229
225
current_frame = bpy .context .scene .frame_current
0 commit comments