You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
4.7 KiB
144 lines
4.7 KiB
from math import radians |
|
import sys, os, time, bpy, requests, json, bmesh |
|
|
|
def get_obj_version(filename): |
|
with open(filename, 'r') as f: |
|
for line in f: |
|
if line.startswith('# Engine version'): |
|
return float(line.split(' ')[-1][1:].strip()[:3]) |
|
exit(0) |
|
return None |
|
|
|
def delete_lines_in_file(filename, count): |
|
with open(filename, 'r') as f: |
|
lines = f.readlines() |
|
lines = lines[count:] |
|
with open(filename, 'w') as f: |
|
f.writelines(lines) |
|
|
|
def diff_minutes_and_seconds(start): |
|
hours = int((time.time() - start) / 3600) |
|
minutes = int((time.time() - start) / 60) |
|
seconds = int((time.time() - start) % 60) |
|
microseconds = int(int((time.time() - start) * 1000000) % 1000000 / 1000) |
|
return f'{hours}:{minutes}:{seconds}.{microseconds}' |
|
|
|
def getPSid(pid): |
|
get_psid_url = 'https://mp.api.suwa3d.com/api/customerP3dLog/photoStudio' |
|
res = requests.get(get_psid_url, params={'pid': pid}) |
|
res = json.loads(res.text) |
|
return str(res['data']) |
|
|
|
def bmesh_copy_from_object(obj, transform=True, triangulate=True, apply_modifiers=False): |
|
"""Returns a transformed, triangulated copy of the mesh""" |
|
assert obj.type == 'MESH' |
|
if apply_modifiers and obj.modifiers: |
|
import bpy |
|
depsgraph = bpy.context.evaluated_depsgraph_get() |
|
obj_eval = obj.evaluated_get(depsgraph) |
|
me = obj_eval.to_mesh() |
|
bm = bmesh.new() |
|
bm.from_mesh(me) |
|
obj_eval.to_mesh_clear() |
|
else: |
|
me = obj.data |
|
if obj.mode == 'EDIT': |
|
bm_orig = bmesh.from_edit_mesh(me) |
|
bm = bm_orig.copy() |
|
else: |
|
bm = bmesh.new() |
|
bm.from_mesh(me) |
|
if transform: |
|
matrix = obj.matrix_world.copy() |
|
if not matrix.is_identity: |
|
bm.transform(matrix) |
|
matrix.translation.zero() |
|
if not matrix.is_identity: |
|
bm.normal_update() |
|
if triangulate: |
|
bmesh.ops.triangulate(bm, faces=bm.faces) |
|
return bm |
|
|
|
|
|
def main(): |
|
start = time.time() |
|
config = { |
|
'0': { |
|
'rotation': (radians(0), radians(0), radians(0)), |
|
}, |
|
'1': { |
|
'rotation': (radians(0), radians(0), radians(66)), |
|
}, |
|
'29': { |
|
'rotation': (radians(0), radians(0), radians(180)), |
|
}, |
|
'45': { |
|
'rotation': (radians(0), radians(0), radians(105)), |
|
}, |
|
'46': { |
|
'rotation': (radians(0), radians(0), radians(-10)), |
|
}, |
|
'74': { |
|
'rotation': (radians(0), radians(0), radians(110)), |
|
}, |
|
'75': { |
|
'rotation': (radians(0), radians(0), radians(210)), |
|
}, |
|
} |
|
workdir = 'd:\\' |
|
|
|
if len(sys.argv) - (sys.argv.index("--") +1) < 1: |
|
print("Usage: blender -b -P autofix.py -- <pids>") |
|
sys.exit(1) |
|
input_file = sys.argv[sys.argv.index("--") + 1] |
|
|
|
for pid in input_file.split(','): |
|
psid = getPSid(pid) |
|
|
|
bpy.ops.object.delete(use_global=False, confirm=False) |
|
|
|
filename = f'{workdir}{pid}\\output\{pid}.obj' |
|
print('正在处理:', filename) |
|
bpy.ops.import_scene.obj(filepath=filename) |
|
bpy.ops.object.align(relative_to='OPT_1', align_axis={'X'}) |
|
# bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) |
|
print('import obj time:', diff_minutes_and_seconds(start)) |
|
|
|
# rotate obj |
|
obj = bpy.context.selected_objects[0] |
|
bpy.context.view_layer.objects.active = obj |
|
obj.select_set(True) |
|
|
|
if psid in config: |
|
obj.rotation_euler = config[psid]['rotation'] |
|
else: |
|
obj.rotation_euler = config['0']['rotation'] |
|
print('rotate obj time:', diff_minutes_and_seconds(start)) |
|
# bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) |
|
|
|
# resize object |
|
obj_scale = 90 / obj.dimensions.z |
|
print('scale:', obj_scale) |
|
|
|
obj.scale = (obj_scale, obj_scale, obj_scale) |
|
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) |
|
|
|
bm = bmesh_copy_from_object(obj) |
|
obj_volume = round(bm.calc_volume() / 1000, 3) |
|
print('volume:', obj_volume) |
|
print('weight:', obj_volume * 1.2, 'g') |
|
|
|
faces = len(obj.data.polygons) |
|
print('faces:', faces) |
|
|
|
# save object |
|
bpy.ops.export_scene.obj(filepath=f'{workdir}{pid}\\output\{pid}.obj') |
|
# render scene to a file |
|
# bpy.context.scene.render.filepath = f'{workdir}{pid}_fixed.png' |
|
# bpy.ops.render.render(write_still=True, use_viewport=True) |
|
print('render time:', diff_minutes_and_seconds(start)) |
|
|
|
bpy.ops.wm.quit_blender() |
|
|
|
if __name__ == '__main__': |
|
main() |