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 file in os.listdir(dirPath): if file.endswith('.obj'): isObjFile = True if file.endswith('.jpg'): isJpgFile = True if file.endswith('.mtl'): isMtlFile = True if localfile.endswith('.obj'): if isObjFile and os.path.exists(localfile): print(f'目录{dirPath}已存在obj文件,跳过') continue if localfile.endswith('.jpg'): if isJpgFile and os.path.exists(localfile): print(f'目录{dirPath}已存在jpg文件,跳过') continue if localfile.endswith('.mtl'): if isMtlFile and os.path.exists(localfile): print(f'目录{dirPath}已存在mtl文件,跳过') continue 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 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 order_id 自定义尺寸/默认四个尺寸就不填')