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.
175 lines
6.0 KiB
175 lines
6.0 KiB
import os, sys, time, bpy, bmesh, shutil,requests,json |
|
import platform,oss2 |
|
if platform.system() == 'Windows': |
|
sys.path.append('e:\\libs\\') |
|
else: |
|
sys.path.append('/data/deploy/make3d/make2/libs/') |
|
|
|
import config, libs, libs_db |
|
|
|
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 reload_obj(pid, action): |
|
obj_filename = os.path.join(config.workdir, action, pid, f'{pid}.obj') |
|
bpy.ops.wm.read_homefile() |
|
bpy.ops.object.delete(use_global=False, confirm=False) |
|
bpy.ops.import_scene.obj(filepath=obj_filename) |
|
bpy.context.scene.unit_settings.scale_length = 0.001 |
|
bpy.context.scene.unit_settings.length_unit = 'CENTIMETERS' |
|
bpy.context.scene.unit_settings.mass_unit = 'GRAMS' |
|
|
|
obj = bpy.context.selected_objects[0] |
|
bpy.context.view_layer.objects.active = obj |
|
obj.select_set(True) |
|
|
|
return obj |
|
|
|
def cal_weight(obj, size): |
|
# 统一缩放到9cm标准尺寸 |
|
scale = size / obj.dimensions.z |
|
obj.scale = (scale, scale, scale) |
|
bpy.ops.object.transform_apply(scale=True) |
|
|
|
# bpy.ops.wm.save_as_mainfile(filepath=os.path.join(config.workdir, action, pid, f'{pid}-{size/10}cm.blend')) |
|
model_info = {} |
|
bm = bmesh_copy_from_object(obj) |
|
model_info['volume'] = round(bm.calc_volume() / 1000) |
|
model_info['weight'] = round(model_info['volume'] * 1.226) |
|
print(f'{size/10}cm:体积 {model_info["volume"]}cm³, 克重 {model_info["weight"]}g') |
|
return model_info["weight"] |
|
|
|
def down_obj_from_oss(workdir, pid, action): |
|
if os.path.exists(os.path.join(workdir, action, pid)): |
|
print(f'目录{os.path.join(workdir, action, pid)}已存在,跳过') |
|
return |
|
else: |
|
os.makedirs(os.path.join(workdir, action, pid)) |
|
|
|
# 根据前缀获取文件列表 |
|
prefix = f'objs/{action}/{pid}/' |
|
filelist = oss2.ObjectIteratorV2(config.oss_bucket, prefix=prefix) |
|
print('正在下载:', prefix) |
|
obj_filename = "" |
|
dirPath = os.path.join(workdir, action, pid) |
|
for file in filelist: |
|
filename = file.key.split('/')[-1] |
|
if filename.endswith('.obj'): |
|
obj_filename = filename |
|
# print('正在下载:', file.key) |
|
localfile = os.path.join(workdir, action, pid, filename) |
|
#判断目录里是否已经存在obj文件了 |
|
isObjFile = False |
|
isJpgFile = False |
|
isMtlFile = False |
|
for file1 in os.listdir(dirPath): |
|
if file1.endswith('.obj'): |
|
isObjFile = True |
|
|
|
if file1.endswith('.jpg'): |
|
isJpgFile = True |
|
|
|
if file1.endswith('.mtl'): |
|
isMtlFile = True |
|
|
|
|
|
if "obj" in localfile: |
|
if isObjFile: |
|
print(f'目录{dirPath}已存在obj文件,跳过') |
|
continue |
|
|
|
if "jpg" in localfile: |
|
if isJpgFile: |
|
print(f'目录{dirPath}已存在jpg文件,跳过') |
|
continue |
|
|
|
if "mtl" in localfile: |
|
if isMtlFile: |
|
print(f'目录{dirPath}已存在mtl文件,跳过') |
|
continue |
|
|
|
print(f'下载文件{file.key}到{localfile} ---- isobj= {isObjFile} isjpg= {isJpgFile} ismtl= {isMtlFile}') |
|
config.oss_bucket.get_object_to_file(file.key, localfile) |
|
|
|
return obj_filename |
|
|
|
|
|
def main(action, pid, sizes,orderId=0): |
|
down_obj_from_oss(config.workdir, pid, action) |
|
obj = reload_obj(pid, action) |
|
|
|
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) |
|
print(f'模型{pid}的体积与克重估算信息:') |
|
arrData = {} |
|
for size in sizes: |
|
size = float(size) |
|
weight = cal_weight(obj, size) |
|
size = str(size/10)+"cm" |
|
arrData[size] = str(weight)+"g" |
|
|
|
#请求接口进行更新数据 |
|
arrParams = {"pid":pid,"order_id":orderId} |
|
if action == "auto": |
|
arrParams["auto_weight"] = json.dumps(arrData) |
|
|
|
if action == "print": |
|
arrParams["print_weight"] = json.dumps(arrData) |
|
|
|
#发起请求 |
|
print(f"请求的参数-{arrParams}") |
|
url = "https://mp.api.suwa3d.com/api/physical/addPhysicalWeight" |
|
res = requests.post(url,data=arrParams) |
|
print('res:', res.text) |
|
|
|
|
|
if __name__ == '__main__': |
|
sizes = (90, 120, 150, 180) |
|
|
|
if len(sys.argv) == 3: |
|
action = sys.argv[1] |
|
pids = sys.argv[2].split(',') |
|
for pid in pids: |
|
main(action, pid, sizes) |
|
elif len(sys.argv) == 5: |
|
action = sys.argv[1] |
|
pids = sys.argv[2].split(',') |
|
sizes = sys.argv[3].split(',') |
|
orderId = sys.argv[4] |
|
for pid in pids: |
|
main(action, pid, sizes,orderId) |
|
print('Usage: python cal_weight.py print <pids> order_id 自定义尺寸/默认四个尺寸就不填') |
|
|
|
elif len(sys.argv) == 4: |
|
action = sys.argv[1] |
|
pids = sys.argv[2].split(',') |
|
sizes = sys.argv[3].split(',') |
|
for pid in pids: |
|
main(action, pid, sizes) |
|
print('Usage: python cal_weight.py print <pids> order_id 自定义尺寸/默认四个尺寸就不填') |