建模程序 多个定时程序
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

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