export with optimized texture size
This commit is contained in:
parent
8e7d8a4f56
commit
e562d2515e
|
@ -1149,8 +1149,24 @@ class ArmoryExporter:
|
||||||
default_values[count] = shape_key.value
|
default_values[count] = shape_key.value
|
||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
|
pos_array = np.array(vert_pos)
|
||||||
|
nor_array = np.array(vert_nor)
|
||||||
|
max = np.amax(pos_array)
|
||||||
|
min = np.amin(pos_array)
|
||||||
|
|
||||||
|
array_size = len(pos_array[0]), len(pos_array)
|
||||||
|
|
||||||
|
img_size, extra_zeros, block_size = self.get_best_image_size(array_size)
|
||||||
|
|
||||||
|
if(img_size < 1):
|
||||||
|
log.error(f"""object {bobject.name} contains too many vertices or shape keys to support shape keys export""")
|
||||||
|
self.remove_morph_uv_set(bobject)
|
||||||
|
return
|
||||||
|
|
||||||
min, max = self.bake_to_image(vert_pos, vert_nor, name, output_dir)
|
self.bake_to_image(pos_array, nor_array, max, min, extra_zeros, img_size, name, output_dir)
|
||||||
|
|
||||||
|
self.create_morph_uv_set(bobject, img_size)
|
||||||
|
|
||||||
morph_target = {}
|
morph_target = {}
|
||||||
morph_target['morph_target_data_file'] = name
|
morph_target['morph_target_data_file'] = name
|
||||||
|
@ -1159,6 +1175,8 @@ class ArmoryExporter:
|
||||||
morph_target['num_morph_targets'] = count
|
morph_target['num_morph_targets'] = count
|
||||||
morph_target['morph_scale'] = max - min
|
morph_target['morph_scale'] = max - min
|
||||||
morph_target['morph_offset'] = min
|
morph_target['morph_offset'] = min
|
||||||
|
morph_target['morph_img_size'] = img_size
|
||||||
|
morph_target['morph_block_size'] = block_size
|
||||||
|
|
||||||
out_mesh['morph_target'] = morph_target
|
out_mesh['morph_target'] = morph_target
|
||||||
return
|
return
|
||||||
|
@ -1184,44 +1202,67 @@ class ArmoryExporter:
|
||||||
|
|
||||||
return {'pos': pos, 'nor': nor}
|
return {'pos': pos, 'nor': nor}
|
||||||
|
|
||||||
def bake_to_image(self, vert_pos, vert_nor, name, output_dir):
|
def bake_to_image(self, pos_array, nor_array, pos_max, pos_min, extra_x, img_size, name, output_dir):
|
||||||
|
|
||||||
pos_array = np.array(vert_pos)
|
|
||||||
nor_array = np.array(vert_nor)
|
|
||||||
pos_max = np.amax(pos_array)
|
|
||||||
pos_min = np.amin(pos_array)
|
|
||||||
|
|
||||||
pos_array_scaled = np.interp(pos_array, (pos_min, pos_max), (0, 1))
|
pos_array_scaled = np.interp(pos_array, (pos_min, pos_max), (0, 1))
|
||||||
|
|
||||||
self.write_output_image(pos_array_scaled, name + '_pos', output_dir)
|
self.write_output_image(pos_array_scaled, extra_x, img_size, name + '_morph_pos', output_dir)
|
||||||
|
|
||||||
nor_array_scaled = np.interp(nor_array, (-1, 1), (0, 1))
|
nor_array_scaled = np.interp(nor_array, (-1, 1), (0, 1))
|
||||||
|
|
||||||
self.write_output_image(nor_array_scaled, name + '_nor', output_dir)
|
self.write_output_image(nor_array_scaled, extra_x, img_size, name + '_morph_nor', output_dir)
|
||||||
|
|
||||||
return pos_min, pos_max
|
|
||||||
|
|
||||||
def write_output_image(self, data, name, output_dir):
|
def write_output_image(self, data, extra_x, img_size, name, output_dir):
|
||||||
|
|
||||||
size = len(data[0]), len(data)
|
size = len(data[0]), len(data)
|
||||||
|
|
||||||
|
print("size 0 =")
|
||||||
|
print(size[0])
|
||||||
|
print("size 1 =")
|
||||||
|
print(size[1])
|
||||||
|
print(len(data))
|
||||||
|
print(len(data[0]))
|
||||||
|
print(len(data[0][0]))
|
||||||
|
data = np.pad(data, ((0, 0), (0, extra_x), (0, 0)), 'minimum')
|
||||||
|
print(len(data))
|
||||||
|
print(len(data[0]))
|
||||||
|
print(len(data[0][0]))
|
||||||
|
|
||||||
|
print("img_size = ")
|
||||||
|
|
||||||
pixel_list = []
|
pixel_list = []
|
||||||
|
|
||||||
for y in range(size[1]):
|
for y in range(len(data)):
|
||||||
for x in range(size[0]):
|
for x in range(len(data[0])):
|
||||||
# assign RGBA
|
# assign RGBA
|
||||||
pixel_list.append(data[y, x, 0])
|
pixel_list.append(data[y, x, 0])
|
||||||
pixel_list.append(data[y, x, 1])
|
pixel_list.append(data[y, x, 1])
|
||||||
pixel_list.append(data[y, x, 2])
|
pixel_list.append(data[y, x, 2])
|
||||||
pixel_list.append(1.0)
|
pixel_list.append(1.0)
|
||||||
|
|
||||||
image = bpy.data.images.new(name, width = size[0], height = size[1], is_data = True)
|
image = bpy.data.images.new(name, width = img_size, height = img_size, is_data = True)
|
||||||
image.pixels = pixel_list
|
image.pixels = pixel_list
|
||||||
image.save_render(output_dir + name + ".png", scene= bpy.context.scene)
|
image.save_render(output_dir + name + ".png", scene= bpy.context.scene)
|
||||||
bpy.data.images.remove(image)
|
bpy.data.images.remove(image)
|
||||||
|
|
||||||
|
def get_best_image_size(self, size):
|
||||||
|
|
||||||
|
for i in range(1, 12):
|
||||||
|
block_len = pow(2, i)
|
||||||
|
block_height = np.ceil(size[0]/block_len)
|
||||||
|
if(block_height * size[1] <= block_len):
|
||||||
|
extra_zeros_x = block_height * block_len - size[0]
|
||||||
|
return pow(2,i), round(extra_zeros_x), block_height
|
||||||
|
|
||||||
|
return 0, 0, 0
|
||||||
|
|
||||||
def create_morph_uv_set(self, obj):
|
def remove_morph_uv_set(self, obj):
|
||||||
|
layer = obj.data.uv_layers.get('UVMap_shape_key')
|
||||||
|
if(layer is not None):
|
||||||
|
obj.data.uv_layers.remove(layer)
|
||||||
|
|
||||||
|
def create_morph_uv_set(self, obj, img_size):
|
||||||
|
|
||||||
if(obj.data.uv_layers.get('UVMap_shape_key') is None):
|
if(obj.data.uv_layers.get('UVMap_shape_key') is None):
|
||||||
obj.data.uv_layers.new(name = 'UVMap_shape_key')
|
obj.data.uv_layers.new(name = 'UVMap_shape_key')
|
||||||
|
|
||||||
|
@ -1229,14 +1270,18 @@ class ArmoryExporter:
|
||||||
bm.from_mesh(obj.data)
|
bm.from_mesh(obj.data)
|
||||||
uv_layer = bm.loops.layers.uv.get('UVMap_shape_key')
|
uv_layer = bm.loops.layers.uv.get('UVMap_shape_key')
|
||||||
|
|
||||||
pixel_size = 1.0 / len(bm.verts)
|
pixel_size = 1.0 / img_size
|
||||||
|
|
||||||
i= 0
|
i = 0
|
||||||
|
j = 0
|
||||||
for v in bm.verts:
|
for v in bm.verts:
|
||||||
for l in v.link_loops:
|
for l in v.link_loops:
|
||||||
uv_data = l[uv_layer]
|
uv_data = l[uv_layer]
|
||||||
uv_data.uv = Vector(((i + 0.5) * pixel_size, 0.0))
|
uv_data.uv = Vector(((i + 0.5) * pixel_size, (j + 0.5) * pixel_size))
|
||||||
i += 1
|
i += 1
|
||||||
|
if(i > img_size - 1):
|
||||||
|
j += 1
|
||||||
|
i = 0
|
||||||
|
|
||||||
bm.to_mesh(obj.data)
|
bm.to_mesh(obj.data)
|
||||||
bm.free()
|
bm.free()
|
||||||
|
@ -1295,12 +1340,12 @@ class ArmoryExporter:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
for i in range(0, len(uv_layers)):
|
for i in range(0, len(uv_layers)):
|
||||||
if uv_layers[i].active_render and uv_layers[i].name is not 'UVMap_shape_key':
|
if uv_layers[i].active_render and uv_layers[i].name != 'UVMap_shape_key':
|
||||||
t0map = i
|
t0map = i
|
||||||
break
|
break
|
||||||
if has_tex1:
|
if has_tex1:
|
||||||
for i in range(0, len(uv_layers)):
|
for i in range(0, len(uv_layers)):
|
||||||
if i is not t0map and uv_layers.name is not 'UVMap_shape_key':
|
if i != t0map and uv_layers.name != 'UVMap_shape_key':
|
||||||
t1map = i
|
t1map = i
|
||||||
t1data = np.empty(num_verts * 2, dtype='<f4')
|
t1data = np.empty(num_verts * 2, dtype='<f4')
|
||||||
# Scale for packed coords
|
# Scale for packed coords
|
||||||
|
@ -1569,6 +1614,9 @@ Make sure the mesh only has tris/quads.""")
|
||||||
|
|
||||||
shape_keys = ArmoryExporter.get_shape_keys(mesh)
|
shape_keys = ArmoryExporter.get_shape_keys(mesh)
|
||||||
if shape_keys:
|
if shape_keys:
|
||||||
|
if self.get_export_vcols(bobject.data):
|
||||||
|
log.warn(oid + ' has vertex colors. Shape keys are not supported for objects with vertex colors')
|
||||||
|
shape_keys = False
|
||||||
# Save the morph state
|
# Save the morph state
|
||||||
active_shape_key_index = bobject.active_shape_key_index
|
active_shape_key_index = bobject.active_shape_key_index
|
||||||
show_only_shape_key = bobject.show_only_shape_key
|
show_only_shape_key = bobject.show_only_shape_key
|
||||||
|
@ -1576,11 +1624,6 @@ Make sure the mesh only has tris/quads.""")
|
||||||
# Reset morph state to base for mesh export
|
# Reset morph state to base for mesh export
|
||||||
bobject.active_shape_key_index = 0
|
bobject.active_shape_key_index = 0
|
||||||
bobject.show_only_shape_key = True
|
bobject.show_only_shape_key = True
|
||||||
if self.get_export_vcols(bobject.data):
|
|
||||||
log.warn(oid + ' has vertex colors. Shape keys are not supported for objects with vertex colors')
|
|
||||||
shape_keys = False
|
|
||||||
else:
|
|
||||||
self.create_morph_uv_set(bobject)
|
|
||||||
self.depsgraph.update()
|
self.depsgraph.update()
|
||||||
|
|
||||||
armature = bobject.find_armature()
|
armature = bobject.find_armature()
|
||||||
|
@ -1591,6 +1634,9 @@ Make sure the mesh only has tris/quads.""")
|
||||||
|
|
||||||
if shape_keys:
|
if shape_keys:
|
||||||
self.export_shape_keys(bobject, export_mesh, out_mesh)
|
self.export_shape_keys(bobject, export_mesh, out_mesh)
|
||||||
|
self.depsgraph.update()
|
||||||
|
bobject_eval = bobject.evaluated_get(self.depsgraph) if apply_modifiers else bobject
|
||||||
|
export_mesh = bobject_eval.to_mesh()
|
||||||
|
|
||||||
if export_mesh is None:
|
if export_mesh is None:
|
||||||
log.warn(oid + ' was not exported')
|
log.warn(oid + ' was not exported')
|
||||||
|
|
Loading…
Reference in a new issue