建模程序 多个定时程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

637 lines
28 KiB

import os, sys, bpy, math, time, platform, cairosvg, ppf.datamatrix, shutil, requests, json, redis, oss2, cv2,qrcode
from retrying import retry
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('e:\\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 gen_data_matrix(print_id,pid, qr_path, size = 300):
psid = getPSid(pid)
if int(psid) == 9:
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)
# 下载分2种情况,一种是第一次打印,下载标准{pid}.obj,{pid}.mtl,{pid}Tex1.jpg,另一种是重打或加打,obj文件名可以从oss上任意获取一个,但是mtl和jpg文件名是固定的
res = oss_client.get_object_to_file(f'objs/print/{pid}/{pid}.mtl', os.path.join(path, f'{pid}.mtl'))
last_modified = oss_client.get_object_meta(f"objs/print/{pid}/{pid}.mtl").last_modified
print(f'mtl文件最后修改时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(last_modified))}')
print(f'下载文件:objs/print/{pid}/{pid}.mtl,状态:{res.status}')
if oss_client.object_exists(f'objs/print/{pid}/{pid}Tex1.jpg'):
res = oss_client.get_object_to_file(f'objs/print/{pid}/{pid}Tex1.jpg', os.path.join(path, f'{pid}Tex1.jpg'))
last_modified = oss_client.get_object_meta(f"objs/print/{pid}/{pid}Tex1.jpg").last_modified
print(f'jpg文件最后修改时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(last_modified))}')
print(f'下载文件:objs/print/{pid}/{pid}Tex1.jpg,状态:{res.status}')
else:
res = oss_client.get_object_to_file(f'objs/print/{pid}/{pid}.jpg', os.path.join(path, f'{pid}Tex1.jpg'))
last_modified = oss_client.get_object_meta(f"objs/print/{pid}/{pid}.jpg").last_modified
print(f'jpg文件最后修改时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(last_modified))}')
print(f'下载文件:objs/print/{pid}/{pid}.jpg,状态:{res.status}')
if oss_client.object_exists(f'objs/print/{pid}/{pid}.obj'):
res = oss_client.get_object_to_file(f'objs/print/{pid}/{pid}.obj', os.path.join(path, f'{pid}.obj'))
last_modified = oss_client.get_object_meta(f"objs/print/{pid}/{pid}.obj").last_modified
print(f'obj文件最后修改时间:{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(last_modified))}')
print(f'下载文件:objs/print/{pid}/{pid}.obj,状态:{res.status}')
else:
prefix = f'objs/print/{pid}/'
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 not os.path.exists(os.path.join(workdir, f'{pid}_{order_id}', f'{pid}.mtl')):
# 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
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 main(workdir, r, print_id):
print('脚底板二维码程序开始运行...')
only_one = False
while True:
if print_id == '0':
try:
if r.llen('model:foot') == 0:
# print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), '队列为空,5秒后重试')
time.sleep(5)
continue
except Exception as e:
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), 'redis连接异常,5秒后重试')
print(e)
time.sleep(5)
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)
continue
# 打印队列里面的全部内容
print(f'当前model:foot队列长度:{r.llen("model:foot")}')
for i in r.lrange('model:foot', 0, -1):
print(i)
print_id = r.lpop('model:foot')
if print_id is None:
print_id = '0'
continue
#判断是否存在相同的值
isHaveAlready = 0
for i in r.lrange('model:foot', 0, -1):
if i == print_id:
isHaveAlready = 1
if isHaveAlready == 1:
print_id = '0'
continue
print_id = print_id.decode('utf-8')
else:
print(f'接收到运行一个{print_id}任务')
only_one = True
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:
print("获取打印任务信息有问题,重新任务队列,打印id-",print_id,"重新执行脚底板任务,等待20s")
time.sleep(20)
#将pid 重新扔进队列
r.lpush("model:foot", print_id)
#重新调用脚底板程序
#os.system(f'blender -b -P fill_dm_code.py')
continue
use_foot_type = json.loads(res.text)['data']['use_foot_type']
pid = json.loads(res.text)['data']['pid']
order_id = json.loads(res.text)['data']['order_id']
filename = os.path.join(workdir, f'{pid}_{order_id}', find_obj(pid, order_id))
print('导入obj文件:', filename)
if only_one:
print(f'接收到运行一个{print_id}任务,强制调用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('从云端获取的qr_position1:', res.text)
qr_position = json.loads(res.text)['data']['position_data']
else:
#从云端获取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_position2:', res.text)
qr_position = json.loads(res.text)['data']['position_data']
print("云端获取的坐标数据",qr_position)
if qr_position == '':
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('从云端获取的qr_position3:', res.text)
qr_position = json.loads(res.text)['data']['position_data']
else:
qr_position = json.loads(qr_position)
#如果获取的坐标为空,
if qr_position == "":
print("获取坐标为空问题,重新推入任务队列,打印id-",print_id,"重新执行脚底板任务,等待20s")
# time.sleep(20)
#将pid 重新扔进队列
r.lpush("model:foot", print_id)
#重新调用脚底板程序
#os.system(f'blender -b -P fill_dm_code.py')
# continueprint("获取打印任务信息有问题,重新任务队列,打印id-",print_id,"重新执行脚底板任务,等待20s")
time.sleep(20)
#将pid 重新扔进队列
# r.lpush("model:foot", print_id)
#重新调用脚底板程序
#os.system(f'blender -b -P fill_dm_code.py')
continue
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)
# 导入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)
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_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_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)
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()
# 删除临时文件
shutil.rmtree(os.path.join(workdir, f'{pid}_{order_id}'))
if only_one:
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 运行{print_id}任务完成,退出程序')
break
else:
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 运行{print_id}任务完成,继续运行下一个任务')
print_id = '0'
continue
#根据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):
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)
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 = 'd:\\print\\foot\\'
else:
workdir = '/data/datasets/foot/'
print("Usage: blender -b -P fill_dm_code.py")
if len(sys.argv) == 5:
print_ids = sys.argv[-1]
else:
print_ids = '0'
for print_id in print_ids.split(','):
main(workdir, r, print_id)