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.
 
 
 

368 lines
15 KiB

from ctypes import util
import os, oss2, time, redis, requests, shutil, sys, subprocess, json, platform,random
from PIL import Image, ImageDraw, ImageFont
from retrying import retry
import atexit,platform
import get_preview_image
# if platform.system() == 'Windows':
# sys.path.append('libs\\')
sys.path.append('/home/acprint/code/libs/')
import common
#创建文本文件
def creatDoingLog(order_id):
#在指定路径创建一条 order_id.txt 文本
file_path = f"doingLog/{order_id}.txt"
if os.path.exists(file_path):
return
#创建
with open(file_path, "w", encoding="utf-8") as file:
file.write("1")
#移除指定的文本文件
def removeDoingLog(order_id):
file_path = f"doingLog/{order_id}.txt"
if not os.path.exists(file_path):
return
os.remove(file_path)
#遍历文件夹,返回指定的order_id
def get_order_id_by_txt():
#遍历文件夹
for file in os.listdir("doingLog"):
if file != "":
arrFile = file.split(".")
return arrFile[0]
return None
def find_blender_bin_path():
if platform.system() == 'Linux': return '/home/acprint/code/blender/blender'
base_path = 'C:\\Program Files\\Blender Foundation\\'
if os.path.exists(base_path):
for dir in os.listdir(base_path):
if dir.startswith('Blender'):
blender_bin_path = base_path + dir + '\\blender.exe'
return f'"{blender_bin_path}"'
else:
print('未找到blender安装目录')
exit(1)
@retry(stop_max_attempt_number=10, wait_fixed=3000)
def down_obj_fromoss(pid, print_type=1, order_id=None,download_flag="print_build"):
# print_type:// 打印状态 1:正常打印 2:重打 3:加打,4: 样品
print('开始下载obj文件...' , pid)
if not order_id is None:
path = os.path.join(workdir, 'print', f'{pid}_{order_id}')
else:
path = os.path.join(workdir, 'print', pid)
if not os.path.exists(path): os.makedirs(path)
# 根据前缀获取文件列表
prefix = f'objs/print/{pid}/'
filelist = oss2.ObjectIteratorV2(oss_client, prefix=prefix)
find = False
findTex1Jpg = False
for file in filelist:
filename = file.key.split('/')[-1]
if filename == '': continue
if filename.endswith(f'{pid}.obj'):
find = True
if download_flag == "print_build":
if filename != str(pid)+".obj" and filename != str(pid)+".mtl" and filename != str(pid)+"Tex1.jpg":
continue
localfile = os.path.join(path, filename)
res = oss_client.get_object_to_file(file.key, localfile)
print(f'下载文件:{file.key},状态:{res.status}')
if not find:
filelist = oss2.ObjectIteratorV2(oss_client, prefix=prefix)
for file in filelist:
filename = file.key.split('/')[-1]
if filename == '': continue
if filename.endswith(f'.obj'):
find = True
# if download_flag == "print_build":
# if filename != str(pid)+".obj" and filename != str(pid)+".mtl" and filename != str(pid)+"Tex1.jpg":
# continue
localfile = os.path.join(path, filename)
res = oss_client.get_object_to_file(file.key, localfile)
print(f'下载文件:{file.key},状态:{res.status}')
break
if find:
os.rename(localfile, os.path.join(path,f"{pid}.obj"))
#重命名文件
#判断是否有Tex1.jpg
if not os.path.exists(os.path.join(path,f"{pid}Tex1.jpg")):
filelist = oss2.ObjectIteratorV2(oss_client, prefix=prefix)
for file in filelist:
filename = file.key.split('/')[-1]
if filename == '': continue
if filename.endswith(f'{pid}.jpg'):
findTex1Jpg = True
# if download_flag == "print_build":
# if filename != str(pid)+".obj" and filename != str(pid)+".mtl" and filename != str(pid)+"Tex1.jpg":
# continue
localfile = os.path.join(path, filename)
res = oss_client.get_object_to_file(file.key, localfile)
print(f'下载文件:{file.key},状态:{res.status}')
break
if findTex1Jpg:
os.rename(localfile, os.path.join(path,f"{pid}Tex1.jpg"))
#重命名文件
# for file in filelist:
# filename = file.key.split('/')[-1]
# if filename == '': continue
# if filename.endswith(f'{pid}.obj'):
# find = True
# if filename.endswith('.obj'):
# print('找到其他obj文件,采用这个文件来生成需要的尺寸', file)
# shutil.copy(os.path.join(path, file), os.path.join(path, f'{pid}.obj'))
# find = True
# break
if not find:
print('找不到obj文件,跳过')
common.notify(f"{pid}-构建打印文件,找不到obj文件,异常,跳过该任务处理")
# sys.exit(1)
os.system(f'python auto_convert3d.py')
return
# print('下载完成后静默10秒,等待文件写入完成')
# time.sleep(10)
#根据pid获取orderId
def getPidFromOrderId(orderId):
getPidFromOrderId_url = 'https://mp.api.suwa3d.com/api/printOrder/info'
print(f'{getPidFromOrderId_url}?id={orderId}')
res = requests.get(f'{getPidFromOrderId_url}?id={orderId}')
resCode = res.json()['code']
if int(resCode) != 1000:
return -1
print(res.text)
return res.json()['data']
def detect_obj4print(pid, orderId):
for file in os.listdir(os.path.join(workdir, 'print', f'{pid}_{orderId}')):
if file.endswith('.obj') and 'x' in file:
return True
def restart_current_process(new_command):
try:
# 保存新进程的命令
command = new_command.split()
# 启动新进程
new_process = subprocess.Popen(command)
# 打印新进程的PID
print(f"New process started with PID: {new_process.pid}")
# 终止当前进程
os._exit(0)
except Exception as e:
print(f"An error occurred: {e}")
def make3d4print_task(r):
tempOrderId = "0"
try:
if r.llen('model:printOrder') == 0:
time.sleep(5)
# tempOrderId = get_order_id_by_txt()
# if tempOrderId == "0":
# return
except Exception as e:
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), 'redis连接异常,重新连接')
print(e)
time.sleep(5)
r = redis.Redis(host='106.14.158.208', password='kcV2000', port=6379, db=6)
return
orderId = None
if tempOrderId == "0":
orderId = r.lpop('model:printOrder')
else:
orderId = tempOrderId
if orderId is None: return
if type(orderId) != str:
orderId = orderId.decode('utf-8')
# orderId = 56077
res = getPidFromOrderId(orderId)
if res == -1:
print("查询打印订单信息失败,重新开启进程")
#os.system(f'python auto_convert3d.py')
return
pid = str(res['pid'])
if pid == "88985":
return
if pid == "":
return
#创建正在处理的文本内容
creatDoingLog(orderId)
print_type = res['print_type']
digital_type = res['digital_type'] # 0: 只有手办 1: 只有数字模型 2: 手办+数字模型
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'orderId:{orderId} pid:{pid} 生成待打印模型 start', )
isFindObj = False
down_obj_fromoss(pid, print_type, orderId,download_flag="print_build")
# 获取程序运行当前目录
resize_py_path = os.path.join(os.getcwd(), 'blender', 'resize_model.py')
print(f'{blenderbin} -b -P {resize_py_path} -- {orderId}')
os.system(f'{blenderbin} -b -P {resize_py_path} -- {orderId}')
if not detect_obj4print(pid, orderId):
print('obj文件生成异常,退出,重新执行')
restart_current_process("python auto_convert3d.py")
return
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'orderId:{orderId} pid:{pid} 生成待打印模型 end')
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'orderId:{orderId} pid:{pid} 处理鼻孔 start')
if os.path.exists(f'{workdir}/print/{pid}_{orderId}/{pid}Tex1_old.jpg'):
print('已经处理过鼻孔,跳过')
else:
os.system(f'python fix_nose.py {pid}_{orderId}')
#上传jpg文件
oss_client.put_object_from_file(f'objs/print/{pid}/{pid}Tex1.jpg', os.path.join(workdir, 'print', f'{pid}_{orderId}', f'{pid}Tex1.jpg'))
# oss_client.put_object_from_file(f'objs/print/{pid}/{pid}Tex1_old.jpg', os.path.join(workdir, 'print', f'{pid}_{orderId}', f'{pid}Tex1_old.jpg'))
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'orderId:{orderId} pid:{pid} 处理鼻孔 end')
# print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'orderId:{orderId} pid:{pid} 生成脚底板二维码 start')
# os.system(f'{blenderbin} -b -P d:\\apps\\blender\\auto_dm.py -- {pid}_{orderId}')
# print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'orderId:{orderId} pid:{pid} 生成脚底板二维码 end')
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'orderId:{orderId} pid:{pid} 上传生成的模型 start')
path = os.path.join(workdir, 'print', f'{pid}_{orderId}')
# 如果指定文件夹目标文件存在,则先删除
if os.path.exists(os.path.join(workdir, f'complate/objs/{pid}/order_{orderId}/')):
delete_files_in_directory(os.path.join(workdir, f'complate/objs/{pid}/order_{orderId}/'))
for file in os.listdir(path):
# 跳过一些不需要上传的文件
if file in [f'{pid}.png',f'{pid}_old.jpg', f'{pid}.obj', f'{pid}_decimate.glb', f'{pid}_decimate.obj', f'{pid}_decimate.mtl', f'{pid}Tex1_decimate.jpg', f'{pid}_original.obj', f'{pid}_original.mtl']: continue
print("当前目录",os.path.join(path, file))
#将文件移动到指定目录
if not os.path.exists(os.path.join(workdir, f'complate/objs/{pid}/')):
os.makedirs(os.path.join(workdir, f'complate/objs/{pid}/'),mode=0o777, exist_ok=True)
if not os.path.exists(os.path.join(workdir, f'complate/objs/{pid}/order_{orderId}/')):
os.makedirs(os.path.join(workdir, f'complate/objs/{pid}/order_{orderId}/'),mode=0o777, exist_ok=True)
shutil.move(os.path.join(path, file), os.path.join(workdir, f'complate/objs/{pid}/order_{orderId}/'))
# oss_client.put_object_from_file(f'objs/print/{pid}/{file}', os.path.join(path, file))
# texture_file = os.path.join(path, f'{pid}Tex1_decimate.jpg')
# if os.path.exists(texture_file):
# img = Image.open(texture_file)
# img = img.resize((int(img.size[0] * 0.5), int(img.size[1] * 0.5)))
# img.save(texture_file, quality=90, optimize=True)
# print('resize texture file to 50% success')
input = os.path.join(path, f'{pid}_decimate.obj')
output = os.path.join(path, f'{pid}_decimate.glb')
# os.system(f'gltfpack -c -i {input} -o {output}')
# oss_client.put_object_from_file(f'glbs/3d/{pid}.glb', output)
shutil.rmtree(path, ignore_errors=True)
print(f'{update_makeprintobj_status_url}?id={orderId}')
if digital_type == 1:
print('只有数字模型,不需要推送手办打印任务,仍有调用接口')
res = requests.get(f'{update_makeprintobj_status_url}?id={orderId}')
print('更新打印状态:', res.text)
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'orderId:{orderId} pid:{pid} 上传生成的模型 end')
removeDoingLog(orderId)
#生成封面图片
print('小票封面图处理中....')
get_preview_image.createImage(pid)
#os.system(f'python get_preview_image.py {pid}')
print(f"{pid}-已处理结束")
restart_current_process("python auto_convert3d.py")
def delete_files_in_directory(directory):
for file_name in os.listdir(directory):
file_path = os.path.join(directory, file_name)
try:
if os.path.isfile(file_path):
os.remove(file_path)
print(f"Deleted: {file_path}")
except Exception as e:
print(f"Error deleting {file_path}: {e}")
def create_redis_connection():
"""创建 Redis 连接,若连接失败则重试"""
while True:
try:
r = redis.Redis(host="106.14.158.208", password="kcV2000", port=6379, db=6)
# 尝试进行一次操作,检查连接是否有效
r.ping() # ping 操作是一个简单的连接测试
print("Redis连接成功!")
return r
except ConnectionError:
print("Redis连接失败,正在重试...")
time.sleep(5)
def main(r):
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), '模型生成程序 start')
while True:
try:
#随机休眠 1- 9
time.sleep(random.uniform(1, 9))
#构建打印文件
make3d4print_task(r)
except Exception as e:
print(f'出现异常:{e}')
time.sleep(15)
r = create_redis_connection()
continue
if __name__ == '__main__':
# atexit.register(common.notify,"虚拟机,生成打印任务程序停止")
AccessKeyId = 'LTAI5tSReWm8hz7dSYxxth8f'
AccessKeySecret = '8ywTDF9upPAtvgXtLKALY2iMYHIxdS'
Endpoint = 'oss-cn-shanghai.aliyuncs.com'
Bucket = 'suwa3d-securedata'
oss_client = oss2.Bucket(oss2.Auth(AccessKeyId, AccessKeySecret), Endpoint, Bucket)
update_check_url = 'https://mp.api.suwa3d.com/api/customerP3dLog/updateStatusToWaitingPlatformCheckingStatus'
update_team_check_url = 'https://mp.api.suwa3d.com/api/customerP3dLog/updateStatusToWaitingTeamCheckingStatus'
update_status_printstatus_url = 'https://mp.api.suwa3d.com/api/customerP3dLog/updateBuildPrintModelStatus'
update_makeprintobj_status_url = 'https://mp.api.suwa3d.com/api/printOrder/updateMakePrintObjSucceed'
getRepairInfo_url = 'https://repair.api.suwa3d.com/api/modelRepairOrder/teamCheckGLBInfo'
update_repair_status_url = 'https://repair.api.suwa3d.com/api/modelRepairOrder/updateStatusToWaitingTeamCheckingStatus'
if platform.system() == 'Windows':
workdir = 'E:\\'
else:
workdir = '/data/datasets/'
blenderbin = find_blender_bin_path()
r = create_redis_connection()
#E:\\complate/objs/147852_54579/
# os.remove(os.path.join(workdir, f'complate/objs/147852_54579/'))
main(r)