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.
296 lines
10 KiB
296 lines
10 KiB
import platform,sys,redis,time,requests,json,atexit |
|
sys.path.append('../libs/') |
|
|
|
import config,libs,libs_db_temp,common |
|
|
|
import os, sys, time, argparse, requests, json, re, oss2 |
|
import bpy |
|
import open3d as o3d |
|
import shutil |
|
import psutil |
|
# 下载 obj mtl jpg 文件 修正obj 的贴地板 及身高尺寸 生成预览图 |
|
|
|
#文件存储lua路径 |
|
diskName = "G:\\" |
|
filePath = "G://obj_fix/auto" |
|
#获取真实身高 |
|
def get_real_height(input_path): |
|
get_real_height_url = 'https://mp.api.suwa3d.com/api/physical/infoByPid' |
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: Getting real height from {input_path}') |
|
pid = re.findall(r'(\d+)', input_path)[0] |
|
print(f'pid: {pid}') |
|
res = requests.get(get_real_height_url, params={'pid': pid}) |
|
res = json.loads(res.text) |
|
if res['code'] == -1: |
|
print(f'Error: {res["message"]}, return default height 160') |
|
return 160 |
|
height = res['data']['height'] |
|
if height == 0: |
|
print(f'Error: height=0, return default height 160') |
|
return 160 |
|
print(f'height: {height}') |
|
return height |
|
|
|
|
|
def base_fix(input_path): |
|
if not os.path.exists(input_path): |
|
print(f'Error: {input_path} does not exist.') |
|
return "error" |
|
|
|
bpy.ops.wm.read_homefile() |
|
bpy.ops.object.delete(use_global=False, confirm=False) |
|
bpy.ops.wm.obj_import(filepath=input_path) |
|
bpy.context.scene.unit_settings.scale_length = 1 |
|
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) |
|
|
|
# 脚底贴地 |
|
bpy.ops.object.align(align_mode='OPT_1', relative_to='OPT_1', align_axis={'Z'}) |
|
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) |
|
|
|
real_height = get_real_height(input_path) |
|
print(obj.dimensions) |
|
scale = real_height / obj.dimensions[2] / 100 # 除以100是因为单位是厘米 |
|
bpy.context.object.scale = (scale, scale, scale) |
|
bpy.context.object.rotation_euler = (0, 0, 0) |
|
bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_VOLUME', center='MEDIAN') |
|
bpy.context.object.location[0] = 0 # 移动到特定位置(1m, 1m)是为了让human3d可以正确识别 |
|
bpy.context.object.location[1] = 0 |
|
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) |
|
|
|
# # bpy.ops.wm.save_mainfile(filepath=args.input_path.replace('.obj', '.blend')) |
|
# output_file = input_path.replace('.obj', 'test.obj') |
|
bpy.ops.wm.obj_export(filepath=input_path.replace('.obj', '_base_fix.obj')) |
|
return obj |
|
|
|
#检测mtl文件最后一行是否 map_Kd 7126Tex1.jpg |
|
def check_mtl(tempMtlFilePath,pid): |
|
start_time = time.time() |
|
print(f"{pid}-开始检测mtl文件-开始时间-{start_time}") |
|
#读取mtl文件 |
|
if not os.path.exists(tempMtlFilePath): |
|
return False |
|
with open(tempMtlFilePath, 'r', encoding='utf-8') as f: |
|
lines = f.readlines() |
|
if len(lines) > 0: |
|
line = lines[-1] |
|
print(line) |
|
if "map_Kd" in line and f"{pid}Tex1.jpg" in line: |
|
print(f"{pid}-检测mtl文件-成功-耗时-{time.time()-start_time}") |
|
return True |
|
else: |
|
#删除最后一行 |
|
if "map_Kd" in line and f"{pid}.jpg" in line: |
|
lines.pop() |
|
#最后一行插入 map_Kd 7126Tex1.jpg |
|
lines.append(f"map_Kd {pid}Tex1.jpg\n") |
|
with open(tempMtlFilePath, 'w', encoding='utf-8') as f: |
|
f.writelines(lines) |
|
print(f"{pid}-检测mtl文件-成功-耗时-{time.time()-start_time}") |
|
return True |
|
print(f"{pid}-检测mtl文件-失败-耗时-{time.time()-start_time}") |
|
return False |
|
|
|
|
|
#生成预览图 |
|
def create_preview(obj_file_path,image_save_path,pid): |
|
|
|
start_time = time.time() |
|
print(f"{pid}-开始生成预览图-开始时间-{start_time}") |
|
# 加载 OBJ 文件 |
|
mesh = o3d.io.read_triangle_mesh(obj_file_path,enable_post_processing=True) |
|
mesh.compute_vertex_normals() |
|
# 创建视觉化窗口 |
|
# o3d.visualization.MeshColorOption = o3d.visualization.MeshColorOption.Default |
|
vis = o3d.visualization.Visualizer() |
|
# render = o3d.visualization.RenderOption() |
|
width = 800 |
|
height = 600 |
|
vis.create_window(width=width, height=height,visible=False) |
|
# 添加几何体到视觉化窗口 |
|
vis.add_geometry(mesh) |
|
vis.get_render_option().light_on = True |
|
# vis.get_render_option().mesh_color_option = o3d.visualization.MeshColorOption.Default |
|
vis.get_render_option().mesh_shade_option = o3d.visualization.MeshShadeOption.Default |
|
# render.background_color = [123,251,89] # 将光照强度设置为0.5或更低 |
|
# vis.get_render_option().ambient_intensity = 0.9 # 设置环境光强度 |
|
# vis.get_render_option().directional_light = False # 关闭定向光 |
|
|
|
# vis.get_render_option().line_width = 2.0 |
|
# 更新渲染器并捕获屏幕图像 |
|
vis.update_renderer() |
|
vis.poll_events() |
|
vis.capture_screen_image(image_save_path) |
|
# 关闭窗口 |
|
vis.destroy_window() |
|
|
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: {pid} Run time: ', time.time() - start_time) |
|
|
|
time.sleep(2) |
|
# 检测图片是否存在 |
|
if not os.path.exists(image_save_path): |
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: {pid} Error: {image_save_path} does not exist.') |
|
return False |
|
#判断文件夹是否存在 |
|
if not os.path.exists(f"{filePath}/preview/"): |
|
os.makedirs(f"{filePath}/preview/") |
|
#图片存在则复制到指定的文件夹中 |
|
shutil.copy(image_save_path, f"{filePath}/preview/") |
|
|
|
|
|
return True |
|
|
|
|
|
#检测硬盘容量 |
|
def check_disk(): |
|
# 获取硬盘分区列表 |
|
partitions = psutil.disk_partitions() |
|
|
|
for partition in partitions: |
|
print("分区信息",partition) |
|
# 获取指定分区(比如'C:')的使用情况 |
|
if partition.mountpoint == diskName: # 更改为您要检测的硬盘分区 |
|
usage = psutil.disk_usage(partition.mountpoint) |
|
|
|
free = f'{usage.free / (1024**3):.2f}' |
|
free = float(free) |
|
print(f"{diskName}剩余容量{free}") |
|
if free < 3: |
|
print("硬盘空间不足") |
|
return False |
|
|
|
# print(f"Total: {usage.total / (1024**3):.2f} GB") |
|
# print(f"Used: {usage.used / (1024**3):.2f} GB") |
|
# print(f"Free: {usage.free / (1024**3):.2f} GB") |
|
# print(f"Percentage: {usage.percent}%") |
|
return True |
|
|
|
|
|
# def traverse_directory(directory): |
|
# for root, dirs, files in os.walk(directory): |
|
# print(f"当前目录: {root}") |
|
# print("子目录: ", dirs) |
|
# print("文件: ", files) |
|
# print() |
|
|
|
def readTask(): |
|
#遍历 G:\obj_fix\print\wrong |
|
folder_path = 'G:\\obj_fix\print\wrong' |
|
arrFiles = [] |
|
for root, dirs, files in os.walk(folder_path): |
|
# print(f"当前目录: {root}") |
|
# print("子目录: ", dirs) |
|
arrFiles = files |
|
# print("文件: ", files) |
|
# print() |
|
for file in arrFiles: |
|
if file.endswith('_ok.png'): |
|
#提取pid |
|
pid = file.split('_')[0] |
|
print(pid) |
|
base_fix(f'{filePath}/{pid}/{pid}_new.obj') |
|
|
|
|
|
return |
|
#读取数据库的任务 |
|
pid="164" |
|
base_fix(f'{filePath}/{pid}/{pid}_new.obj') |
|
|
|
#生成预览图 |
|
#res = create_preview(f'{filePath}/{pid}/{pid}_new.obj',f'{filePath}/{pid}/{pid}_preview.png',pid) |
|
|
|
return |
|
|
|
startTimeTask = time.time() |
|
|
|
|
|
pid = libs_db_temp.get_task_by_level() |
|
pid = str(pid) |
|
if pid == "": |
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: 无任务,延时10s') |
|
time.sleep(10) |
|
return |
|
|
|
if int(pid) == 0: |
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: 无任务,延时10s') |
|
time.sleep(10) |
|
return |
|
#记录状态为处理中 |
|
libs_db_temp.update_fix_status(pid,1) |
|
|
|
# #判断对应的文件夹是否存在,存在则删除 |
|
# if os.path.exists(f'{filePath}/{pid}'): |
|
# shutil.rmtree(f'{filePath}/{pid}') |
|
|
|
|
|
|
|
# #下载pid的对应的oss端的文件 |
|
# tempName = libs.down_obj_from_oss_for_fix(filePath, pid, "print") |
|
|
|
# if tempName == "no_file": |
|
# #记录状态为异常 -3 文件不存在 |
|
# libs_db_temp.update_fix_status(pid,-3) |
|
# return "error" |
|
|
|
|
|
# if tempName == "error": |
|
# #记录状态为异常 -1 |
|
# libs_db_temp.update_fix_status(pid,-2) |
|
# return "error" |
|
|
|
# if tempName == "": |
|
# print("找不到对应的obj文件") |
|
# #记录状态为异常 -1 |
|
# libs_db_temp.update_fix_status(pid,-1) |
|
# return |
|
|
|
|
|
# #处理逻辑 |
|
# print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())+"-"+pid+"-开始执行任务") |
|
# try: |
|
# res=base_fix(f'{filePath}/{pid}/{pid}.obj') |
|
# if res == "error": |
|
# #记录状态为异常 -2 |
|
# libs_db_temp.update_fix_status(pid,-1) |
|
# return "error" |
|
# #记录状态为成功 2 |
|
# # libs_db_temp.update_fix_status(pid,2) |
|
# except Exception as e: |
|
# #状态异常 -2 |
|
# libs_db_temp.update_fix_status(pid,-1) |
|
# return "error" |
|
|
|
# #检测 mtl文件是否有map_Kd 7126Tex1.jpg |
|
# res = check_mtl(f'{filePath}/{pid}/{pid}.mtl',pid) |
|
# if res == False: |
|
# #记录状态为异常 -2 |
|
# libs_db_temp.update_fix_status(pid,-2) |
|
# return "error" |
|
# time.sleep(2) |
|
|
|
#生成预览图 |
|
res = create_preview(f'{filePath}/{pid}/{pid}.obj',f'{filePath}/{pid}/{pid}_preview.png',pid) |
|
if not res: |
|
#记录状态为异常 -2 |
|
libs_db_temp.update_fix_status(pid,-2) |
|
return "error" |
|
libs_db_temp.update_fix_status(pid,2) |
|
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}: {pid} -任务完美结束总耗时: ', time.time() - startTimeTask) |
|
return True |
|
|
|
#程序主入口 |
|
if __name__ == '__main__': |
|
#atexit.register(common.notify,"处理数据校准任务已经停止") |
|
pid="90864" |
|
base_fix(f'{filePath}/{pid}/{pid}.obj') |
|
# readTask() |
|
# while True: |
|
# pid = readTask() |
|
# res = check_disk() |
|
# if res == False: |
|
# print("硬盘空间不足,无法执行任务") |
|
# break |