296 lines
10 KiB
Python
296 lines
10 KiB
Python
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 |