Compare commits
17
Commits
f764cb967d
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62f5ede4ba | ||
|
|
c5dbd09ad1 | ||
|
|
06018dad6e | ||
|
|
9600ac4e29 | ||
|
|
26505b78bc | ||
|
|
b793d7cfd5 | ||
|
|
593ed145c2 | ||
|
|
54a278f346 | ||
|
|
4d1e9dff58 | ||
|
|
a84990f7d4 | ||
|
|
dba35f6c36 | ||
|
|
70c9d86c20 | ||
|
|
5cfa3d84af | ||
|
|
f317d7ff41 | ||
|
|
cc752a9da9 | ||
|
|
1c4b698b0f | ||
|
|
0b9b2eb4f0 |
No files matched your search
+2
-2
@@ -71,7 +71,7 @@ def down_obj_fromoss(pid, print_type=1, order_id=None,download_flag="print_build
|
||||
find = True
|
||||
|
||||
if download_flag == "print_build":
|
||||
if filename != str(pid)+".obj" and filename != str(pid)+".mtl" and filename != str(pid)+"Tex1.jpg":
|
||||
if filename != str(pid)+".obj" and filename != str(pid)+".mtl" and filename != str(pid)+"Tex1.jpg" and filename != str(pid)+"_RB_B_Tex1.jpg":
|
||||
continue
|
||||
localfile = os.path.join(path, filename)
|
||||
res = oss_client.get_object_to_file(file.key, localfile)
|
||||
@@ -208,7 +208,7 @@ def make3d4print_task(orderId):
|
||||
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.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')
|
||||
|
||||
|
||||
+11
-2
@@ -71,7 +71,7 @@ def down_obj_fromoss(pid, print_type=1, order_id=None,download_flag="print_build
|
||||
find = True
|
||||
|
||||
if download_flag == "print_build":
|
||||
if filename != str(pid)+".obj" and filename != str(pid)+".mtl" and filename != str(pid)+"Tex1.jpg":
|
||||
if filename != str(pid)+".obj" and filename != str(pid)+".mtl" and filename != str(pid)+"Tex1.jpg" and filename != str(pid)+"_RB_B_Tex1.jpg":
|
||||
continue
|
||||
localfile = os.path.join(path, filename)
|
||||
res = oss_client.get_object_to_file(file.key, localfile)
|
||||
@@ -205,6 +205,14 @@ def make3d4print_task(r):
|
||||
print("查询打印订单信息失败,重新开启进程")
|
||||
#os.system(f'python auto_convert3d.py')
|
||||
return
|
||||
|
||||
#根据 buy_type 判断 是否是冰箱贴 或者徽章
|
||||
buyType = str(res['buy_type'])
|
||||
if buyType == "2" or buyType == "3":
|
||||
#塞入到no_resize 队列
|
||||
r.lpush("model:noresize", orderId)
|
||||
return
|
||||
|
||||
pid = str(res['pid'])
|
||||
if pid == "88985":
|
||||
return
|
||||
@@ -235,7 +243,7 @@ def make3d4print_task(r):
|
||||
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.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')
|
||||
|
||||
@@ -257,6 +265,7 @@ def make3d4print_task(r):
|
||||
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))
|
||||
|
||||
print(f"复制文件路径-{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)
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
from math import radians
|
||||
import sys, platform, os, time, bpy, requests, json, bmesh, shutil
|
||||
from PIL import Image
|
||||
import platform
|
||||
# if platform.system() == 'Windows':
|
||||
# sys.path.append('e:\\libs\\')
|
||||
# else:
|
||||
# sys.path.append('/data/deploy/make3d/make2/libs/')
|
||||
sys.path.append('/home/acprint/code/libs/')
|
||||
import config, libs
|
||||
|
||||
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 fix_link_texture(pid):
|
||||
# 修改obj中的mtl文件为pid_original.mtl
|
||||
path = os.path.join(workdir, 'print', f'{pid}_{orderId}')
|
||||
filename = os.path.join(path, f'{pid}_original.obj')
|
||||
|
||||
with open(filename, 'r') as f:
|
||||
lines = f.readlines()
|
||||
for i in range(len(lines)):
|
||||
if lines[i].startswith('mtllib'):
|
||||
lines[i] = f'mtllib {pid}_original.mtl\n'
|
||||
break
|
||||
with open(filename, 'w') as f:
|
||||
f.writelines(lines)
|
||||
|
||||
f.close()
|
||||
|
||||
# 将pid.mtl文件复制为pid_original.mtl _decimate
|
||||
shutil.copy(os.path.join(path, f'{pid}.mtl'), os.path.join(path, f'{pid}_original.mtl'))
|
||||
shutil.copy(os.path.join(path, f'{pid}Tex1.jpg'), os.path.join(path, f'{pid}Tex1_decimate.jpg'))
|
||||
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=100, optimize=True)
|
||||
print('resize texture file to 50% success')
|
||||
# 修改pid_original.mtl文件中的贴图为pid_old.jpg
|
||||
with open(os.path.join(path, f'{pid}_original.mtl'), 'r') as f:
|
||||
lines = f.readlines()
|
||||
for i in range(len(lines)):
|
||||
if lines[i].startswith('map_Kd'):
|
||||
lines[i] = f'map_Kd {pid}Tex1_decimate.jpg\n'
|
||||
break
|
||||
with open(os.path.join(path, f'{pid}_original.mtl'), 'w') as f:
|
||||
f.writelines(lines)
|
||||
|
||||
f.close()
|
||||
|
||||
def imagePiex(filePath,piex):
|
||||
# 打开图片
|
||||
image = Image.open(filePath)
|
||||
# 设置新的最大宽度和高度
|
||||
max_size = (piex, piex)
|
||||
# 保持宽高比缩放图片
|
||||
image.thumbnail(max_size)
|
||||
# 保存调整后的图片
|
||||
image.save(filePath)
|
||||
|
||||
def main():
|
||||
start = time.time()
|
||||
|
||||
get_printsize_url = 'https://mp.api.suwa3d.com/api/printOrder/infoByOrderId'
|
||||
upload_obj_volume_url = 'https://mp.api.suwa3d.com/api/physical/add' # ?pid=1&order_id=1&faces=1&volume=1
|
||||
|
||||
print(f'{get_printsize_url}?order_id={orderId}')
|
||||
res = requests.get(f'{get_printsize_url}?id={orderId}')
|
||||
print('获取打印尺寸:', res.text)
|
||||
|
||||
if res.status_code == 200:
|
||||
pid = res.json()['data']['pid']
|
||||
path = os.path.join(workdir, 'print', f'{pid}_{orderId}')
|
||||
filename = os.path.join(path, f'{pid}.obj')
|
||||
imagePath = os.path.join(path, f'{pid}Tex1.jpg')
|
||||
bpy.ops.object.delete(use_global=False, confirm=False)
|
||||
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'
|
||||
|
||||
print('正在处理:', filename)
|
||||
bpy.ops.import_scene.obj(filepath=filename)
|
||||
obj = bpy.context.selected_objects[0]
|
||||
print('原始模型尺寸:', obj.dimensions)
|
||||
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
|
||||
print('应用后模型尺寸:', obj.dimensions)
|
||||
shutil.copy(filename, os.path.join(path, f'{pid}_original.obj'))
|
||||
filename_original = os.path.join(path, f'{pid}_original.obj')
|
||||
headcount = res.json()['data']['headcount']
|
||||
for f in res.json()['data']['fileList']:
|
||||
|
||||
if "undefined" in f:
|
||||
continue
|
||||
|
||||
try:
|
||||
height = float(f.split('_')[-2][:-2]) * 10
|
||||
except Exception as e:
|
||||
print("eeee",e)
|
||||
bpy.ops.wm.quit_blender()
|
||||
return
|
||||
|
||||
|
||||
|
||||
obj = bpy.context.selected_objects[0]
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
print(f'{f}处理前{height}mm模型尺寸: {obj.dimensions}')
|
||||
scale = height / obj.dimensions.z
|
||||
obj.scale = (scale, scale, scale)
|
||||
bpy.ops.object.transform_apply(scale=True)
|
||||
print(f'{f}处理后{height}mm模型尺寸: {obj.dimensions}')
|
||||
|
||||
if headcount == 1 and height <= 80:
|
||||
pixs = 4096
|
||||
faces_dest = 125000
|
||||
if height <= 50:
|
||||
pixs = 2048
|
||||
faces_dest = 63000
|
||||
print(f'减面到{faces_dest}')
|
||||
faces_dest = faces_dest * headcount
|
||||
# 减面
|
||||
faces_current = len(obj.data.polygons)
|
||||
bpy.ops.object.modifier_add(type='DECIMATE')
|
||||
bpy.context.object.modifiers["Decimate"].ratio = faces_dest / faces_current
|
||||
bpy.ops.object.modifier_apply(modifier="Decimate")
|
||||
# imagePiex(imagePath,pixs)
|
||||
|
||||
bpy.ops.export_scene.obj(filepath=os.path.join(path, f'{pid}.obj'))
|
||||
if os.path.exists(os.path.join(path, f)):
|
||||
os.remove(os.path.join(path, f))
|
||||
os.rename(os.path.join(path, f'{pid}.obj'), os.path.join(path, f))
|
||||
#config.oss_bucket.put_object_from_file(f'objs/print/{pid}/{f}', os.path.join(path, f))
|
||||
|
||||
|
||||
|
||||
# 重新加载模型,然后生成数字模型
|
||||
bpy.ops.object.delete(use_global=False, confirm=False)
|
||||
fix_link_texture(pid)
|
||||
bpy.ops.import_scene.obj(filepath=filename_original)
|
||||
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)
|
||||
|
||||
scale = 90 / obj.dimensions.y
|
||||
obj.scale = (scale, scale, scale)
|
||||
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
|
||||
# if str(pid) == '120745': bpy.ops.wm.save_as_mainfile(filepath=os.path.join(path, f'{pid}_{orderId}.blend'))
|
||||
|
||||
|
||||
|
||||
bm = bmesh_copy_from_object(obj)
|
||||
obj_volume = round(bm.calc_volume() / 1000, 3)
|
||||
print('volume:', obj_volume)
|
||||
print('weight:', obj_volume * 1.2, 'g')
|
||||
tempWeight = obj_volume * 1.2
|
||||
faces = len(obj.data.polygons)
|
||||
print('faces:', faces)
|
||||
upload_res = requests.get(f'{upload_obj_volume_url}?pid={pid}&order_id={orderId}&faces={faces}&volume={obj_volume}&headcount={headcount}&weight={tempWeight}')
|
||||
print('上传模型体积:', upload_res.text)
|
||||
|
||||
# 生成数字模型
|
||||
|
||||
faces_dest = 120000 * headcount
|
||||
# 减面
|
||||
faces_current = len(obj.data.polygons)
|
||||
bpy.ops.object.modifier_add(type='DECIMATE')
|
||||
bpy.context.object.modifiers["Decimate"].ratio = faces_dest / faces_current
|
||||
bpy.ops.object.modifier_apply(modifier="Decimate")
|
||||
|
||||
bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_VOLUME', center='MEDIAN')
|
||||
bpy.context.object.location[0] = 0
|
||||
bpy.context.object.location[1] = 0
|
||||
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
|
||||
|
||||
bpy.ops.export_scene.obj(filepath=os.path.join(path, f'{pid}_decimate.obj'))
|
||||
bpy.ops.export_scene.gltf(filepath=os.path.join(path, f'{pid}_decimate.glb'), export_format='GLB', export_apply=True, export_jpeg_quality=100)
|
||||
config.oss_bucket.put_object_from_file(f'glbs/3d/{pid}.glb', os.path.join(path, f'{pid}_decimate.glb'))
|
||||
config.oss_bucket.put_object_from_file(f'glbs/3d/order_id/{orderId}.glb', os.path.join(path, f'{pid}_decimate.glb'))
|
||||
bpy.ops.wm.quit_blender()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if platform.system() == 'Windows':
|
||||
workdir = 'E:\\'
|
||||
else:
|
||||
workdir = '/data/datasets/'
|
||||
|
||||
if len(sys.argv) - (sys.argv.index("--") + 1) < 1:
|
||||
print("Usage: blender -b -P resize_model.py -- <orderId>")
|
||||
sys.exit(1)
|
||||
orderId = sys.argv[sys.argv.index("--") + 1]
|
||||
|
||||
main()
|
||||
+37
-2
@@ -144,8 +144,35 @@ def find_obj(pid, order_id):
|
||||
for filename in filelist:
|
||||
if f'{pid}.obj' in filename:
|
||||
find = True
|
||||
#进行图片分辨率的调整
|
||||
# get_printsize_url = 'https://mp.api.suwa3d.com/api/printOrder/info'
|
||||
# res = requests.get(f'{get_printsize_url}?id={order_id}')
|
||||
# print('获取订单信息:', res.text)
|
||||
# if res.status_code == 200:
|
||||
# headcount = res.json()['data']['headcount']
|
||||
# for f in res.json()['data']['fileList']:
|
||||
# if "undefined" in f:
|
||||
# continue
|
||||
# try:
|
||||
# height = float(f.split('_')[-2][:-2]) * 10
|
||||
# except Exception as e:
|
||||
# continue
|
||||
|
||||
# if headcount == 1 and height <= 80:
|
||||
# pixs = 4096
|
||||
# if height <= 5:
|
||||
# pixs = 1024
|
||||
# print(f"图片分辨率进行处理{pixs}")
|
||||
# imagePiex(os.path.join(workdir, f'{pid}_{order_id}', f'{pid}Tex1.jpg'),pixs)
|
||||
|
||||
return filename
|
||||
print('没有找到obj模型文件')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return ''
|
||||
|
||||
def find_pid_objname(pid):
|
||||
@@ -606,10 +633,18 @@ def main(workdir, r, print_id):
|
||||
print("workdirworkdir",workdir)
|
||||
shutil.rmtree(os.path.join(workdir, f'{pid}_{order_id}'))
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 运行{print_id}任务完成,继续运行下一个任务')
|
||||
|
||||
|
||||
# restart_current_process("blender -b -P fill_dm_code.py")
|
||||
|
||||
def imagePiex(filePath,piex):
|
||||
# 打开图片
|
||||
image = Image.open(filePath)
|
||||
# 设置新的最大宽度和高度
|
||||
max_size = (piex, piex)
|
||||
# 保持宽高比缩放图片
|
||||
image.thumbnail(max_size)
|
||||
# 保存调整后的图片
|
||||
image.save(filePath)
|
||||
|
||||
#根据print_id 获取 短网址
|
||||
def get_short_url(print_id):
|
||||
res = requests.get(f'{get_short_url_by_print_id}?print_id={print_id}')
|
||||
|
||||
@@ -0,0 +1,856 @@
|
||||
import os, sys, bpy, math, time, platform, cairosvg, ppf.datamatrix, shutil, requests, json, redis, oss2, cv2,qrcode
|
||||
from retrying import retry
|
||||
import subprocess
|
||||
import multiprocessing
|
||||
import random
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from PIL import Image, ImageEnhance
|
||||
from addon_utils import enable
|
||||
import logging,atexit,platform
|
||||
# if platform.system() == 'Windows':
|
||||
sys.path.append('/home/acprint/code/libs/')
|
||||
import common
|
||||
logging.basicConfig(filename='foot_update_res.log', level=logging.ERROR)
|
||||
enable('io_import_images_as_planes')
|
||||
enable('eyek_addon')
|
||||
|
||||
|
||||
#查询影棚ID
|
||||
def getPSid(pid):
|
||||
res = requests.get("https://mp.api.suwa3d.com/api/customerP3dLog/photoStudio",params={"pid":pid})
|
||||
res = json.loads(res.text)
|
||||
return str(res['data'])
|
||||
|
||||
|
||||
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 gen_data_matrix(print_id,pid, qr_path, size = 300):
|
||||
psid = getPSid(pid)
|
||||
if int(psid) == 0:
|
||||
print("费工夫构建脚底二维码")
|
||||
# if use_foot_type == "short_url":
|
||||
#调用接口获取短网址信息
|
||||
short_url = get_short_url(print_id)
|
||||
if short_url == False:
|
||||
return
|
||||
temp_foot_data = short_url
|
||||
|
||||
#生成二维码
|
||||
qr = qrcode.QRCode(
|
||||
version=1,
|
||||
error_correction = qrcode.constants.ERROR_CORRECT_L,
|
||||
box_size=10,
|
||||
border=2,
|
||||
)
|
||||
qr.add_data(temp_foot_data)
|
||||
qr.make(fit=True)
|
||||
img = qr.make_image(fill_color="black",back_color="white").resize((size,size))
|
||||
img.save(qr_path)
|
||||
else:
|
||||
#正常生成不是常规的二维码
|
||||
print("排除费工夫正常构建二维码")
|
||||
svg = ppf.datamatrix.DataMatrix(f'p{print_id}').svg()
|
||||
cairosvg.svg2png(bytestring=svg, write_to=qr_path, output_width=size, output_height=size, background_color='white')
|
||||
|
||||
def active_object(obj):
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
obj.select_set(True)
|
||||
#下载oss的文件
|
||||
@retry(stop_max_attempt_number=10, wait_fixed=2000)
|
||||
def down_obj_fromoss(pid, print_type=1, order_id=None):
|
||||
# print_type:// 打印状态 1:正常打印 2:重打 3:加打,4: 样品
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 开始下载模型,若网络异常将每间隔2秒重试10次...')
|
||||
if order_id is not None:
|
||||
path = os.path.join(workdir, f'{pid}_{order_id}')
|
||||
else:
|
||||
path = os.path.join(workdir, pid)
|
||||
if os.path.exists(path):
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 已存在模型文件,删除后重新下载')
|
||||
print("AAAAAAAAAAAA")
|
||||
shutil.rmtree(path, ignore_errors=True)
|
||||
print("BBBBBBBBBBBBBBB")
|
||||
os.makedirs(path)
|
||||
|
||||
print("准备下载,获取ossPath")
|
||||
prefix = f'objs/print/{pid}'
|
||||
#根据order_id 获取文件在 oss 上的存储路径
|
||||
if order_id is not None:
|
||||
tempURL = "https://mp.api.suwa3d.com/api/order/getOssSuffixByOrderId?order_id="+str(order_id)
|
||||
res = requests.get(tempURL)
|
||||
print("ossPath res",res.json())
|
||||
resCode = res.json()['code']
|
||||
if int(resCode) != 1000:
|
||||
return -1
|
||||
print(res.text)
|
||||
if res.json()['data'] != "":
|
||||
prefix = f'objs/print/{pid}/{res.json()["data"]}/{str(order_id)}'
|
||||
|
||||
|
||||
print("最终的prefix",prefix)
|
||||
|
||||
# 下载分2种情况,一种是第一次打印,下载标准{pid}.obj,{pid}.mtl,{pid}Tex1.jpg,另一种是重打或加打,obj文件名可以从oss上任意获取一个,但是mtl和jpg文件名是固定的
|
||||
res = oss_client.get_object_to_file(f'{prefix}/{pid}.mtl', os.path.join(path, f'{pid}.mtl'))
|
||||
last_modified = oss_client.get_object_meta(f"{prefix}/{pid}.mtl").last_modified
|
||||
print(f'mtl文件最后修改时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(last_modified))}')
|
||||
print(f'下载文件:{prefix}/{pid}.mtl,状态:{res.status}')
|
||||
if oss_client.object_exists(f'{prefix}/{pid}Tex1.jpg'):
|
||||
res = oss_client.get_object_to_file(f'{prefix}/{pid}Tex1.jpg', os.path.join(path, f'{pid}Tex1.jpg'))
|
||||
last_modified = oss_client.get_object_meta(f"{prefix}/{pid}Tex1.jpg").last_modified
|
||||
print(f'jpg文件最后修改时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(last_modified))}')
|
||||
print(f'下载文件:{prefix}/{pid}Tex1.jpg,状态:{res.status}')
|
||||
else:
|
||||
res = oss_client.get_object_to_file(f'{prefix}/{pid}.jpg', os.path.join(path, f'{pid}Tex1.jpg'))
|
||||
last_modified = oss_client.get_object_meta(f"{prefix}/{pid}.jpg").last_modified
|
||||
print(f'jpg文件最后修改时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(last_modified))}')
|
||||
print(f'下载文件:{prefix}/{pid}.jpg,状态:{res.status}')
|
||||
if oss_client.object_exists(f'{prefix}/{pid}.obj'):
|
||||
res = oss_client.get_object_to_file(f'{prefix}/{pid}.obj', os.path.join(path, f'{pid}.obj'))
|
||||
last_modified = oss_client.get_object_meta(f"{prefix}/{pid}.obj").last_modified
|
||||
print(f'obj文件最后修改时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(last_modified))}')
|
||||
print(f'下载文件:{prefix}/{pid}.obj,状态:{res.status}')
|
||||
else:
|
||||
prefix = f'{prefix}'
|
||||
filelist = oss2.ObjectIteratorV2(oss_client, prefix=prefix)
|
||||
for file in filelist:
|
||||
filename = file.key.split('/')[-1]
|
||||
if filename == '': continue
|
||||
if filename.endswith(f'.obj'):
|
||||
res = oss_client.get_object_to_file(file.key, os.path.join(path, f'{pid}.obj'))
|
||||
last_modified = oss_client.get_object_meta(file.key).last_modified
|
||||
print(f'obj文件最后修改时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(last_modified))}')
|
||||
print(f'下载文件:{file.key},状态:{res.status}')
|
||||
break
|
||||
#查找obj
|
||||
def find_obj(pid, order_id):
|
||||
find = False
|
||||
if os.path.exists(os.path.join(sourceFilePath, f'{pid}_{order_id}', f'{pid}.obj')):
|
||||
|
||||
if not os.path.exists(os.path.join(workdir, f'{pid}_{order_id}', f'{pid}.obj')):
|
||||
#复制文件到 指定目录
|
||||
shutil.copytree(os.path.join(sourceFilePath, f'{pid}_{order_id}'), os.path.join(workdir,f'{pid}_{order_id}'))
|
||||
|
||||
# shutil.copy(f"/data/datasets/print/{pid}_{order_id}/{pid}.obj", os.path.join(workdir, f'{pid}_{order_id}', f'{pid}.obj'))
|
||||
# shutil.copy(f"/data/datasets/print/{pid}_{order_id}/{pid}.mtl", os.path.join(workdir, f'{pid}_{order_id}', f'{pid}.mtl'))
|
||||
# shutil.copy(f"/data/datasets/print/{pid}_{order_id}/{pid}.Tex1.jpg", os.path.join(workdir, f'{pid}_{order_id}', f'{pid}Tex1.jpg'))
|
||||
else:
|
||||
print('没有找到obj模型文件,开始下载')
|
||||
down_obj_fromoss(pid, order_id=order_id)
|
||||
if os.path.exists(os.path.join(workdir, f'{pid}_{order_id}', f'{pid}.jpg')):
|
||||
shutil.move(os.path.join(workdir, f'{pid}_{order_id}', f'{pid}.jpg'), os.path.join(workdir, f'{pid}_{order_id}', f'{pid}Tex1.jpg'))
|
||||
with open(os.path.join(workdir, f'{pid}_{order_id}', f'{pid}.mtl'), 'r') as f:
|
||||
lines = f.readlines()
|
||||
lines = [line.replace(f'map_Kd {pid}.jpg', f'map_Kd {pid}Tex1.jpg') for line in lines]
|
||||
with open(os.path.join(workdir, f'{pid}_{order_id}', f'{pid}.mtl'), 'w') as f:
|
||||
f.writelines(lines)
|
||||
filelist = os.listdir(os.path.join(workdir, f'{pid}_{order_id}'))
|
||||
for filename in filelist:
|
||||
if f'{pid}.obj' in filename:
|
||||
find = True
|
||||
#进行图片分辨率的调整
|
||||
# get_printsize_url = 'https://mp.api.suwa3d.com/api/printOrder/info'
|
||||
# res = requests.get(f'{get_printsize_url}?id={order_id}')
|
||||
# print('获取订单信息:', res.text)
|
||||
# if res.status_code == 200:
|
||||
# headcount = res.json()['data']['headcount']
|
||||
# for f in res.json()['data']['fileList']:
|
||||
# if "undefined" in f:
|
||||
# continue
|
||||
# try:
|
||||
# height = float(f.split('_')[-2][:-2]) * 10
|
||||
# except Exception as e:
|
||||
# continue
|
||||
|
||||
# if headcount == 1 and height <= 80:
|
||||
# pixs = 4096
|
||||
# if height <= 5:
|
||||
# pixs = 1024
|
||||
# print(f"图片分辨率进行处理{pixs}")
|
||||
# imagePiex(os.path.join(workdir, f'{pid}_{order_id}', f'{pid}Tex1.jpg'),pixs)
|
||||
|
||||
return filename
|
||||
print('没有找到obj模型文件')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return ''
|
||||
|
||||
def find_pid_objname(pid):
|
||||
for obj in bpy.data.objects:
|
||||
if obj.name.startswith(str(pid)):
|
||||
return obj.name
|
||||
|
||||
def ps_color_scale_adjustment(image, shadow=0, highlight=255, midtones=1):
|
||||
'''
|
||||
模拟 PS 的色阶调整; 0 <= Shadow < Highlight <= 255
|
||||
:param image: 传入的图片
|
||||
:param shadow: 黑场(0-Highlight)
|
||||
:param highlight: 白场(Shadow-255)
|
||||
:param midtones: 灰场(9.99-0.01)
|
||||
:return: 图片
|
||||
'''
|
||||
if highlight > 255:
|
||||
highlight = 255
|
||||
if shadow < 0:
|
||||
shadow = 0
|
||||
if shadow >= highlight:
|
||||
shadow = highlight - 2
|
||||
if midtones > 9.99:
|
||||
midtones = 9.99
|
||||
if midtones < 0.01:
|
||||
midtones = 0.01
|
||||
image = np.array(image, dtype=np.float16)
|
||||
# 计算白场 黑场离差
|
||||
Diff = highlight - shadow
|
||||
image = image - shadow
|
||||
image[image < 0] = 0
|
||||
image = (image / Diff) ** (1 / midtones) * 255
|
||||
image[image > 255] = 255
|
||||
image = np.array(image, dtype=np.uint8)
|
||||
|
||||
return image
|
||||
|
||||
|
||||
def show_histogram(image, image_id, save_hist_dir, min_threshold, max_threshold):
|
||||
'''
|
||||
画出直方图展示
|
||||
:param image: 导入图片
|
||||
:param image_id: 图片id编号
|
||||
:param save_hist_dir: 保存路径
|
||||
:param min_threshold: 最小阈值
|
||||
:param max_threshold: 最大阈值
|
||||
:return: 原图image,和裁剪原图直方图高低阈值后的图片image_change
|
||||
'''
|
||||
plt.rcParams['font.family'] = 'SimHei'
|
||||
plt.rcParams['axes.unicode_minus'] = False
|
||||
plt.hist(image.ravel(), 254, range=(2, 256), density=False)
|
||||
plt.hist(image.ravel(), 96, range=(2, 50), density=False) # 放大 range(0, 50),bins值最好是range的两倍,显得更稀疏,便于对比
|
||||
plt.hist(image.ravel(), 110, range=(200, 255), density=False) # 放大 range(225, 255)
|
||||
plt.annotate('thresh1=' + str(min_threshold), # 文本内容
|
||||
xy=(min_threshold, 0), # 箭头指向位置 # 阈值设定值!
|
||||
xytext=(min_threshold, 500000), # 文本位置 # 阈值设定值!
|
||||
arrowprops=dict(facecolor='black', width=1, shrink=5, headwidth=2)) # 箭头
|
||||
plt.annotate('thresh2=' + str(max_threshold), # 文本内容
|
||||
xy=(max_threshold, 0), # 箭头指向位置 # 阈值设定值!
|
||||
xytext=(max_threshold, 500000), # 文本位置 # 阈值设定值!
|
||||
arrowprops=dict(facecolor='black', width=1, shrink=5, headwidth=2)) # 箭头
|
||||
# 在y轴上绘制一条直线
|
||||
# plt.axhline(y=10000, color='r', linestyle='--', linewidth=0.5)
|
||||
plt.title(str(image_id))
|
||||
# plt.show()
|
||||
# 保存直方图
|
||||
save_hist_name = os.path.join(save_hist_dir, f'{image_id}_{min_threshold}&{max_threshold}.jpg')
|
||||
plt.savefig(save_hist_name)
|
||||
# 清空画布, 防止重叠展示
|
||||
plt.clf()
|
||||
|
||||
|
||||
def low_find_histogram_range(image, target_frequency):
|
||||
'''
|
||||
循环查找在 target_frequency (y)频次限制下的直方图区间值(x)
|
||||
:param image: 导入图片
|
||||
:param target_frequency: 直方图 y 频次限制条件
|
||||
:return: 直方图区间 x,和 该区间频次 y
|
||||
'''
|
||||
# 计算灰度直方图
|
||||
hist, bins = np.histogram(image, bins=256, range=[0, 256])
|
||||
# 初始化区间和频次
|
||||
interval = 2
|
||||
frequency = hist[255]
|
||||
while frequency < target_frequency:
|
||||
# 更新区间和频次
|
||||
interval += 1
|
||||
# 检查直方图的频次是否为None,如果频次是None,则将其设为0,这样可以避免将None和int进行比较报错。
|
||||
frequency = hist[interval] if hist[interval] is not None else 0
|
||||
frequency += hist[interval] if hist[interval] is not None else 0
|
||||
# 如果频次接近10000则停止循环
|
||||
if target_frequency - 2000 <= frequency <= target_frequency + 1000:
|
||||
break
|
||||
|
||||
return interval, frequency
|
||||
|
||||
|
||||
def high_find_histogram_range(image, target_frequency):
|
||||
'''
|
||||
循环查找在 target_frequency (y)频次限制下的直方图区间值(x)
|
||||
:param image: 导入图片
|
||||
:param target_frequency: 直方图 y 频次限制条件
|
||||
:return: 直方图区间 x,和 该区间频次 y
|
||||
'''
|
||||
# 计算灰度直方图
|
||||
hist, bins = np.histogram(image, bins=256, range=[0, 256])
|
||||
# 初始化区间和频次
|
||||
interval = 255
|
||||
frequency = hist[255]
|
||||
while frequency < target_frequency:
|
||||
# 更新区间和频次
|
||||
interval -= 1
|
||||
# 检查直方图的频次是否为None,如果频次是None,则将其设为0,这样可以避免将None和int进行比较报错。
|
||||
frequency = hist[interval] if hist[interval] is not None else 0
|
||||
frequency += hist[interval] if hist[interval] is not None else 0
|
||||
# 如果频次接近10000则停止循环
|
||||
if target_frequency - 2000 <= frequency <= target_frequency + 2000:
|
||||
break
|
||||
|
||||
return interval, frequency
|
||||
|
||||
def reduce_sharpness(image, factor):
|
||||
'''
|
||||
使用PIL库减弱图像锐度
|
||||
:param image: 图像
|
||||
:param factor: 锐度因子,0表示最大程度减弱锐度,1表示原始图像
|
||||
:return: 减弱锐度后的图像
|
||||
'''
|
||||
# OpenCV 格式的图像转换为 PIL 的 Image 对象
|
||||
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
||||
pil_image = Image.fromarray(image_rgb)
|
||||
enhancer = ImageEnhance.Sharpness(pil_image)
|
||||
reduced_image = enhancer.enhance(factor)
|
||||
# PIL 的 Image 对象转换为 OpenCV 的图像格式
|
||||
image_array = np.array(reduced_image)
|
||||
sharpened_image = cv2.cvtColor(image_array, cv2.COLOR_RGB2BGR)
|
||||
|
||||
return sharpened_image
|
||||
|
||||
def sharpening_filter(image):
|
||||
'''
|
||||
锐化滤波器对图片进行锐化,增强图像中的边缘和细节
|
||||
:param image: 导入图片
|
||||
:return: 锐化后的图片
|
||||
'''
|
||||
sharp_kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
|
||||
sharpened_image = cv2.filter2D(image, -1, sharp_kernel)
|
||||
return sharpened_image
|
||||
|
||||
def find_last_x(image, slope_threshold = 1000):
|
||||
x = []
|
||||
y = []
|
||||
hist, bins = np.histogram(image, bins=256, range=[0, 256])
|
||||
|
||||
#找到50以内的最高峰
|
||||
max_y = 0
|
||||
max_i = 5
|
||||
for i in range(5, 50):
|
||||
if hist[i] > max_y:
|
||||
max_y = hist[i]
|
||||
max_i = i
|
||||
print(f'50以内最高峰值y:{max_y},最高峰位置x:{max_i}')
|
||||
|
||||
for i in range(2, max_i):
|
||||
x.append(i)
|
||||
y.append(hist[i])
|
||||
slopes = [abs(y[i + 1] - y[i]) for i in range(len(x) - 1)]
|
||||
|
||||
current_interval = []
|
||||
max_interval = []
|
||||
max_x = {}
|
||||
for i, slope in enumerate(slopes):
|
||||
current_interval.append(slope)
|
||||
if slope >= slope_threshold:
|
||||
if len(current_interval) > len(max_interval):
|
||||
max_interval = current_interval.copy()
|
||||
max_x[x[i]] = slope
|
||||
current_interval = []
|
||||
|
||||
print(max_x)
|
||||
last_x = list(max_x)[-1]
|
||||
last_y = max_x[last_x]
|
||||
return last_x, last_y
|
||||
|
||||
def find_last_high(image, slope_threshold = 2500):
|
||||
x = []
|
||||
y = []
|
||||
hist, bins = np.histogram(image, bins=255, range=[2, 255])
|
||||
|
||||
#找到200以上的最高峰
|
||||
max_y = 0
|
||||
max_i = 254
|
||||
for i in range(220, 255):
|
||||
if hist[i] > max_y:
|
||||
max_y = hist[i]
|
||||
max_i = i
|
||||
print(f'200以上的最高峰值y:{max_y},最高峰位置x:{max_i}')
|
||||
|
||||
for i in range(max_i, 255):
|
||||
x.append(i)
|
||||
y.append(hist[i])
|
||||
slopes = [abs(y[i + 1] - y[i]) for i in range(len(x) - 1)]
|
||||
|
||||
current_interval = []
|
||||
max_interval = []
|
||||
max_x = {}
|
||||
find = False
|
||||
for i in range(len(slopes) - 1, -1, -1):
|
||||
slope = slopes[i]
|
||||
current_interval.append(slope)
|
||||
if slope >= slope_threshold:
|
||||
find = True
|
||||
if len(current_interval) > len(max_interval):
|
||||
max_interval = current_interval.copy()
|
||||
max_x[x[i]] = slope
|
||||
current_interval = []
|
||||
#如果没有找到200以上很平,而且高度小于5000,就按220位置削平
|
||||
if not find and hist[220] < 5000:
|
||||
max_x[220] = hist[220]
|
||||
|
||||
print(max_x)
|
||||
if len(max_x) > 0:
|
||||
last_x = list(max_x)[0]
|
||||
last_y = max_x[last_x]
|
||||
else:
|
||||
print(f'找不到200以上曲线较平的区间,使用254作为最高峰')
|
||||
last_x = 254
|
||||
last_y = hist[254]
|
||||
return last_x, last_y
|
||||
|
||||
def remove_gray_and_sharpening(jpg_path):
|
||||
input_image = cv2.imread(jpg_path)
|
||||
# low_x_thresh, low_y_frequency = low_find_histogram_range(input_image, low_y_limit)
|
||||
low_x_thresh, low_y_frequency = find_last_x(input_image)
|
||||
# high_x_thresh, high_y_frequency = high_find_histogram_range(input_image, high_y_limit)
|
||||
high_x_thresh, high_y_frequency = find_last_high(input_image)
|
||||
print(f"{low_x_thresh} 区间, {low_y_frequency} 频次")
|
||||
print(f"{high_x_thresh} 区间, {high_y_frequency} 频次")
|
||||
high_output_image = ps_color_scale_adjustment(input_image, shadow=low_x_thresh, highlight=high_x_thresh, midtones=1)
|
||||
# high_output_image = ps_color_scale_adjustment(low_ouput_image, shadow=0, highlight=high_x_thresh, midtones=1)
|
||||
|
||||
# # 人体贴图和黑色背景交界处不进行锐化
|
||||
# gray = cv2.cvtColor(input_image, cv2.COLOR_BGR2GRAY)
|
||||
# _, thresh = cv2.threshold(gray, 2, 255, cv2.THRESH_BINARY)
|
||||
# kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
|
||||
# gradient = cv2.morphologyEx(thresh, cv2.MORPH_GRADIENT, kernel)
|
||||
# roi_gradient = cv2.bitwise_and(high_output_image, high_output_image, mask=gradient)
|
||||
|
||||
# # 锐化滤波器
|
||||
# # sharpened_image = sharpening_filter(high_output_image)
|
||||
# sharpened_image = reduce_sharpness(high_output_image, factor=4)
|
||||
# # 将原图边界替换锐化后的图片边界
|
||||
# sharpened_image[gradient != 0] = roi_gradient[gradient != 0]
|
||||
|
||||
# 直方图标记并保存
|
||||
# show_histogram(input_image, img_id, low_x_thresh, high_x_thresh)
|
||||
cv2.imwrite(jpg_path, high_output_image, [cv2.IMWRITE_JPEG_QUALITY, 95]) # 保存图片的质量是原图的 95%
|
||||
|
||||
|
||||
#获取该笔订单的信息,判断是否存在,不存在就跳过
|
||||
def getInfoByPrintId(print_id):
|
||||
res = requests.get(f'{get_pid_by_printid_url}?print_id={print_id}')
|
||||
print('获取pid:', f'{get_pid_by_printid_url}?print_id={print_id}', res.text)
|
||||
resCode = json.loads(res.text)['code']
|
||||
#该笔订单的获取信息有误,可能信息还没有成功
|
||||
if int(resCode) != 1000:
|
||||
tempMesg = json.loads(res.text)['message']
|
||||
#判断是否包含 不存在
|
||||
if tempMesg == "打印订单不存在":
|
||||
print(f"打印ID{print_id}打印订单不存在,跳过")
|
||||
# res = requests.get(f'https://mp.api.suwa3d.com/api/footCode/deleteByPid?pid={pid}')
|
||||
#os.system(f'blender -b -P fill_dm_code.py')
|
||||
return False
|
||||
|
||||
print("获取打印任务信息有问题,重新任务队列,打印id-",print_id,"重新执行脚底板任务,等待20s")
|
||||
time.sleep(20)
|
||||
#将pid 重新扔进队列
|
||||
r.lpush("model:foot", print_id)
|
||||
return False
|
||||
return res.text
|
||||
|
||||
#获取订单的坐标信息,判断是否有,没有的话就重新生成坐标信息
|
||||
def getQrPosition(print_id,pid,order_id):
|
||||
#从云端获取qr_position,如果获取为空,调用cal_foot_position.py计算并上传qr_position,再重新读取qr_position.txt
|
||||
res = requests.get(f'{get_qr_position_url}?print_id={print_id}')
|
||||
print('从云端获取的qr_position1:', res.text)
|
||||
codeTemp = json.loads(res.text)['code']
|
||||
if str(codeTemp) == "-1":
|
||||
print(f"获取打印ID{print_id}的脚底板坐标失败,进行下一笔订单的处理")
|
||||
return False
|
||||
qr_position = json.loads(res.text)['data']['position_data']
|
||||
if qr_position == '':
|
||||
print(f"pid={pid},打印id={print_id} order_id={order_id},云端获取的坐标数据为空,进行重新计算")
|
||||
time.sleep(3)
|
||||
print('qr_position为空,调用cal_foot_position.py计算并上传qr_position')
|
||||
os.system(f'blender -b -P cal_foot_position.py -- {pid}_{order_id}_{print_id}')
|
||||
print("延时20s,等待计算脚底板坐标")
|
||||
time.sleep(20)
|
||||
res = requests.get(f'{get_qr_position_url}?print_id={print_id}')
|
||||
print(f"pid={pid},打印id={print_id} order_id={order_id},重新获取qr_position",res.text)
|
||||
print('从云端获取的qr_position3:', res.text)
|
||||
if str(json.loads(res.text)['code']) == "-1":
|
||||
print(f"pid={pid},打印id={print_id} order_id={order_id},重新获取qr_position 失败",res.text)
|
||||
return False
|
||||
qr_position = json.loads(res.text)['data']['position_data']
|
||||
if qr_position == '':
|
||||
#跳过该笔订单
|
||||
print(f"pid={pid},打印id={print_id} order_id={order_id},重新获取qr_position 为空,跳过脚底板的处理,执行下一笔任务")
|
||||
#移除该脚底板的面积处理
|
||||
res = requests.get(f'https://mp.api.suwa3d.com/api/footCode/deleteByPid?pid={pid}')
|
||||
return False
|
||||
else:
|
||||
qr_position = json.loads(qr_position)
|
||||
|
||||
if qr_position == "":
|
||||
print("获取脚底坐标数据为空,重新任务队列,打印id-",print_id,"重新执行脚底板任务")
|
||||
#将pid 重新扔进队列
|
||||
r.lpush("model:foot", print_id)
|
||||
return False
|
||||
|
||||
return qr_position
|
||||
|
||||
def main(workdir, r, print_id):
|
||||
|
||||
resText = getInfoByPrintId(print_id)
|
||||
print(f"根据打印ID{print_id}获取订单信息-内容{resText}")
|
||||
if resText == False:
|
||||
print(f"根据打印ID{print_id}获取订单信息失败")
|
||||
return
|
||||
arrResText = json.loads(resText)
|
||||
#订单的相关信息
|
||||
use_foot_type = arrResText['data']['use_foot_type'] #构建类型
|
||||
pid = arrResText['data']['pid'] #pid
|
||||
order_id = arrResText['data']['order_id'] # order_id
|
||||
|
||||
#文件路劲
|
||||
tempName = find_obj(pid, order_id)
|
||||
print("tempName",tempName)
|
||||
filename = os.path.join(workdir, f'{pid}_{order_id}', tempName)
|
||||
print('导入obj文件:', filename)
|
||||
|
||||
#获取该笔订单的坐标
|
||||
qr_position = getQrPosition(print_id,pid,order_id)
|
||||
if qr_position == False:
|
||||
return
|
||||
|
||||
if type(qr_position) == str: qr_position = json.loads(qr_position)
|
||||
print(f'type of qr_position:{type(qr_position)}')
|
||||
print(f'qr_position:{qr_position}')
|
||||
|
||||
qr_position['location'][2] = -0.1
|
||||
|
||||
temp_foot_data = print_id
|
||||
# 根据print_id生成qr码
|
||||
qr_path = os.path.join(workdir, f'{pid}_{order_id}' ,'qr.png')
|
||||
# if use_foot_type == "short_url":
|
||||
# #调用接口获取短网址信息
|
||||
# short_url = get_short_url(print_id)
|
||||
# if short_url == False:
|
||||
# return
|
||||
# temp_foot_data = short_url
|
||||
# print(f'temp_foot_data---{temp_foot_data}')
|
||||
gen_data_matrix(print_id,pid, qr_path)
|
||||
#休眠1秒
|
||||
time.sleep(2)
|
||||
#判断是否存在 qr_path,不存在就执行下一个任务
|
||||
if not os.path.exists(qr_path):
|
||||
#移除该脚底板的面积处理
|
||||
print(f"pid={pid},打印id={print_id} order_id={order_id},生成的二维码为空,跳过脚底板的处理,执行下一笔任务")
|
||||
res = requests.get(f'https://mp.api.suwa3d.com/api/footCode/deleteByPid?pid={pid}')
|
||||
#os.system(f'blender -b -P fill_dm_code.py')
|
||||
return
|
||||
|
||||
#在blender中贴上脚底板二维码的信息
|
||||
|
||||
# 导入obj文件,重置到标准单位
|
||||
bpy.ops.wm.read_homefile()
|
||||
bpy.context.preferences.view.language = 'en_US'
|
||||
bpy.ops.object.delete(use_global=False, confirm=False)
|
||||
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'
|
||||
|
||||
bpy.ops.import_scene.obj(filepath=filename)
|
||||
#bpy.ops.wm.obj_import(filepath=filename)
|
||||
obj = bpy.context.selected_objects[0]
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
obj.select_set(True)
|
||||
|
||||
pid_objname = find_pid_objname(pid)
|
||||
|
||||
scale = 90 / obj.dimensions.y
|
||||
obj.scale = (scale, scale, scale)
|
||||
bpy.ops.object.align(align_mode='OPT_1', relative_to='OPT_1', align_axis={'Z'})
|
||||
bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS', center='MEDIAN')
|
||||
obj.location[0] = 0
|
||||
obj.location[1] = 0
|
||||
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
|
||||
|
||||
print(f'qr_position:{qr_position}')
|
||||
print(f'qr_position_type:{type(qr_position)}')
|
||||
|
||||
# 根据qr_position的值,恢复qr的位置和尺寸,重新生成贴图
|
||||
bpy.ops.object.load_reference_image(filepath=os.path.join(workdir, f'{pid}_{order_id}', 'qr.png'))
|
||||
bpy.context.object.rotation_euler = (math.radians(-180), math.radians(0), qr_position['rotation'])
|
||||
bpy.ops.transform.translate(value=qr_position['location'], orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False, snap=False, snap_elements={'INCREMENT'}, use_snap_project=False, snap_target='CLOSEST', use_snap_self=True, use_snap_edit=True, use_snap_nonedit=True, use_snap_selectable=False, release_confirm=True)
|
||||
|
||||
bpy.context.object.empty_display_size = qr_position['dimensions'][0]
|
||||
|
||||
qr_path = os.path.join(workdir,f'{pid}_{order_id}', f"{pid}_{order_id}Tex1_qr.png")
|
||||
jpg_path = os.path.join(workdir,f'{pid}_{order_id}', f"{pid}Tex1.jpg")
|
||||
#判断是否存在 jpg_path,不存在就执行下一个任务
|
||||
if not os.path.exists(jpg_path):
|
||||
#移除该脚底板的面积处理
|
||||
res = requests.get(f'https://mp.api.suwa3d.com/api/footCode/deleteByPid?pid={pid}')
|
||||
#os.system(f'blender -b -P fill_dm_code.py')
|
||||
bpy.ops.wm.quit_blender()
|
||||
return
|
||||
|
||||
jpg_img = Image.open(jpg_path)
|
||||
shutil.copyfile(jpg_path, os.path.join(workdir,f'{pid}_{order_id}', f"{pid}Tex1_noqr.jpg"))
|
||||
|
||||
bpy.context.scene.eyek.res_x = jpg_img.width
|
||||
bpy.context.scene.eyek.res_y = jpg_img.height
|
||||
bpy.context.scene.eyek.path_export_image = qr_path
|
||||
bpy.data.objects[pid_objname].select_set(True)
|
||||
bpy.data.objects['Empty'].select_set(True)
|
||||
bpy.context.view_layer.objects.active = bpy.data.objects[pid_objname]
|
||||
bpy.ops.eyek.exe()
|
||||
|
||||
#判断qr_path是否存在,不存在就执行下一个任务
|
||||
if not os.path.exists(qr_path):
|
||||
#移除该脚底板的面积处理
|
||||
res = requests.get(f'https://mp.api.suwa3d.com/api/footCode/deleteByPid?pid={pid}')
|
||||
#os.system(f'blender -b -P fill_dm_code.py')
|
||||
bpy.ops.wm.quit_blender()
|
||||
return
|
||||
|
||||
qr_img = Image.open(qr_path)
|
||||
jpg_img.paste(qr_img, (0, 0), qr_img)
|
||||
jpg_img.save(jpg_path, quality=90)
|
||||
shutil.copyfile(jpg_path, os.path.join(workdir,f'{pid}_{order_id}', f"{pid}Tex1_qr.jpg"))
|
||||
|
||||
# 加入去灰、锐化
|
||||
remove_gray_and_sharpening(jpg_path)
|
||||
|
||||
shutil.copyfile(jpg_path, os.path.join(workdir,f'{pid}_{order_id}', f"{pid}Tex1_qr.jpg"))
|
||||
|
||||
#上传脚底板文件 -》 修改为移动脚底板文件
|
||||
upload_jpg_mtl(pid, order_id, print_id)
|
||||
|
||||
# plt.axis('equal')
|
||||
# plt.show()
|
||||
|
||||
# 保存blend文件
|
||||
# bpy.ops.wm.save_as_mainfile(filepath=f'{workdir}{pid}_{order_id}/{pid}_qr_end.blend')
|
||||
bpy.ops.wm.quit_blender()
|
||||
|
||||
# 删除临时文件
|
||||
print("workdirworkdir",workdir)
|
||||
shutil.rmtree(os.path.join(workdir, f'{pid}_{order_id}'))
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 运行{print_id}任务完成,继续运行下一个任务')
|
||||
# restart_current_process("blender -b -P fill_dm_code.py")
|
||||
|
||||
def imagePiex(filePath,piex):
|
||||
# 打开图片
|
||||
image = Image.open(filePath)
|
||||
# 设置新的最大宽度和高度
|
||||
max_size = (piex, piex)
|
||||
# 保持宽高比缩放图片
|
||||
image.thumbnail(max_size)
|
||||
# 保存调整后的图片
|
||||
image.save(filePath)
|
||||
|
||||
#根据print_id 获取 短网址
|
||||
def get_short_url(print_id):
|
||||
res = requests.get(f'{get_short_url_by_print_id}?print_id={print_id}')
|
||||
resCode = json.loads(res.text)['code']
|
||||
#该笔订单的获取信息有误,可能信息还没有成功
|
||||
if int(resCode) != 1000:
|
||||
print("获取短网址信息失败,延时1分钟,重新扔入脚底板队列,打印id-",print_id,"重新执行脚底板任务")
|
||||
time.sleep(60)
|
||||
#将pid 重新扔进队列
|
||||
r.lpush("model:foot", print_id)
|
||||
#重新调用脚底板程序
|
||||
return False
|
||||
return json.loads(res.text)['data']
|
||||
|
||||
|
||||
@retry(stop_max_attempt_number=10, wait_fixed=2000)
|
||||
def upload_jpg_mtl(pid, order_id, print_id):
|
||||
try:
|
||||
print("移动脚底板文件")
|
||||
#判断文件夹是否存在,不存在则创建
|
||||
if not os.path.exists(os.path.join(f'{resFilePath}/{pid}/foot_print_id_{print_id}/')):
|
||||
os.makedirs(os.path.join(f'{resFilePath}/{pid}/foot_print_id_{print_id}/'),mode=0o777, exist_ok=True)
|
||||
else:
|
||||
#移除路径下的文件
|
||||
if os.path.exists(os.path.join(f'{resFilePath}/{pid}/foot_print_id_{print_id}/{pid}Tex1.jpg')):
|
||||
os.remove(os.path.join(f'{resFilePath}/{pid}/foot_print_id_{print_id}/{pid}Tex1.jpg'))
|
||||
print(f"文件 '{pid}' 已成功删除。")
|
||||
|
||||
shutil.move(os.path.join(workdir,f'{pid}_{order_id}', f"{pid}Tex1.jpg"),os.path.join(f'{resFilePath}/{pid}/foot_print_id_{print_id}/'))
|
||||
|
||||
|
||||
#print('生成贴图完成,开始上传...')
|
||||
# oss_client.put_object_from_file(f'objs/print/{pid}/{pid}Tex1.{print_id}.jpg', os.path.join(workdir,f'{pid}_{order_id}', f"{pid}Tex1.jpg"))
|
||||
# oss_client.put_object_from_file(f'objs/print/{pid}/{pid}.mtl', os.path.join(workdir,f'{pid}_{order_id}', f"{pid}.mtl"))
|
||||
# # oss_client.put_object_from_file(f'objs/print/{pid}/{pid}Tex1_noqr.jpg', os.path.join(workdir,f'{pid}_{order_id}', f"{pid}Tex1_noqr.jpg"))
|
||||
|
||||
print('更新状态为已生成脚底板二维码')
|
||||
res = requests.post(f'{upload_qr_position_url}?print_id={print_id}')
|
||||
# #记录日志
|
||||
# logging.error(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}-结果:pid:{pid}-print_id:{print_id} {str(res.text)}")
|
||||
print('更新返回状态:', f'{upload_qr_position_url}?print_id={print_id}', res.text)
|
||||
|
||||
except Exception as e:
|
||||
|
||||
print("迁移文件出 yichang ")
|
||||
|
||||
|
||||
def worker(workdir, r, print_id):
|
||||
"""每个子进程的工作函数,用于处理单个 print_id。"""
|
||||
try:
|
||||
main(workdir, r, print_id)
|
||||
except Exception as e:
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f"处理 print_id {print_id} 时出错: {e}")
|
||||
|
||||
def process_print_ids(workdir, r, pool_size):
|
||||
"""监控 Redis 队列并并行处理 print_id,同时控制进程池的大小。"""
|
||||
# 创建进程池
|
||||
pool = multiprocessing.Pool(processes=pool_size)
|
||||
|
||||
while True:
|
||||
try:
|
||||
# 如果队列为空,等待10秒后重试
|
||||
if r.llen('model:foot') == 0:
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), '队列为空,10秒后重试')
|
||||
time.sleep(10)
|
||||
continue
|
||||
|
||||
# 从队列中取出一个 print_id
|
||||
print_id = r.lpop('model:foot')
|
||||
if print_id is None:
|
||||
continue
|
||||
|
||||
# 判断该 print_id 是否已经存在,避免重复处理
|
||||
isHaveAlready = 0
|
||||
for i in r.lrange('model:foot', 0, -1):
|
||||
if i == print_id:
|
||||
isHaveAlready = 1
|
||||
break
|
||||
if isHaveAlready == 1:
|
||||
continue
|
||||
|
||||
# 如果 print_id 是唯一的,则将任务提交给进程池处理
|
||||
print(f"正在处理 print_id: {print_id}")
|
||||
pool.apply_async(worker, args=(workdir, r, print_id)) # 使用 apply_async 异步执行任务
|
||||
|
||||
except Exception as e:
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f"出现异常错误: {e}")
|
||||
r = create_redis_connection()
|
||||
continue
|
||||
|
||||
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)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
atexit.register(common.notify,"打印工厂-本地虚拟木脚底板处理程序已停止一个")
|
||||
low_y_limit = 25000
|
||||
high_y_limit = 13000
|
||||
|
||||
get_qr_position_url = 'https://mp.api.suwa3d.com/api/printOrder/getFootCodePositionData'
|
||||
upload_qr_position_url = 'https://mp.api.suwa3d.com/api/printOrder/updateFootCodeStatus'
|
||||
get_pid_by_printid_url = 'https://mp.api.suwa3d.com/api/printOrder/getPidByPrintId'
|
||||
get_short_url_by_print_id = 'https://mp.api.suwa3d.com/api/footCode/qrcode'
|
||||
# get_qr_position_url = 'http://172.31.1.254:8199/api/printOrder/getFootCodePositionData'
|
||||
# upload_qr_position_url = 'http://172.31.1.254:8199/api/printOrder/updateFootCodeStatus'
|
||||
# get_pid_by_printid_url = 'http://172.31.1.254:8199/api/printOrder/getPidByPrintId'
|
||||
|
||||
|
||||
r = redis.Redis(host='106.14.158.208', password='kcV2000', port=6379, db=6)
|
||||
# r = redis.Redis(host='172.31.1.254', password='', port=6379, db=6)
|
||||
AccessKeyId = 'LTAI5tSReWm8hz7dSYxxth8f'
|
||||
AccessKeySecret = '8ywTDF9upPAtvgXtLKALY2iMYHIxdS'
|
||||
Endpoint = 'oss-cn-shanghai.aliyuncs.com'
|
||||
Bucket = 'suwa3d-securedata'
|
||||
oss_client = oss2.Bucket(oss2.Auth(AccessKeyId, AccessKeySecret), Endpoint, Bucket)
|
||||
|
||||
if platform.system() == 'Windows':
|
||||
workdir = 'E:\\print\\foot\\'
|
||||
else:
|
||||
workdir = '/data/datasets/foot/'
|
||||
|
||||
#构建好的obj文件目录
|
||||
sourceFilePath = '/data/datasets/print'
|
||||
#脚底板最终保存的路径
|
||||
resFilePath = '/data/datasets/complate/objs'
|
||||
print("Usage: blender -b -P fill_dm_code.py")
|
||||
|
||||
# # 控制进程池的大小
|
||||
# pool_size = 2 # 设置最大并发进程数为4(根据需求调整)
|
||||
|
||||
# # 创建一个进程池
|
||||
# pool = multiprocessing.Pool(processes=pool_size)
|
||||
|
||||
# # 如果传递了参数,则处理特定的 print_ids
|
||||
# if len(sys.argv) == 5:
|
||||
# print_ids = sys.argv[-1]
|
||||
# for print_id in print_ids.split(','):
|
||||
# main(workdir, r, print_id)
|
||||
# else:
|
||||
# # 启动进程池,监控队列并并行处理 print_id
|
||||
# process_print_ids(workdir, r, pool_size)
|
||||
|
||||
if len(sys.argv) == 5:
|
||||
print_ids = sys.argv[-1]
|
||||
for print_id in print_ids.split(','):
|
||||
main(workdir, r, print_id)
|
||||
else:
|
||||
while True:
|
||||
try:
|
||||
#判断队列是否为空
|
||||
if r.llen('model:foot') == 0:
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), '队列为空,10秒后重试')
|
||||
time.sleep(10)
|
||||
continue
|
||||
#不为空,取出队列的第一个值
|
||||
print_id = r.lpop('model:foot')
|
||||
if print_id is None:
|
||||
continue
|
||||
#判断是否存在相同的值
|
||||
isHaveAlready = 0
|
||||
for i in r.lrange('model:foot', 0, -1):
|
||||
if i == print_id:
|
||||
isHaveAlready = 1
|
||||
break
|
||||
if isHaveAlready == 1:
|
||||
continue
|
||||
print_id = print_id.decode('utf-8')
|
||||
#获取队列的长度
|
||||
lengthQueue = r.llen('model:foot')
|
||||
print(f"正在处理 print_id: {print_id}, 队列长度: {lengthQueue}")
|
||||
|
||||
#如果是唯一值, 则调用main函数
|
||||
main(workdir, r, print_id)
|
||||
except Exception as e:
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), '出现异常错误,5秒后重试',e)
|
||||
r = create_redis_connection()
|
||||
continue
|
||||
|
||||
@@ -0,0 +1,847 @@
|
||||
import os, sys, bpy, math, time, platform, cairosvg, ppf.datamatrix, shutil, requests, json, redis, oss2, cv2,qrcode
|
||||
from retrying import retry
|
||||
import subprocess
|
||||
import multiprocessing
|
||||
import random
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from PIL import Image, ImageEnhance
|
||||
from addon_utils import enable
|
||||
import logging,atexit,platform
|
||||
# if platform.system() == 'Windows':
|
||||
sys.path.append('/home/acprint/code/libs/')
|
||||
import common
|
||||
logging.basicConfig(filename='foot_update_res.log', level=logging.ERROR)
|
||||
enable('io_import_images_as_planes')
|
||||
enable('eyek_addon')
|
||||
|
||||
|
||||
#查询影棚ID
|
||||
def getPSid(pid):
|
||||
res = requests.get("https://mp.gray.api.suwa3d.com/api/customerP3dLog/photoStudio",params={"pid":pid})
|
||||
res = json.loads(res.text)
|
||||
return str(res['data'])
|
||||
|
||||
|
||||
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 gen_data_matrix(print_id,pid, qr_path, size = 300):
|
||||
psid = getPSid(pid)
|
||||
if int(psid) == 0:
|
||||
print("费工夫构建脚底二维码")
|
||||
# if use_foot_type == "short_url":
|
||||
#调用接口获取短网址信息
|
||||
short_url = get_short_url(print_id)
|
||||
if short_url == False:
|
||||
return
|
||||
temp_foot_data = short_url
|
||||
|
||||
#生成二维码
|
||||
qr = qrcode.QRCode(
|
||||
version=1,
|
||||
error_correction = qrcode.constants.ERROR_CORRECT_L,
|
||||
box_size=10,
|
||||
border=2,
|
||||
)
|
||||
qr.add_data(temp_foot_data)
|
||||
qr.make(fit=True)
|
||||
img = qr.make_image(fill_color="black",back_color="white").resize((size,size))
|
||||
img.save(qr_path)
|
||||
else:
|
||||
#正常生成不是常规的二维码
|
||||
print("排除费工夫正常构建二维码")
|
||||
svg = ppf.datamatrix.DataMatrix(f'p{print_id}').svg()
|
||||
cairosvg.svg2png(bytestring=svg, write_to=qr_path, output_width=size, output_height=size, background_color='white')
|
||||
|
||||
def active_object(obj):
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
obj.select_set(True)
|
||||
#下载oss的文件
|
||||
@retry(stop_max_attempt_number=10, wait_fixed=2000)
|
||||
def down_obj_fromoss(pid, print_type=1, order_id=None):
|
||||
# print_type:// 打印状态 1:正常打印 2:重打 3:加打,4: 样品
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 开始下载模型,若网络异常将每间隔2秒重试10次...')
|
||||
if not order_id is None:
|
||||
path = os.path.join(workdir, f'{pid}_{order_id}')
|
||||
else:
|
||||
path = os.path.join(workdir, pid)
|
||||
if os.path.exists(path):
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 已存在模型文件,删除后重新下载')
|
||||
shutil.rmtree(path, ignore_errors=True)
|
||||
os.makedirs(path)
|
||||
|
||||
prefix = f'objs/print/{pid}/'
|
||||
#根据order_id 获取文件在 oss 上的存储路径
|
||||
if order_id is not None:
|
||||
tempURL = "https://mp.gray.api.suwa3d.com/api/order/getOssSuffixByOrderId?orderId="+str(order_id)
|
||||
res = requests.get(tempURL)
|
||||
resCode = res.json()['code']
|
||||
if int(resCode) != 1000:
|
||||
return -1
|
||||
print(res.text)
|
||||
if res.json()['data'] != "":
|
||||
prefix = f'objs/print/{pid}/{res.json()["data"]}/{str(order_id)}/'
|
||||
|
||||
# 下载分2种情况,一种是第一次打印,下载标准{pid}.obj,{pid}.mtl,{pid}Tex1.jpg,另一种是重打或加打,obj文件名可以从oss上任意获取一个,但是mtl和jpg文件名是固定的
|
||||
res = oss_client.get_object_to_file(f'{prefix}/{pid}.mtl', os.path.join(path, f'{pid}.mtl'))
|
||||
last_modified = oss_client.get_object_meta(f"{prefix}/{pid}.mtl").last_modified
|
||||
print(f'mtl文件最后修改时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(last_modified))}')
|
||||
print(f'下载文件:{prefix}/{pid}.mtl,状态:{res.status}')
|
||||
if oss_client.object_exists(f'{prefix}/{pid}Tex1.jpg'):
|
||||
res = oss_client.get_object_to_file(f'{prefix}/{pid}Tex1.jpg', os.path.join(path, f'{pid}Tex1.jpg'))
|
||||
last_modified = oss_client.get_object_meta(f"{prefix}/{pid}Tex1.jpg").last_modified
|
||||
print(f'jpg文件最后修改时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(last_modified))}')
|
||||
print(f'下载文件:{prefix}/{pid}Tex1.jpg,状态:{res.status}')
|
||||
else:
|
||||
res = oss_client.get_object_to_file(f'{prefix}/{pid}.jpg', os.path.join(path, f'{pid}Tex1.jpg'))
|
||||
last_modified = oss_client.get_object_meta(f"{prefix}/{pid}.jpg").last_modified
|
||||
print(f'jpg文件最后修改时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(last_modified))}')
|
||||
print(f'下载文件:{prefix}/{pid}.jpg,状态:{res.status}')
|
||||
if oss_client.object_exists(f'{prefix}/{pid}.obj'):
|
||||
res = oss_client.get_object_to_file(f'{prefix}/{pid}.obj', os.path.join(path, f'{pid}.obj'))
|
||||
last_modified = oss_client.get_object_meta(f"{prefix}/{pid}.obj").last_modified
|
||||
print(f'obj文件最后修改时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(last_modified))}')
|
||||
print(f'下载文件:{prefix}/{pid}.obj,状态:{res.status}')
|
||||
else:
|
||||
prefix = f'{prefix}'
|
||||
filelist = oss2.ObjectIteratorV2(oss_client, prefix=prefix)
|
||||
for file in filelist:
|
||||
filename = file.key.split('/')[-1]
|
||||
if filename == '': continue
|
||||
if filename.endswith(f'.obj'):
|
||||
res = oss_client.get_object_to_file(file.key, os.path.join(path, f'{pid}.obj'))
|
||||
last_modified = oss_client.get_object_meta(file.key).last_modified
|
||||
print(f'obj文件最后修改时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(last_modified))}')
|
||||
print(f'下载文件:{file.key},状态:{res.status}')
|
||||
break
|
||||
#查找obj
|
||||
def find_obj(pid, order_id):
|
||||
find = False
|
||||
if os.path.exists(os.path.join(sourceFilePath, f'{pid}_{order_id}', f'{pid}.obj')):
|
||||
|
||||
if not os.path.exists(os.path.join(workdir, f'{pid}_{order_id}', f'{pid}.obj')):
|
||||
#复制文件到 指定目录
|
||||
shutil.copytree(os.path.join(sourceFilePath, f'{pid}_{order_id}'), os.path.join(workdir,f'{pid}_{order_id}'))
|
||||
|
||||
# shutil.copy(f"/data/datasets/print/{pid}_{order_id}/{pid}.obj", os.path.join(workdir, f'{pid}_{order_id}', f'{pid}.obj'))
|
||||
# shutil.copy(f"/data/datasets/print/{pid}_{order_id}/{pid}.mtl", os.path.join(workdir, f'{pid}_{order_id}', f'{pid}.mtl'))
|
||||
# shutil.copy(f"/data/datasets/print/{pid}_{order_id}/{pid}.Tex1.jpg", os.path.join(workdir, f'{pid}_{order_id}', f'{pid}Tex1.jpg'))
|
||||
else:
|
||||
print('没有找到obj模型文件,开始下载')
|
||||
down_obj_fromoss(pid, order_id=order_id)
|
||||
if os.path.exists(os.path.join(workdir, f'{pid}_{order_id}', f'{pid}.jpg')):
|
||||
shutil.move(os.path.join(workdir, f'{pid}_{order_id}', f'{pid}.jpg'), os.path.join(workdir, f'{pid}_{order_id}', f'{pid}Tex1.jpg'))
|
||||
with open(os.path.join(workdir, f'{pid}_{order_id}', f'{pid}.mtl'), 'r') as f:
|
||||
lines = f.readlines()
|
||||
lines = [line.replace(f'map_Kd {pid}.jpg', f'map_Kd {pid}Tex1.jpg') for line in lines]
|
||||
with open(os.path.join(workdir, f'{pid}_{order_id}', f'{pid}.mtl'), 'w') as f:
|
||||
f.writelines(lines)
|
||||
filelist = os.listdir(os.path.join(workdir, f'{pid}_{order_id}'))
|
||||
for filename in filelist:
|
||||
if f'{pid}.obj' in filename:
|
||||
find = True
|
||||
#进行图片分辨率的调整
|
||||
# get_printsize_url = 'https://mp.gray.api.suwa3d.com/api/printOrder/info'
|
||||
# res = requests.get(f'{get_printsize_url}?id={order_id}')
|
||||
# print('获取订单信息:', res.text)
|
||||
# if res.status_code == 200:
|
||||
# headcount = res.json()['data']['headcount']
|
||||
# for f in res.json()['data']['fileList']:
|
||||
# if "undefined" in f:
|
||||
# continue
|
||||
# try:
|
||||
# height = float(f.split('_')[-2][:-2]) * 10
|
||||
# except Exception as e:
|
||||
# continue
|
||||
|
||||
# if headcount == 1 and height <= 80:
|
||||
# pixs = 4096
|
||||
# if height <= 5:
|
||||
# pixs = 1024
|
||||
# print(f"图片分辨率进行处理{pixs}")
|
||||
# imagePiex(os.path.join(workdir, f'{pid}_{order_id}', f'{pid}Tex1.jpg'),pixs)
|
||||
|
||||
return filename
|
||||
print('没有找到obj模型文件')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return ''
|
||||
|
||||
def find_pid_objname(pid):
|
||||
for obj in bpy.data.objects:
|
||||
if obj.name.startswith(str(pid)):
|
||||
return obj.name
|
||||
|
||||
def ps_color_scale_adjustment(image, shadow=0, highlight=255, midtones=1):
|
||||
'''
|
||||
模拟 PS 的色阶调整; 0 <= Shadow < Highlight <= 255
|
||||
:param image: 传入的图片
|
||||
:param shadow: 黑场(0-Highlight)
|
||||
:param highlight: 白场(Shadow-255)
|
||||
:param midtones: 灰场(9.99-0.01)
|
||||
:return: 图片
|
||||
'''
|
||||
if highlight > 255:
|
||||
highlight = 255
|
||||
if shadow < 0:
|
||||
shadow = 0
|
||||
if shadow >= highlight:
|
||||
shadow = highlight - 2
|
||||
if midtones > 9.99:
|
||||
midtones = 9.99
|
||||
if midtones < 0.01:
|
||||
midtones = 0.01
|
||||
image = np.array(image, dtype=np.float16)
|
||||
# 计算白场 黑场离差
|
||||
Diff = highlight - shadow
|
||||
image = image - shadow
|
||||
image[image < 0] = 0
|
||||
image = (image / Diff) ** (1 / midtones) * 255
|
||||
image[image > 255] = 255
|
||||
image = np.array(image, dtype=np.uint8)
|
||||
|
||||
return image
|
||||
|
||||
|
||||
def show_histogram(image, image_id, save_hist_dir, min_threshold, max_threshold):
|
||||
'''
|
||||
画出直方图展示
|
||||
:param image: 导入图片
|
||||
:param image_id: 图片id编号
|
||||
:param save_hist_dir: 保存路径
|
||||
:param min_threshold: 最小阈值
|
||||
:param max_threshold: 最大阈值
|
||||
:return: 原图image,和裁剪原图直方图高低阈值后的图片image_change
|
||||
'''
|
||||
plt.rcParams['font.family'] = 'SimHei'
|
||||
plt.rcParams['axes.unicode_minus'] = False
|
||||
plt.hist(image.ravel(), 254, range=(2, 256), density=False)
|
||||
plt.hist(image.ravel(), 96, range=(2, 50), density=False) # 放大 range(0, 50),bins值最好是range的两倍,显得更稀疏,便于对比
|
||||
plt.hist(image.ravel(), 110, range=(200, 255), density=False) # 放大 range(225, 255)
|
||||
plt.annotate('thresh1=' + str(min_threshold), # 文本内容
|
||||
xy=(min_threshold, 0), # 箭头指向位置 # 阈值设定值!
|
||||
xytext=(min_threshold, 500000), # 文本位置 # 阈值设定值!
|
||||
arrowprops=dict(facecolor='black', width=1, shrink=5, headwidth=2)) # 箭头
|
||||
plt.annotate('thresh2=' + str(max_threshold), # 文本内容
|
||||
xy=(max_threshold, 0), # 箭头指向位置 # 阈值设定值!
|
||||
xytext=(max_threshold, 500000), # 文本位置 # 阈值设定值!
|
||||
arrowprops=dict(facecolor='black', width=1, shrink=5, headwidth=2)) # 箭头
|
||||
# 在y轴上绘制一条直线
|
||||
# plt.axhline(y=10000, color='r', linestyle='--', linewidth=0.5)
|
||||
plt.title(str(image_id))
|
||||
# plt.show()
|
||||
# 保存直方图
|
||||
save_hist_name = os.path.join(save_hist_dir, f'{image_id}_{min_threshold}&{max_threshold}.jpg')
|
||||
plt.savefig(save_hist_name)
|
||||
# 清空画布, 防止重叠展示
|
||||
plt.clf()
|
||||
|
||||
|
||||
def low_find_histogram_range(image, target_frequency):
|
||||
'''
|
||||
循环查找在 target_frequency (y)频次限制下的直方图区间值(x)
|
||||
:param image: 导入图片
|
||||
:param target_frequency: 直方图 y 频次限制条件
|
||||
:return: 直方图区间 x,和 该区间频次 y
|
||||
'''
|
||||
# 计算灰度直方图
|
||||
hist, bins = np.histogram(image, bins=256, range=[0, 256])
|
||||
# 初始化区间和频次
|
||||
interval = 2
|
||||
frequency = hist[255]
|
||||
while frequency < target_frequency:
|
||||
# 更新区间和频次
|
||||
interval += 1
|
||||
# 检查直方图的频次是否为None,如果频次是None,则将其设为0,这样可以避免将None和int进行比较报错。
|
||||
frequency = hist[interval] if hist[interval] is not None else 0
|
||||
frequency += hist[interval] if hist[interval] is not None else 0
|
||||
# 如果频次接近10000则停止循环
|
||||
if target_frequency - 2000 <= frequency <= target_frequency + 1000:
|
||||
break
|
||||
|
||||
return interval, frequency
|
||||
|
||||
|
||||
def high_find_histogram_range(image, target_frequency):
|
||||
'''
|
||||
循环查找在 target_frequency (y)频次限制下的直方图区间值(x)
|
||||
:param image: 导入图片
|
||||
:param target_frequency: 直方图 y 频次限制条件
|
||||
:return: 直方图区间 x,和 该区间频次 y
|
||||
'''
|
||||
# 计算灰度直方图
|
||||
hist, bins = np.histogram(image, bins=256, range=[0, 256])
|
||||
# 初始化区间和频次
|
||||
interval = 255
|
||||
frequency = hist[255]
|
||||
while frequency < target_frequency:
|
||||
# 更新区间和频次
|
||||
interval -= 1
|
||||
# 检查直方图的频次是否为None,如果频次是None,则将其设为0,这样可以避免将None和int进行比较报错。
|
||||
frequency = hist[interval] if hist[interval] is not None else 0
|
||||
frequency += hist[interval] if hist[interval] is not None else 0
|
||||
# 如果频次接近10000则停止循环
|
||||
if target_frequency - 2000 <= frequency <= target_frequency + 2000:
|
||||
break
|
||||
|
||||
return interval, frequency
|
||||
|
||||
def reduce_sharpness(image, factor):
|
||||
'''
|
||||
使用PIL库减弱图像锐度
|
||||
:param image: 图像
|
||||
:param factor: 锐度因子,0表示最大程度减弱锐度,1表示原始图像
|
||||
:return: 减弱锐度后的图像
|
||||
'''
|
||||
# OpenCV 格式的图像转换为 PIL 的 Image 对象
|
||||
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
||||
pil_image = Image.fromarray(image_rgb)
|
||||
enhancer = ImageEnhance.Sharpness(pil_image)
|
||||
reduced_image = enhancer.enhance(factor)
|
||||
# PIL 的 Image 对象转换为 OpenCV 的图像格式
|
||||
image_array = np.array(reduced_image)
|
||||
sharpened_image = cv2.cvtColor(image_array, cv2.COLOR_RGB2BGR)
|
||||
|
||||
return sharpened_image
|
||||
|
||||
def sharpening_filter(image):
|
||||
'''
|
||||
锐化滤波器对图片进行锐化,增强图像中的边缘和细节
|
||||
:param image: 导入图片
|
||||
:return: 锐化后的图片
|
||||
'''
|
||||
sharp_kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
|
||||
sharpened_image = cv2.filter2D(image, -1, sharp_kernel)
|
||||
return sharpened_image
|
||||
|
||||
def find_last_x(image, slope_threshold = 1000):
|
||||
x = []
|
||||
y = []
|
||||
hist, bins = np.histogram(image, bins=256, range=[0, 256])
|
||||
|
||||
#找到50以内的最高峰
|
||||
max_y = 0
|
||||
max_i = 5
|
||||
for i in range(5, 50):
|
||||
if hist[i] > max_y:
|
||||
max_y = hist[i]
|
||||
max_i = i
|
||||
print(f'50以内最高峰值y:{max_y},最高峰位置x:{max_i}')
|
||||
|
||||
for i in range(2, max_i):
|
||||
x.append(i)
|
||||
y.append(hist[i])
|
||||
slopes = [abs(y[i + 1] - y[i]) for i in range(len(x) - 1)]
|
||||
|
||||
current_interval = []
|
||||
max_interval = []
|
||||
max_x = {}
|
||||
for i, slope in enumerate(slopes):
|
||||
current_interval.append(slope)
|
||||
if slope >= slope_threshold:
|
||||
if len(current_interval) > len(max_interval):
|
||||
max_interval = current_interval.copy()
|
||||
max_x[x[i]] = slope
|
||||
current_interval = []
|
||||
|
||||
print(max_x)
|
||||
last_x = list(max_x)[-1]
|
||||
last_y = max_x[last_x]
|
||||
return last_x, last_y
|
||||
|
||||
def find_last_high(image, slope_threshold = 2500):
|
||||
x = []
|
||||
y = []
|
||||
hist, bins = np.histogram(image, bins=255, range=[2, 255])
|
||||
|
||||
#找到200以上的最高峰
|
||||
max_y = 0
|
||||
max_i = 254
|
||||
for i in range(220, 255):
|
||||
if hist[i] > max_y:
|
||||
max_y = hist[i]
|
||||
max_i = i
|
||||
print(f'200以上的最高峰值y:{max_y},最高峰位置x:{max_i}')
|
||||
|
||||
for i in range(max_i, 255):
|
||||
x.append(i)
|
||||
y.append(hist[i])
|
||||
slopes = [abs(y[i + 1] - y[i]) for i in range(len(x) - 1)]
|
||||
|
||||
current_interval = []
|
||||
max_interval = []
|
||||
max_x = {}
|
||||
find = False
|
||||
for i in range(len(slopes) - 1, -1, -1):
|
||||
slope = slopes[i]
|
||||
current_interval.append(slope)
|
||||
if slope >= slope_threshold:
|
||||
find = True
|
||||
if len(current_interval) > len(max_interval):
|
||||
max_interval = current_interval.copy()
|
||||
max_x[x[i]] = slope
|
||||
current_interval = []
|
||||
#如果没有找到200以上很平,而且高度小于5000,就按220位置削平
|
||||
if not find and hist[220] < 5000:
|
||||
max_x[220] = hist[220]
|
||||
|
||||
print(max_x)
|
||||
if len(max_x) > 0:
|
||||
last_x = list(max_x)[0]
|
||||
last_y = max_x[last_x]
|
||||
else:
|
||||
print(f'找不到200以上曲线较平的区间,使用254作为最高峰')
|
||||
last_x = 254
|
||||
last_y = hist[254]
|
||||
return last_x, last_y
|
||||
|
||||
def remove_gray_and_sharpening(jpg_path):
|
||||
input_image = cv2.imread(jpg_path)
|
||||
# low_x_thresh, low_y_frequency = low_find_histogram_range(input_image, low_y_limit)
|
||||
low_x_thresh, low_y_frequency = find_last_x(input_image)
|
||||
# high_x_thresh, high_y_frequency = high_find_histogram_range(input_image, high_y_limit)
|
||||
high_x_thresh, high_y_frequency = find_last_high(input_image)
|
||||
print(f"{low_x_thresh} 区间, {low_y_frequency} 频次")
|
||||
print(f"{high_x_thresh} 区间, {high_y_frequency} 频次")
|
||||
high_output_image = ps_color_scale_adjustment(input_image, shadow=low_x_thresh, highlight=high_x_thresh, midtones=1)
|
||||
# high_output_image = ps_color_scale_adjustment(low_ouput_image, shadow=0, highlight=high_x_thresh, midtones=1)
|
||||
|
||||
# # 人体贴图和黑色背景交界处不进行锐化
|
||||
# gray = cv2.cvtColor(input_image, cv2.COLOR_BGR2GRAY)
|
||||
# _, thresh = cv2.threshold(gray, 2, 255, cv2.THRESH_BINARY)
|
||||
# kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
|
||||
# gradient = cv2.morphologyEx(thresh, cv2.MORPH_GRADIENT, kernel)
|
||||
# roi_gradient = cv2.bitwise_and(high_output_image, high_output_image, mask=gradient)
|
||||
|
||||
# # 锐化滤波器
|
||||
# # sharpened_image = sharpening_filter(high_output_image)
|
||||
# sharpened_image = reduce_sharpness(high_output_image, factor=4)
|
||||
# # 将原图边界替换锐化后的图片边界
|
||||
# sharpened_image[gradient != 0] = roi_gradient[gradient != 0]
|
||||
|
||||
# 直方图标记并保存
|
||||
# show_histogram(input_image, img_id, low_x_thresh, high_x_thresh)
|
||||
cv2.imwrite(jpg_path, high_output_image, [cv2.IMWRITE_JPEG_QUALITY, 95]) # 保存图片的质量是原图的 95%
|
||||
|
||||
|
||||
#获取该笔订单的信息,判断是否存在,不存在就跳过
|
||||
def getInfoByPrintId(print_id):
|
||||
res = requests.get(f'{get_pid_by_printid_url}?print_id={print_id}')
|
||||
print('获取pid:', f'{get_pid_by_printid_url}?print_id={print_id}', res.text)
|
||||
resCode = json.loads(res.text)['code']
|
||||
#该笔订单的获取信息有误,可能信息还没有成功
|
||||
if int(resCode) != 1000:
|
||||
tempMesg = json.loads(res.text)['message']
|
||||
#判断是否包含 不存在
|
||||
if tempMesg == "打印订单不存在":
|
||||
print(f"打印ID{print_id}打印订单不存在,跳过")
|
||||
# res = requests.get(f'https://mp.gray.api.suwa3d.com/api/footCode/deleteByPid?pid={pid}')
|
||||
#os.system(f'blender -b -P fill_dm_code.py')
|
||||
return False
|
||||
|
||||
print("获取打印任务信息有问题,重新任务队列,打印id-",print_id,"重新执行脚底板任务,等待20s")
|
||||
time.sleep(20)
|
||||
#将pid 重新扔进队列
|
||||
r.lpush("model:foot", print_id)
|
||||
return False
|
||||
return res.text
|
||||
|
||||
#获取订单的坐标信息,判断是否有,没有的话就重新生成坐标信息
|
||||
def getQrPosition(print_id,pid,order_id):
|
||||
#从云端获取qr_position,如果获取为空,调用cal_foot_position.py计算并上传qr_position,再重新读取qr_position.txt
|
||||
res = requests.get(f'{get_qr_position_url}?print_id={print_id}')
|
||||
print('从云端获取的qr_position1:', res.text)
|
||||
codeTemp = json.loads(res.text)['code']
|
||||
if str(codeTemp) == "-1":
|
||||
print(f"获取打印ID{print_id}的脚底板坐标失败,进行下一笔订单的处理")
|
||||
return False
|
||||
qr_position = json.loads(res.text)['data']['position_data']
|
||||
if qr_position == '':
|
||||
print(f"pid={pid},打印id={print_id} order_id={order_id},云端获取的坐标数据为空,进行重新计算")
|
||||
time.sleep(3)
|
||||
print('qr_position为空,调用cal_foot_position.py计算并上传qr_position')
|
||||
os.system(f'blender -b -P cal_foot_position.py -- {pid}_{order_id}_{print_id}')
|
||||
print("延时20s,等待计算脚底板坐标")
|
||||
time.sleep(20)
|
||||
res = requests.get(f'{get_qr_position_url}?print_id={print_id}')
|
||||
print(f"pid={pid},打印id={print_id} order_id={order_id},重新获取qr_position",res.text)
|
||||
print('从云端获取的qr_position3:', res.text)
|
||||
if str(json.loads(res.text)['code']) == "-1":
|
||||
print(f"pid={pid},打印id={print_id} order_id={order_id},重新获取qr_position 失败",res.text)
|
||||
return False
|
||||
qr_position = json.loads(res.text)['data']['position_data']
|
||||
if qr_position == '':
|
||||
#跳过该笔订单
|
||||
print(f"pid={pid},打印id={print_id} order_id={order_id},重新获取qr_position 为空,跳过脚底板的处理,执行下一笔任务")
|
||||
#移除该脚底板的面积处理
|
||||
res = requests.get(f'https://mp.gray.api.suwa3d.com/api/footCode/deleteByPid?pid={pid}')
|
||||
return False
|
||||
else:
|
||||
qr_position = json.loads(qr_position)
|
||||
|
||||
if qr_position == "":
|
||||
print("获取脚底坐标数据为空,重新任务队列,打印id-",print_id,"重新执行脚底板任务")
|
||||
#将pid 重新扔进队列
|
||||
r.lpush("model:foot", print_id)
|
||||
return False
|
||||
|
||||
return qr_position
|
||||
|
||||
def main(workdir, r, print_id):
|
||||
|
||||
resText = getInfoByPrintId(print_id)
|
||||
print(f"根据打印ID{print_id}获取订单信息-内容{resText}")
|
||||
if resText == False:
|
||||
print(f"根据打印ID{print_id}获取订单信息失败")
|
||||
return
|
||||
arrResText = json.loads(resText)
|
||||
#订单的相关信息
|
||||
use_foot_type = arrResText['data']['use_foot_type'] #构建类型
|
||||
pid = arrResText['data']['pid'] #pid
|
||||
order_id = arrResText['data']['order_id'] # order_id
|
||||
|
||||
#文件路劲
|
||||
filename = os.path.join(workdir, f'{pid}_{order_id}', find_obj(pid, order_id))
|
||||
print('导入obj文件:', filename)
|
||||
|
||||
#获取该笔订单的坐标
|
||||
qr_position = getQrPosition(print_id,pid,order_id)
|
||||
if qr_position == False:
|
||||
return
|
||||
|
||||
if type(qr_position) == str: qr_position = json.loads(qr_position)
|
||||
print(f'type of qr_position:{type(qr_position)}')
|
||||
print(f'qr_position:{qr_position}')
|
||||
|
||||
qr_position['location'][2] = -0.1
|
||||
|
||||
temp_foot_data = print_id
|
||||
# 根据print_id生成qr码
|
||||
qr_path = os.path.join(workdir, f'{pid}_{order_id}' ,'qr.png')
|
||||
# if use_foot_type == "short_url":
|
||||
# #调用接口获取短网址信息
|
||||
# short_url = get_short_url(print_id)
|
||||
# if short_url == False:
|
||||
# return
|
||||
# temp_foot_data = short_url
|
||||
# print(f'temp_foot_data---{temp_foot_data}')
|
||||
gen_data_matrix(print_id,pid, qr_path)
|
||||
#休眠1秒
|
||||
time.sleep(2)
|
||||
#判断是否存在 qr_path,不存在就执行下一个任务
|
||||
if not os.path.exists(qr_path):
|
||||
#移除该脚底板的面积处理
|
||||
print(f"pid={pid},打印id={print_id} order_id={order_id},生成的二维码为空,跳过脚底板的处理,执行下一笔任务")
|
||||
res = requests.get(f'https://mp.gray.api.suwa3d.com/api/footCode/deleteByPid?pid={pid}')
|
||||
#os.system(f'blender -b -P fill_dm_code.py')
|
||||
return
|
||||
|
||||
#在blender中贴上脚底板二维码的信息
|
||||
|
||||
# 导入obj文件,重置到标准单位
|
||||
bpy.ops.wm.read_homefile()
|
||||
bpy.context.preferences.view.language = 'en_US'
|
||||
bpy.ops.object.delete(use_global=False, confirm=False)
|
||||
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'
|
||||
|
||||
bpy.ops.import_scene.obj(filepath=filename)
|
||||
#bpy.ops.wm.obj_import(filepath=filename)
|
||||
obj = bpy.context.selected_objects[0]
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
obj.select_set(True)
|
||||
|
||||
pid_objname = find_pid_objname(pid)
|
||||
|
||||
scale = 90 / obj.dimensions.y
|
||||
obj.scale = (scale, scale, scale)
|
||||
bpy.ops.object.align(align_mode='OPT_1', relative_to='OPT_1', align_axis={'Z'})
|
||||
bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS', center='MEDIAN')
|
||||
obj.location[0] = 0
|
||||
obj.location[1] = 0
|
||||
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
|
||||
|
||||
print(f'qr_position:{qr_position}')
|
||||
print(f'qr_position_type:{type(qr_position)}')
|
||||
|
||||
# 根据qr_position的值,恢复qr的位置和尺寸,重新生成贴图
|
||||
bpy.ops.object.load_reference_image(filepath=os.path.join(workdir, f'{pid}_{order_id}', 'qr.png'))
|
||||
bpy.context.object.rotation_euler = (math.radians(-180), math.radians(0), qr_position['rotation'])
|
||||
bpy.ops.transform.translate(value=qr_position['location'], orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False, snap=False, snap_elements={'INCREMENT'}, use_snap_project=False, snap_target='CLOSEST', use_snap_self=True, use_snap_edit=True, use_snap_nonedit=True, use_snap_selectable=False, release_confirm=True)
|
||||
|
||||
bpy.context.object.empty_display_size = qr_position['dimensions'][0]
|
||||
|
||||
qr_path = os.path.join(workdir,f'{pid}_{order_id}', f"{pid}_{order_id}Tex1_qr.png")
|
||||
jpg_path = os.path.join(workdir,f'{pid}_{order_id}', f"{pid}Tex1.jpg")
|
||||
#判断是否存在 jpg_path,不存在就执行下一个任务
|
||||
if not os.path.exists(jpg_path):
|
||||
#移除该脚底板的面积处理
|
||||
res = requests.get(f'https://mp.gray.api.suwa3d.com/api/footCode/deleteByPid?pid={pid}')
|
||||
#os.system(f'blender -b -P fill_dm_code.py')
|
||||
bpy.ops.wm.quit_blender()
|
||||
return
|
||||
|
||||
jpg_img = Image.open(jpg_path)
|
||||
shutil.copyfile(jpg_path, os.path.join(workdir,f'{pid}_{order_id}', f"{pid}Tex1_noqr.jpg"))
|
||||
|
||||
bpy.context.scene.eyek.res_x = jpg_img.width
|
||||
bpy.context.scene.eyek.res_y = jpg_img.height
|
||||
bpy.context.scene.eyek.path_export_image = qr_path
|
||||
bpy.data.objects[pid_objname].select_set(True)
|
||||
bpy.data.objects['Empty'].select_set(True)
|
||||
bpy.context.view_layer.objects.active = bpy.data.objects[pid_objname]
|
||||
bpy.ops.eyek.exe()
|
||||
|
||||
#判断qr_path是否存在,不存在就执行下一个任务
|
||||
if not os.path.exists(qr_path):
|
||||
#移除该脚底板的面积处理
|
||||
res = requests.get(f'https://mp.gray.api.suwa3d.com/api/footCode/deleteByPid?pid={pid}')
|
||||
#os.system(f'blender -b -P fill_dm_code.py')
|
||||
bpy.ops.wm.quit_blender()
|
||||
return
|
||||
|
||||
qr_img = Image.open(qr_path)
|
||||
jpg_img.paste(qr_img, (0, 0), qr_img)
|
||||
jpg_img.save(jpg_path, quality=90)
|
||||
shutil.copyfile(jpg_path, os.path.join(workdir,f'{pid}_{order_id}', f"{pid}Tex1_qr.jpg"))
|
||||
|
||||
# 加入去灰、锐化
|
||||
remove_gray_and_sharpening(jpg_path)
|
||||
|
||||
shutil.copyfile(jpg_path, os.path.join(workdir,f'{pid}_{order_id}', f"{pid}Tex1_qr.jpg"))
|
||||
|
||||
#上传脚底板文件 -》 修改为移动脚底板文件
|
||||
upload_jpg_mtl(pid, order_id, print_id)
|
||||
|
||||
# plt.axis('equal')
|
||||
# plt.show()
|
||||
|
||||
# 保存blend文件
|
||||
# bpy.ops.wm.save_as_mainfile(filepath=f'{workdir}{pid}_{order_id}/{pid}_qr_end.blend')
|
||||
bpy.ops.wm.quit_blender()
|
||||
|
||||
# 删除临时文件
|
||||
print("workdirworkdir",workdir)
|
||||
shutil.rmtree(os.path.join(workdir, f'{pid}_{order_id}'))
|
||||
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 运行{print_id}任务完成,继续运行下一个任务')
|
||||
# restart_current_process("blender -b -P fill_dm_code.py")
|
||||
|
||||
def imagePiex(filePath,piex):
|
||||
# 打开图片
|
||||
image = Image.open(filePath)
|
||||
# 设置新的最大宽度和高度
|
||||
max_size = (piex, piex)
|
||||
# 保持宽高比缩放图片
|
||||
image.thumbnail(max_size)
|
||||
# 保存调整后的图片
|
||||
image.save(filePath)
|
||||
|
||||
#根据print_id 获取 短网址
|
||||
def get_short_url(print_id):
|
||||
res = requests.get(f'{get_short_url_by_print_id}?print_id={print_id}')
|
||||
resCode = json.loads(res.text)['code']
|
||||
#该笔订单的获取信息有误,可能信息还没有成功
|
||||
if int(resCode) != 1000:
|
||||
print("获取短网址信息失败,延时1分钟,重新扔入脚底板队列,打印id-",print_id,"重新执行脚底板任务")
|
||||
time.sleep(60)
|
||||
#将pid 重新扔进队列
|
||||
r.lpush("model:foot", print_id)
|
||||
#重新调用脚底板程序
|
||||
return False
|
||||
return json.loads(res.text)['data']
|
||||
|
||||
|
||||
@retry(stop_max_attempt_number=10, wait_fixed=2000)
|
||||
def upload_jpg_mtl(pid, order_id, print_id):
|
||||
try:
|
||||
print("移动脚底板文件")
|
||||
#判断文件夹是否存在,不存在则创建
|
||||
if not os.path.exists(os.path.join(f'{resFilePath}/{pid}/foot_print_id_{print_id}/')):
|
||||
os.makedirs(os.path.join(f'{resFilePath}/{pid}/foot_print_id_{print_id}/'),mode=0o777, exist_ok=True)
|
||||
else:
|
||||
#移除路径下的文件
|
||||
if os.path.exists(os.path.join(f'{resFilePath}/{pid}/foot_print_id_{print_id}/{pid}Tex1.jpg')):
|
||||
os.remove(os.path.join(f'{resFilePath}/{pid}/foot_print_id_{print_id}/{pid}Tex1.jpg'))
|
||||
print(f"文件 '{pid}' 已成功删除。")
|
||||
|
||||
shutil.move(os.path.join(workdir,f'{pid}_{order_id}', f"{pid}Tex1.jpg"),os.path.join(f'{resFilePath}/{pid}/foot_print_id_{print_id}/'))
|
||||
|
||||
|
||||
#print('生成贴图完成,开始上传...')
|
||||
# oss_client.put_object_from_file(f'objs/print/{pid}/{pid}Tex1.{print_id}.jpg', os.path.join(workdir,f'{pid}_{order_id}', f"{pid}Tex1.jpg"))
|
||||
# oss_client.put_object_from_file(f'objs/print/{pid}/{pid}.mtl', os.path.join(workdir,f'{pid}_{order_id}', f"{pid}.mtl"))
|
||||
# # oss_client.put_object_from_file(f'objs/print/{pid}/{pid}Tex1_noqr.jpg', os.path.join(workdir,f'{pid}_{order_id}', f"{pid}Tex1_noqr.jpg"))
|
||||
|
||||
print('更新状态为已生成脚底板二维码')
|
||||
res = requests.post(f'{upload_qr_position_url}?print_id={print_id}')
|
||||
# #记录日志
|
||||
# logging.error(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}-结果:pid:{pid}-print_id:{print_id} {str(res.text)}")
|
||||
print('更新返回状态:', f'{upload_qr_position_url}?print_id={print_id}', res.text)
|
||||
|
||||
except Exception as e:
|
||||
|
||||
print("迁移文件出 yichang ")
|
||||
|
||||
|
||||
def worker(workdir, r, print_id):
|
||||
"""每个子进程的工作函数,用于处理单个 print_id。"""
|
||||
try:
|
||||
main(workdir, r, print_id)
|
||||
except Exception as e:
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f"处理 print_id {print_id} 时出错: {e}")
|
||||
|
||||
def process_print_ids(workdir, r, pool_size):
|
||||
"""监控 Redis 队列并并行处理 print_id,同时控制进程池的大小。"""
|
||||
# 创建进程池
|
||||
pool = multiprocessing.Pool(processes=pool_size)
|
||||
|
||||
while True:
|
||||
try:
|
||||
# 如果队列为空,等待10秒后重试
|
||||
if r.llen('model:foot') == 0:
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), '队列为空,10秒后重试')
|
||||
time.sleep(10)
|
||||
continue
|
||||
|
||||
# 从队列中取出一个 print_id
|
||||
print_id = r.lpop('model:foot')
|
||||
if print_id is None:
|
||||
continue
|
||||
|
||||
# 判断该 print_id 是否已经存在,避免重复处理
|
||||
isHaveAlready = 0
|
||||
for i in r.lrange('model:foot', 0, -1):
|
||||
if i == print_id:
|
||||
isHaveAlready = 1
|
||||
break
|
||||
if isHaveAlready == 1:
|
||||
continue
|
||||
|
||||
# 如果 print_id 是唯一的,则将任务提交给进程池处理
|
||||
print(f"正在处理 print_id: {print_id}")
|
||||
pool.apply_async(worker, args=(workdir, r, print_id)) # 使用 apply_async 异步执行任务
|
||||
|
||||
except Exception as e:
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f"出现异常错误: {e}")
|
||||
r = create_redis_connection()
|
||||
continue
|
||||
|
||||
def create_redis_connection():
|
||||
"""创建 Redis 连接,若连接失败则重试"""
|
||||
while True:
|
||||
try:
|
||||
r = redis.Redis(host="mark.api.suwa3d.com", password="kcV2000", port=6379, db=6)
|
||||
# 尝试进行一次操作,检查连接是否有效
|
||||
r.ping() # ping 操作是一个简单的连接测试
|
||||
print("Redis连接成功!")
|
||||
return r
|
||||
except ConnectionError:
|
||||
print("Redis连接失败,正在重试...")
|
||||
time.sleep(5)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
atexit.register(common.notify,"打印工厂-本地虚拟木脚底板处理程序已停止一个")
|
||||
low_y_limit = 25000
|
||||
high_y_limit = 13000
|
||||
|
||||
get_qr_position_url = 'https://mp.gray.api.suwa3d.com/api/printOrder/getFootCodePositionData'
|
||||
upload_qr_position_url = 'https://mp.gray.api.suwa3d.com/api/printOrder/updateFootCodeStatus'
|
||||
get_pid_by_printid_url = 'https://mp.gray.api.suwa3d.com/api/printOrder/getPidByPrintId'
|
||||
get_short_url_by_print_id = 'https://mp.gray.api.suwa3d.com/api/footCode/qrcode'
|
||||
# get_qr_position_url = 'http://172.31.1.254:8199/api/printOrder/getFootCodePositionData'
|
||||
# upload_qr_position_url = 'http://172.31.1.254:8199/api/printOrder/updateFootCodeStatus'
|
||||
# get_pid_by_printid_url = 'http://172.31.1.254:8199/api/printOrder/getPidByPrintId'
|
||||
|
||||
|
||||
r = redis.Redis(host='mark.api.suwa3d.com', password='kcV2000', port=6379, db=6)
|
||||
# r = redis.Redis(host='172.31.1.254', password='', port=6379, db=6)
|
||||
AccessKeyId = 'LTAI5tSReWm8hz7dSYxxth8f'
|
||||
AccessKeySecret = '8ywTDF9upPAtvgXtLKALY2iMYHIxdS'
|
||||
Endpoint = 'oss-cn-shanghai.aliyuncs.com'
|
||||
Bucket = 'suwa3d-securedata'
|
||||
oss_client = oss2.Bucket(oss2.Auth(AccessKeyId, AccessKeySecret), Endpoint, Bucket)
|
||||
|
||||
if platform.system() == 'Windows':
|
||||
workdir = 'E:\\print\\foot\\'
|
||||
else:
|
||||
workdir = '/data/datasets/foot/'
|
||||
|
||||
#构建好的obj文件目录
|
||||
sourceFilePath = '/data/datasets/print'
|
||||
#脚底板最终保存的路径
|
||||
resFilePath = '/data/datasets/complate/objs'
|
||||
print("Usage: blender -b -P fill_dm_code.py")
|
||||
|
||||
# # 控制进程池的大小
|
||||
# pool_size = 2 # 设置最大并发进程数为4(根据需求调整)
|
||||
|
||||
# # 创建一个进程池
|
||||
# pool = multiprocessing.Pool(processes=pool_size)
|
||||
|
||||
# # 如果传递了参数,则处理特定的 print_ids
|
||||
# if len(sys.argv) == 5:
|
||||
# print_ids = sys.argv[-1]
|
||||
# for print_id in print_ids.split(','):
|
||||
# main(workdir, r, print_id)
|
||||
# else:
|
||||
# # 启动进程池,监控队列并并行处理 print_id
|
||||
# process_print_ids(workdir, r, pool_size)
|
||||
|
||||
if len(sys.argv) == 5:
|
||||
print_ids = sys.argv[-1]
|
||||
for print_id in print_ids.split(','):
|
||||
main(workdir, r, print_id)
|
||||
else:
|
||||
while True:
|
||||
try:
|
||||
#判断队列是否为空
|
||||
if r.llen('model:foot') == 0:
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), '队列为空,10秒后重试')
|
||||
time.sleep(10)
|
||||
continue
|
||||
#不为空,取出队列的第一个值
|
||||
print_id = r.lpop('model:foot')
|
||||
if print_id is None:
|
||||
continue
|
||||
#判断是否存在相同的值
|
||||
isHaveAlready = 0
|
||||
for i in r.lrange('model:foot', 0, -1):
|
||||
if i == print_id:
|
||||
isHaveAlready = 1
|
||||
break
|
||||
if isHaveAlready == 1:
|
||||
continue
|
||||
print_id = print_id.decode('utf-8')
|
||||
#获取队列的长度
|
||||
lengthQueue = r.llen('model:foot')
|
||||
print(f"正在处理 print_id: {print_id}, 队列长度: {lengthQueue}")
|
||||
|
||||
#如果是唯一值, 则调用main函数
|
||||
main(workdir, r, print_id)
|
||||
except Exception as e:
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), '出现异常错误,5秒后重试',e)
|
||||
r = create_redis_connection()
|
||||
continue
|
||||
|
||||
@@ -0,0 +1,223 @@
|
||||
from math import radians
|
||||
import sys, platform, os, time, bpy, requests, json, bmesh, shutil
|
||||
from PIL import Image
|
||||
import platform
|
||||
# if platform.system() == 'Windows':
|
||||
# sys.path.append('e:\\libs\\')
|
||||
# else:
|
||||
# sys.path.append('/data/deploy/make3d/make2/libs/')
|
||||
sys.path.append('/home/acprint/code/libs/')
|
||||
import config, libs
|
||||
|
||||
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 fix_link_texture(pid):
|
||||
# 修改obj中的mtl文件为pid_original.mtl
|
||||
path = os.path.join(workdir, 'print', f'{pid}_{orderId}')
|
||||
filename = os.path.join(path, f'{pid}_original.obj')
|
||||
|
||||
with open(filename, 'r') as f:
|
||||
lines = f.readlines()
|
||||
for i in range(len(lines)):
|
||||
if lines[i].startswith('mtllib'):
|
||||
lines[i] = f'mtllib {pid}_original.mtl\n'
|
||||
break
|
||||
with open(filename, 'w') as f:
|
||||
f.writelines(lines)
|
||||
|
||||
f.close()
|
||||
|
||||
# 将pid.mtl文件复制为pid_original.mtl _decimate
|
||||
shutil.copy(os.path.join(path, f'{pid}.mtl'), os.path.join(path, f'{pid}_original.mtl'))
|
||||
shutil.copy(os.path.join(path, f'{pid}Tex1.jpg'), os.path.join(path, f'{pid}Tex1_decimate.jpg'))
|
||||
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=100, optimize=True)
|
||||
print('resize texture file to 50% success')
|
||||
# 修改pid_original.mtl文件中的贴图为pid_old.jpg
|
||||
with open(os.path.join(path, f'{pid}_original.mtl'), 'r') as f:
|
||||
lines = f.readlines()
|
||||
for i in range(len(lines)):
|
||||
if lines[i].startswith('map_Kd'):
|
||||
lines[i] = f'map_Kd {pid}Tex1_decimate.jpg\n'
|
||||
break
|
||||
with open(os.path.join(path, f'{pid}_original.mtl'), 'w') as f:
|
||||
f.writelines(lines)
|
||||
|
||||
f.close()
|
||||
|
||||
def imagePiex(filePath,piex):
|
||||
# 打开图片
|
||||
image = Image.open(filePath)
|
||||
# 设置新的最大宽度和高度
|
||||
max_size = (piex, piex)
|
||||
# 保持宽高比缩放图片
|
||||
image.thumbnail(max_size)
|
||||
# 保存调整后的图片
|
||||
image.save(filePath)
|
||||
|
||||
def main():
|
||||
start = time.time()
|
||||
|
||||
get_printsize_url = 'https://mp.gray.api.suwa3d.com/api/printOrder/infoByOrderId'
|
||||
upload_obj_volume_url = 'https://mp.gray.api.suwa3d.com/api/physical/add' # ?pid=1&order_id=1&faces=1&volume=1
|
||||
|
||||
print(f'{get_printsize_url}?order_id={orderId}')
|
||||
res = requests.get(f'{get_printsize_url}?id={orderId}')
|
||||
print('获取打印尺寸:', res.text)
|
||||
|
||||
if res.status_code == 200:
|
||||
pid = res.json()['data']['pid']
|
||||
path = os.path.join(workdir, 'print', f'{pid}_{orderId}')
|
||||
filename = os.path.join(path, f'{pid}.obj')
|
||||
imagePath = os.path.join(path, f'{pid}Tex1.jpg')
|
||||
bpy.ops.object.delete(use_global=False, confirm=False)
|
||||
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'
|
||||
|
||||
print('正在处理:', filename)
|
||||
bpy.ops.import_scene.obj(filepath=filename)
|
||||
obj = bpy.context.selected_objects[0]
|
||||
print('原始模型尺寸:', obj.dimensions)
|
||||
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
|
||||
print('应用后模型尺寸:', obj.dimensions)
|
||||
shutil.copy(filename, os.path.join(path, f'{pid}_original.obj'))
|
||||
filename_original = os.path.join(path, f'{pid}_original.obj')
|
||||
headcount = res.json()['data']['headcount']
|
||||
for f in res.json()['data']['fileList']:
|
||||
|
||||
if "undefined" in f:
|
||||
continue
|
||||
|
||||
try:
|
||||
height = float(f.split('_')[-2][:-2]) * 10
|
||||
except Exception as e:
|
||||
print("eeee",e)
|
||||
bpy.ops.wm.quit_blender()
|
||||
return
|
||||
|
||||
|
||||
|
||||
obj = bpy.context.selected_objects[0]
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
print(f'{f}处理前{height}mm模型尺寸: {obj.dimensions}')
|
||||
scale = height / obj.dimensions.z
|
||||
obj.scale = (scale, scale, scale)
|
||||
bpy.ops.object.transform_apply(scale=True)
|
||||
print(f'{f}处理后{height}mm模型尺寸: {obj.dimensions}')
|
||||
|
||||
if headcount == 1 and height <= 80:
|
||||
pixs = 4096
|
||||
faces_dest = 125000
|
||||
if height <= 50:
|
||||
pixs = 2048
|
||||
faces_dest = 63000
|
||||
print(f'减面到{faces_dest}')
|
||||
faces_dest = faces_dest * headcount
|
||||
# 减面
|
||||
faces_current = len(obj.data.polygons)
|
||||
bpy.ops.object.modifier_add(type='DECIMATE')
|
||||
bpy.context.object.modifiers["Decimate"].ratio = faces_dest / faces_current
|
||||
bpy.ops.object.modifier_apply(modifier="Decimate")
|
||||
# imagePiex(imagePath,pixs)
|
||||
|
||||
bpy.ops.export_scene.obj(filepath=os.path.join(path, f'{pid}.obj'))
|
||||
if os.path.exists(os.path.join(path, f)):
|
||||
os.remove(os.path.join(path, f))
|
||||
os.rename(os.path.join(path, f'{pid}.obj'), os.path.join(path, f))
|
||||
#config.oss_bucket.put_object_from_file(f'objs/print/{pid}/{f}', os.path.join(path, f))
|
||||
|
||||
|
||||
|
||||
# 重新加载模型,然后生成数字模型
|
||||
bpy.ops.object.delete(use_global=False, confirm=False)
|
||||
fix_link_texture(pid)
|
||||
bpy.ops.import_scene.obj(filepath=filename_original)
|
||||
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)
|
||||
|
||||
scale = 90 / obj.dimensions.y
|
||||
obj.scale = (scale, scale, scale)
|
||||
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
|
||||
# if str(pid) == '120745': bpy.ops.wm.save_as_mainfile(filepath=os.path.join(path, f'{pid}_{orderId}.blend'))
|
||||
|
||||
|
||||
|
||||
bm = bmesh_copy_from_object(obj)
|
||||
obj_volume = round(bm.calc_volume() / 1000, 3)
|
||||
print('volume:', obj_volume)
|
||||
print('weight:', obj_volume * 1.2, 'g')
|
||||
tempWeight = obj_volume * 1.2
|
||||
faces = len(obj.data.polygons)
|
||||
print('faces:', faces)
|
||||
upload_res = requests.get(f'{upload_obj_volume_url}?pid={pid}&order_id={orderId}&faces={faces}&volume={obj_volume}&headcount={headcount}&weight={tempWeight}')
|
||||
print('上传模型体积:', upload_res.text)
|
||||
|
||||
# 生成数字模型
|
||||
|
||||
faces_dest = 120000 * headcount
|
||||
# 减面
|
||||
faces_current = len(obj.data.polygons)
|
||||
bpy.ops.object.modifier_add(type='DECIMATE')
|
||||
bpy.context.object.modifiers["Decimate"].ratio = faces_dest / faces_current
|
||||
bpy.ops.object.modifier_apply(modifier="Decimate")
|
||||
|
||||
bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_VOLUME', center='MEDIAN')
|
||||
bpy.context.object.location[0] = 0
|
||||
bpy.context.object.location[1] = 0
|
||||
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
|
||||
|
||||
bpy.ops.export_scene.obj(filepath=os.path.join(path, f'{pid}_decimate.obj'))
|
||||
bpy.ops.export_scene.gltf(filepath=os.path.join(path, f'{pid}_decimate.glb'), export_format='GLB', export_apply=True, export_jpeg_quality=100)
|
||||
config.oss_bucket.put_object_from_file(f'glbs/3d/{pid}.glb', os.path.join(path, f'{pid}_decimate.glb'))
|
||||
bpy.ops.wm.quit_blender()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if platform.system() == 'Windows':
|
||||
workdir = 'E:\\'
|
||||
else:
|
||||
workdir = '/data/datasets/'
|
||||
|
||||
if len(sys.argv) - (sys.argv.index("--") + 1) < 1:
|
||||
print("Usage: blender -b -P resize_model.py -- <orderId>")
|
||||
sys.exit(1)
|
||||
orderId = sys.argv[sys.argv.index("--") + 1]
|
||||
|
||||
main()
|
||||
+34
-5
@@ -76,6 +76,15 @@ def fix_link_texture(pid):
|
||||
|
||||
f.close()
|
||||
|
||||
def imagePiex(filePath,piex):
|
||||
# 打开图片
|
||||
image = Image.open(filePath)
|
||||
# 设置新的最大宽度和高度
|
||||
max_size = (piex, piex)
|
||||
# 保持宽高比缩放图片
|
||||
image.thumbnail(max_size)
|
||||
# 保存调整后的图片
|
||||
image.save(filePath)
|
||||
|
||||
def main():
|
||||
start = time.time()
|
||||
@@ -91,6 +100,7 @@ def main():
|
||||
pid = res.json()['data']['pid']
|
||||
path = os.path.join(workdir, 'print', f'{pid}_{orderId}')
|
||||
filename = os.path.join(path, f'{pid}.obj')
|
||||
imagePath = os.path.join(path, f'{pid}Tex1.jpg')
|
||||
bpy.ops.object.delete(use_global=False, confirm=False)
|
||||
bpy.context.scene.unit_settings.scale_length = 0.001
|
||||
bpy.context.scene.unit_settings.length_unit = 'CENTIMETERS'
|
||||
@@ -104,7 +114,7 @@ def main():
|
||||
print('应用后模型尺寸:', obj.dimensions)
|
||||
shutil.copy(filename, os.path.join(path, f'{pid}_original.obj'))
|
||||
filename_original = os.path.join(path, f'{pid}_original.obj')
|
||||
|
||||
headcount = res.json()['data']['headcount']
|
||||
for f in res.json()['data']['fileList']:
|
||||
|
||||
if "undefined" in f:
|
||||
@@ -117,19 +127,38 @@ def main():
|
||||
bpy.ops.wm.quit_blender()
|
||||
return
|
||||
|
||||
|
||||
|
||||
|
||||
obj = bpy.context.selected_objects[0]
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
print(f'{f}处理前{height}mm模型尺寸: {obj.dimensions}')
|
||||
scale = height / obj.dimensions.z
|
||||
obj.scale = (scale, scale, scale)
|
||||
bpy.ops.object.transform_apply(scale=True)
|
||||
print(f'{f}处理后{height}mm模型尺寸: {obj.dimensions}')
|
||||
|
||||
|
||||
if headcount == 1 and height <= 80:
|
||||
pixs = 4096
|
||||
faces_dest = 125000
|
||||
if height <= 50:
|
||||
pixs = 2048
|
||||
faces_dest = 63000
|
||||
print(f'减面到{faces_dest}')
|
||||
faces_dest = faces_dest * headcount
|
||||
# 减面
|
||||
faces_current = len(obj.data.polygons)
|
||||
bpy.ops.object.modifier_add(type='DECIMATE')
|
||||
bpy.context.object.modifiers["Decimate"].ratio = faces_dest / faces_current
|
||||
bpy.ops.object.modifier_apply(modifier="Decimate")
|
||||
# imagePiex(imagePath,pixs)
|
||||
|
||||
bpy.ops.export_scene.obj(filepath=os.path.join(path, f'{pid}.obj'))
|
||||
if os.path.exists(os.path.join(path, f)):
|
||||
os.remove(os.path.join(path, f))
|
||||
os.rename(os.path.join(path, f'{pid}.obj'), os.path.join(path, f))
|
||||
config.oss_bucket.put_object_from_file(f'objs/print/{pid}/{f}', os.path.join(path, f))
|
||||
#config.oss_bucket.put_object_from_file(f'objs/print/{pid}/{f}', os.path.join(path, f))
|
||||
|
||||
|
||||
|
||||
# 重新加载模型,然后生成数字模型
|
||||
bpy.ops.object.delete(use_global=False, confirm=False)
|
||||
@@ -148,7 +177,7 @@ def main():
|
||||
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
|
||||
# if str(pid) == '120745': bpy.ops.wm.save_as_mainfile(filepath=os.path.join(path, f'{pid}_{orderId}.blend'))
|
||||
|
||||
headcount = res.json()['data']['headcount']
|
||||
|
||||
|
||||
bm = bmesh_copy_from_object(obj)
|
||||
obj_volume = round(bm.calc_volume() / 1000, 3)
|
||||
|
||||
@@ -0,0 +1,399 @@
|
||||
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}/'
|
||||
#根据order_id 获取文件在 oss 上的存储路径
|
||||
if order_id is not None:
|
||||
tempURL = "https://mp.api.suwa3d.com/api/order/getOssSuffixByOrderId?order_id="+str(order_id)
|
||||
print(tempURL)
|
||||
res = requests.get(tempURL)
|
||||
print(res.json())
|
||||
resCode = res.json()['code']
|
||||
if int(resCode) != 1000:
|
||||
return -1
|
||||
print(res.text)
|
||||
if res.json()['data'] != "":
|
||||
prefix = f'objs/print/{pid}/{res.json()["data"]}/{str(order_id)}'
|
||||
|
||||
print(prefix)
|
||||
filelist = oss2.ObjectIteratorV2(oss_client, prefix=prefix)
|
||||
#判断是否有值,没有值的话就从老的路径再获取一次数据
|
||||
if len(list(filelist)) == 0:
|
||||
filelist = oss2.ObjectIteratorV2(oss_client, prefix=f'objs/print/{pid}/')
|
||||
else:
|
||||
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" and filename != str(pid)+"_RB_B_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/infoByOrderId'
|
||||
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
|
||||
|
||||
#根据 buy_type 判断 是否是冰箱贴 或者徽章
|
||||
noresize = str(res['noresize'])
|
||||
if noresize == "1":
|
||||
#塞入到no_resize 队列
|
||||
r.lpush("model:noresize", orderId)
|
||||
return
|
||||
|
||||
pid = str(res['pid'])
|
||||
if pid == "88985":
|
||||
return
|
||||
if pid == "":
|
||||
return
|
||||
#创建正在处理的文本内容
|
||||
creatDoingLog(orderId)
|
||||
|
||||
print_type = 1
|
||||
digital_type = 1 # 0: 只有手办 1: 只有数字模型 2: 手办+数字模型
|
||||
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'orderId:{orderId} pid:{pid} 生成待打印模型 start', )
|
||||
isFindObj = False
|
||||
print("AAAAAAAAAAAAAAAAAA")
|
||||
downloadRes = down_obj_fromoss(pid, print_type, orderId,download_flag="print_build")
|
||||
print("downloadRes",downloadRes)
|
||||
if downloadRes == -1:
|
||||
print("下载错误")
|
||||
return
|
||||
# 获取程序运行当前目录
|
||||
resize_py_path = os.path.join(os.getcwd(), 'blender', 'build_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 gray_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))
|
||||
|
||||
print(f"复制文件路径-{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 gray_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:
|
||||
#构建打印文件
|
||||
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)
|
||||
@@ -0,0 +1,399 @@
|
||||
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}/'
|
||||
#根据order_id 获取文件在 oss 上的存储路径
|
||||
if order_id is not None:
|
||||
tempURL = "https://mp.gray.api.suwa3d.com/api/order/getOssSuffixByOrderId?order_id="+str(order_id)
|
||||
print(tempURL)
|
||||
res = requests.get(tempURL)
|
||||
print(res.json())
|
||||
resCode = res.json()['code']
|
||||
if int(resCode) != 1000:
|
||||
return -1
|
||||
print(res.text)
|
||||
if res.json()['data'] != "":
|
||||
prefix = f'objs/print/{pid}/{res.json()["data"]}/{str(order_id)}'
|
||||
|
||||
print(prefix)
|
||||
filelist = oss2.ObjectIteratorV2(oss_client, prefix=prefix)
|
||||
#判断是否有值,没有值的话就从老的路径再获取一次数据
|
||||
if len(list(filelist)) == 0:
|
||||
filelist = oss2.ObjectIteratorV2(oss_client, prefix=f'objs/print/{pid}/')
|
||||
else:
|
||||
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" and filename != str(pid)+"_RB_B_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.gray.api.suwa3d.com/api/printOrder/infoByOrderId'
|
||||
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='mark.api.suwa3d.com', 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
|
||||
|
||||
#根据 buy_type 判断 是否是冰箱贴 或者徽章
|
||||
buyType = str(res['buy_type'])
|
||||
if buyType == "2" or buyType == "3" or buyType == "4":
|
||||
#塞入到no_resize 队列
|
||||
r.lpush("model:noresize", orderId)
|
||||
return
|
||||
|
||||
pid = str(res['pid'])
|
||||
if pid == "88985":
|
||||
return
|
||||
if pid == "":
|
||||
return
|
||||
#创建正在处理的文本内容
|
||||
creatDoingLog(orderId)
|
||||
|
||||
print_type = 1
|
||||
digital_type = 1 # 0: 只有手办 1: 只有数字模型 2: 手办+数字模型
|
||||
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), f'orderId:{orderId} pid:{pid} 生成待打印模型 start', )
|
||||
isFindObj = False
|
||||
print("AAAAAAAAAAAAAAAAAA")
|
||||
downloadRes = down_obj_fromoss(pid, print_type, orderId,download_flag="print_build")
|
||||
print("downloadRes",downloadRes)
|
||||
if downloadRes == -1:
|
||||
print("下载错误")
|
||||
return
|
||||
# 获取程序运行当前目录
|
||||
resize_py_path = os.path.join(os.getcwd(), 'blender', 'gray_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 gray_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))
|
||||
|
||||
print(f"复制文件路径-{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 gray_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="mark.api.suwa3d.com", 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:
|
||||
#构建打印文件
|
||||
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.gray.api.suwa3d.com/api/customerP3dLog/updateStatusToWaitingPlatformCheckingStatus'
|
||||
update_team_check_url = 'https://mp.gray.api.suwa3d.com/api/customerP3dLog/updateStatusToWaitingTeamCheckingStatus'
|
||||
update_status_printstatus_url = 'https://mp.gray.api.suwa3d.com/api/customerP3dLog/updateBuildPrintModelStatus'
|
||||
update_makeprintobj_status_url = 'https://mp.gray.api.suwa3d.com/api/printOrder/updateMakePrintObjSucceed'
|
||||
getRepairInfo_url = 'https://repair.gray.api.suwa3d.com/api/modelRepairOrder/teamCheckGLBInfo'
|
||||
update_repair_status_url = 'https://repair.gray.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)
|
||||
@@ -0,0 +1,249 @@
|
||||
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 create_redis_connection():
|
||||
"""创建 Redis 连接,若连接失败则重试"""
|
||||
while True:
|
||||
try:
|
||||
r = redis.Redis(host="mark.api.suwa3d.com", password="kcV2000", port=6379, db=6)
|
||||
# 尝试进行一次操作,检查连接是否有效
|
||||
r.ping() # ping 操作是一个简单的连接测试
|
||||
print("Redis连接成功!")
|
||||
return r
|
||||
except ConnectionError:
|
||||
print("Redis连接失败,正在重试...")
|
||||
time.sleep(5)
|
||||
|
||||
|
||||
def main(r):
|
||||
while True:
|
||||
try:
|
||||
#构建打印文件
|
||||
make3d4print_task(r)
|
||||
except Exception as e:
|
||||
print(f'出现异常:{e}')
|
||||
time.sleep(15)
|
||||
r = create_redis_connection()
|
||||
continue
|
||||
|
||||
#根据pid获取orderId
|
||||
def getPidFromOrderId(orderId):
|
||||
getPidFromOrderId_url = 'https://mp.gray.api.suwa3d.com/api/printOrder/infoByOrderId'
|
||||
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 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}')
|
||||
|
||||
if not os.path.exists(path): os.makedirs(path)
|
||||
|
||||
# 根据前缀获取文件列表
|
||||
prefix = f'objs/print/{pid}/'
|
||||
#根据order_id 获取文件在 oss 上的存储路径
|
||||
if order_id is not None:
|
||||
tempURL = "https://mp.gray.api.suwa3d.com/api/order/getOssSuffixByOrderId?order_id="+str(order_id)
|
||||
res = requests.get(tempURL)
|
||||
resCode = res.json()['code']
|
||||
if int(resCode) != 1000:
|
||||
return -1
|
||||
print(res.text)
|
||||
if res.json()['data'] != "":
|
||||
prefix = f'objs/print/{pid}/{res.json()["data"]}/{order_id}'
|
||||
|
||||
print(f"prefix ======= {prefix}")
|
||||
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
|
||||
|
||||
|
||||
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"))
|
||||
#重命名文件
|
||||
|
||||
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 make3d4print_task(r):
|
||||
try:
|
||||
if r.llen('model:noresize') == 0:
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), '暂无可处理的数据')
|
||||
time.sleep(5)
|
||||
except Exception as e:
|
||||
time.sleep(5)
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), 'redis连接异常,重新连接')
|
||||
r = redis.Redis(host='106.14.158.208', password='kcV2000', port=6379, db=6)
|
||||
return
|
||||
orderId = r.lpop('model:noresize')
|
||||
if orderId is None: return
|
||||
|
||||
# arrOrder = orderIdStr.decode('utf-8').split('_')
|
||||
# orderId = arrOrder[0]
|
||||
# size = arrOrder[1]
|
||||
|
||||
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
|
||||
|
||||
down_obj_fromoss(pid, 1, orderId,download_flag="print_build")
|
||||
|
||||
|
||||
path = os.path.join(workdir, 'print', f'{pid}_{orderId}')
|
||||
|
||||
#获取打印尺寸信息
|
||||
get_printsize_url = 'https://mp.gray.api.suwa3d.com/api/printOrder/infoByOrderId'
|
||||
res = requests.get(f'{get_printsize_url}?id={orderId}')
|
||||
print('获取打印尺寸:', res.text)
|
||||
objName = ""
|
||||
for f in res.json()['data']['fileList']:
|
||||
if "undefined" in f:
|
||||
continue
|
||||
try:
|
||||
objName = f
|
||||
break
|
||||
except Exception as e:
|
||||
print("eeee",e)
|
||||
return
|
||||
|
||||
print("obj尺寸名称",objName)
|
||||
|
||||
|
||||
# 如果指定文件夹目标文件存在,则先删除
|
||||
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}/'))
|
||||
#判断是否是 Obj, 如果是的话要进行重命名
|
||||
if file.endswith(f'{pid}.obj'):
|
||||
os.rename(os.path.join(workdir, f'complate/objs/{pid}/order_{orderId}/{file}'), os.path.join(workdir, f'complate/objs/{pid}/order_{orderId}/{objName}'))
|
||||
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')
|
||||
#生成封面图片
|
||||
print('小票封面图处理中....')
|
||||
get_preview_image.createImage(pid)
|
||||
#os.system(f'python get_preview_image.py {pid}')
|
||||
print(f"{pid}-已处理结束")
|
||||
|
||||
|
||||
|
||||
|
||||
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.gray.api.suwa3d.com/api/customerP3dLog/updateStatusToWaitingPlatformCheckingStatus'
|
||||
update_team_check_url = 'https://mp.gray.api.suwa3d.com/api/customerP3dLog/updateStatusToWaitingTeamCheckingStatus'
|
||||
update_status_printstatus_url = 'https://mp.gray.api.suwa3d.com/api/customerP3dLog/updateBuildPrintModelStatus'
|
||||
update_makeprintobj_status_url = 'https://mp.gray.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/'
|
||||
|
||||
r = create_redis_connection()
|
||||
#E:\\complate/objs/147852_54579/
|
||||
# os.remove(os.path.join(workdir, f'complate/objs/147852_54579/'))
|
||||
main(r)
|
||||
+53
-6
@@ -123,10 +123,37 @@ def down_obj_fromoss(pid, print_type=1, order_id=None,download_flag="print_build
|
||||
os.rename(localfile, os.path.join(path,f"{pid}Tex1.jpg"))
|
||||
#重命名文件
|
||||
|
||||
|
||||
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 make3d4print_task(orderId):
|
||||
def make3d4print_task(r):
|
||||
try:
|
||||
if r.llen('model:noresize') == 0:
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), '暂无可处理的数据')
|
||||
time.sleep(5)
|
||||
except Exception as e:
|
||||
time.sleep(5)
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), 'redis连接异常,重新连接')
|
||||
r = redis.Redis(host='106.14.158.208', password='kcV2000', port=6379, db=6)
|
||||
return
|
||||
orderId = r.lpop('model:noresize')
|
||||
if orderId is None: return
|
||||
|
||||
# arrOrder = orderIdStr.decode('utf-8').split('_')
|
||||
# orderId = arrOrder[0]
|
||||
# size = arrOrder[1]
|
||||
|
||||
if type(orderId) != str:
|
||||
orderId = orderId.decode('utf-8')
|
||||
# orderId = 56077
|
||||
res = getPidFromOrderId(orderId)
|
||||
if res == -1:
|
||||
print("查询打印订单信息失败,重新开启进程")
|
||||
@@ -138,10 +165,27 @@ def make3d4print_task(orderId):
|
||||
if pid == "":
|
||||
return
|
||||
|
||||
down_obj_fromoss(pid, print_type, orderId,download_flag="print_build")
|
||||
down_obj_fromoss(pid, 1, orderId,download_flag="print_build")
|
||||
|
||||
|
||||
path = os.path.join(workdir, 'print', f'{pid}_{orderId}')
|
||||
|
||||
#获取打印尺寸信息
|
||||
get_printsize_url = 'https://mp.api.suwa3d.com/api/printOrder/info'
|
||||
res = requests.get(f'{get_printsize_url}?id={orderId}')
|
||||
print('获取打印尺寸:', res.text)
|
||||
objName = ""
|
||||
for f in res.json()['data']['fileList']:
|
||||
if "undefined" in f:
|
||||
continue
|
||||
try:
|
||||
objName = f
|
||||
break
|
||||
except Exception as e:
|
||||
print("eeee",e)
|
||||
return
|
||||
|
||||
print("obj尺寸名称",objName)
|
||||
|
||||
|
||||
# 如果指定文件夹目标文件存在,则先删除
|
||||
@@ -150,8 +194,8 @@ def make3d4print_task(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 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}/')):
|
||||
@@ -161,6 +205,10 @@ def make3d4print_task(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}/'))
|
||||
#判断是否是 Obj, 如果是的话要进行重命名
|
||||
if file.endswith(f'{pid}.obj'):
|
||||
os.rename(os.path.join(workdir, f'complate/objs/{pid}/order_{orderId}/{file}'), os.path.join(workdir, f'complate/objs/{pid}/order_{orderId}/{objName}'))
|
||||
print("重命名成功")
|
||||
|
||||
|
||||
|
||||
@@ -194,7 +242,6 @@ if __name__ == '__main__':
|
||||
workdir = 'E:\\'
|
||||
else:
|
||||
workdir = '/data/datasets/'
|
||||
blenderbin = find_blender_bin_path()
|
||||
|
||||
r = create_redis_connection()
|
||||
#E:\\complate/objs/147852_54579/
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
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 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):
|
||||
while True:
|
||||
try:
|
||||
#构建打印文件
|
||||
make3d4print_task(r)
|
||||
except Exception as e:
|
||||
print(f'出现异常:{e}')
|
||||
time.sleep(15)
|
||||
r = create_redis_connection()
|
||||
continue
|
||||
|
||||
#根据pid获取orderId
|
||||
def getPidFromOrderId(orderId):
|
||||
getPidFromOrderId_url = 'https://mp.api.suwa3d.com/api/printOrder/infoByOrderId'
|
||||
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 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}')
|
||||
|
||||
if not os.path.exists(path): os.makedirs(path)
|
||||
|
||||
# 根据前缀获取文件列表
|
||||
prefix = f'objs/print/{pid}/'
|
||||
#根据order_id 获取文件在 oss 上的存储路径
|
||||
if order_id is not None:
|
||||
tempURL = "https://mp.api.suwa3d.com/api/order/getOssSuffixByOrderId?order_id="+str(order_id)
|
||||
res = requests.get(tempURL)
|
||||
resCode = res.json()['code']
|
||||
if int(resCode) != 1000:
|
||||
return -1
|
||||
print(res.text)
|
||||
if res.json()['data'] != "":
|
||||
prefix = f'objs/print/{pid}/{res.json()["data"]}/{order_id}'
|
||||
|
||||
print(f"prefix ======= {prefix}")
|
||||
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
|
||||
|
||||
|
||||
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"))
|
||||
#重命名文件
|
||||
|
||||
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 make3d4print_task(r):
|
||||
try:
|
||||
if r.llen('model:noresize') == 0:
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), '暂无可处理的数据')
|
||||
time.sleep(5)
|
||||
except Exception as e:
|
||||
time.sleep(5)
|
||||
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), 'redis连接异常,重新连接')
|
||||
r = redis.Redis(host='106.14.158.208', password='kcV2000', port=6379, db=6)
|
||||
return
|
||||
orderId = r.lpop('model:noresize')
|
||||
if orderId is None: return
|
||||
|
||||
# arrOrder = orderIdStr.decode('utf-8').split('_')
|
||||
# orderId = arrOrder[0]
|
||||
# size = arrOrder[1]
|
||||
|
||||
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
|
||||
|
||||
down_obj_fromoss(pid, 1, orderId,download_flag="print_build")
|
||||
|
||||
|
||||
path = os.path.join(workdir, 'print', f'{pid}_{orderId}')
|
||||
|
||||
#获取打印尺寸信息
|
||||
get_printsize_url = 'https://mp.api.suwa3d.com/api/printOrder/infoByOrderId'
|
||||
res = requests.get(f'{get_printsize_url}?id={orderId}')
|
||||
print('获取打印尺寸:', res.text)
|
||||
objName = ""
|
||||
for f in res.json()['data']['fileList']:
|
||||
if "undefined" in f:
|
||||
continue
|
||||
try:
|
||||
objName = f
|
||||
break
|
||||
except Exception as e:
|
||||
print("eeee",e)
|
||||
return
|
||||
|
||||
print("obj尺寸名称",objName)
|
||||
|
||||
|
||||
# 如果指定文件夹目标文件存在,则先删除
|
||||
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}/'))
|
||||
#判断是否是 Obj, 如果是的话要进行重命名
|
||||
try:
|
||||
if file.endswith(f'{pid}.obj'):
|
||||
os.rename(os.path.join(workdir, f'complate/objs/{pid}/order_{orderId}/{file}'), os.path.join(workdir, f'complate/objs/{pid}/order_{orderId}/{objName}'))
|
||||
print("重命名成功")
|
||||
except Exception as e:
|
||||
print("AAAAAAAAAAAAAAAA",e)
|
||||
|
||||
|
||||
print("BBBBBBBBBBBB")
|
||||
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')
|
||||
#生成封面图片
|
||||
print('小票封面图处理中....')
|
||||
get_preview_image.createImage(pid)
|
||||
#os.system(f'python get_preview_image.py {pid}')
|
||||
print(f"{pid}-已处理结束")
|
||||
|
||||
|
||||
|
||||
|
||||
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/'
|
||||
|
||||
r = create_redis_connection()
|
||||
#E:\\complate/objs/147852_54579/
|
||||
# os.remove(os.path.join(workdir, f'complate/objs/147852_54579/'))
|
||||
main(r)
|
||||
Reference in new issue
Block a user