Browse Source

程序优化

master
dongchangxi 2 years ago
parent
commit
e1a7647fcb
  1. 14
      config/exportRegistration.xml
  2. 169
      libs/common.py
  3. 149
      libs/foot_mark_seam.py
  4. 46
      libs/libs.py
  5. 26
      libs/libs_db.py
  6. 5
      libs/main_service_db.py
  7. 12
      logic/logic_main_service.py
  8. 5
      main_service.py
  9. 5
      main_step1.py
  10. 73
      main_step2.py
  11. 8
      main_step3.py
  12. 35
      manual_service.py
  13. 147
      manual_single.py
  14. 20
      timer/get_task_to_db.py
  15. 4
      tools/push_cmd.py
  16. 3
      建模碎片步骤.txt

14
config/exportRegistration.xml

@ -0,0 +1,14 @@
<Configuration id="{2D5793BC-A65D-4318-A1B9-A05044608385}">
<entry key="MvsExportIsGeoreferenced" value="0x0"/>
<entry key="MvsExportMoveX" value="0.0"/>
<entry key="MvsExportMoveY" value="0.0"/>
<entry key="MvsExportMoveZ" value="0.0"/>
<entry key="MvsExportScaleX" value="1.0"/>
<entry key="calexFileFormat" value="Internal/External camera parameters"/>
<entry key="calexExportSettingsVisible" value="1"/>
<entry key="MvsExportScaleY" value="1.0"/>
<entry key="calexHasDisabled" value="0x0"/>
<entry key="MvsExportScaleZ" value="1.0"/>
<entry key="calexHasUndistort" value="0x0"/>
<entry key="MvsExportIsModelCoordinates" value="0"/>
</Configuration>

169
libs/common.py

@ -1,5 +1,8 @@
import redis,sys,os,re,oss2,shutil,time import redis,sys,os,re,oss2,shutil,time,cv2
import json
import requests
import platform import platform
import numpy as np
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from PIL import ImageGrab from PIL import ImageGrab
if platform.system() == 'Windows': if platform.system() == 'Windows':
@ -222,14 +225,14 @@ def uploadControlPointsOss(pid):
#截屏保存 #截屏保存
def saveScreenImg(pid): def saveScreenImg(pid):
#获取当前的日志 #获取当前的日志
if not os.path.exists(os.path.join(config.workdir,"screen", time.strftime("%y%m%d" time.localtime()))): if not os.path.exists(os.path.join(config.workdir,"screen", time.strftime("%y%m%d",time.localtime()))):
os.makedirs(os.path.join(config.workdir,"screen", time.strftime("%y%m%d" time.localtime()))) os.makedirs(os.path.join(config.workdir,"screen", time.strftime("%y%m%d",time.localtime())))
screenshot = ImageGrab .grab() screenshot = ImageGrab .grab()
screenshot.save(os.path.join(config.workdir,"screen", time.strftime("%y%m%d" time.localtime())),str(pid)+".png") screenshot.save(os.path.join(config.workdir,"screen", time.strftime("%y%m%d",time.localtime()))+"/"+str(pid)+".png")
#移动到e盘 #移动到e盘
if not os.path.exists(os.path.join(config.sharedir,"screen", time.strftime("%y%m%d" time.localtime()))): if not os.path.exists(os.path.join(config.sharedir,"screen", time.strftime("%y%m%d",time.localtime()))):
os.makedirs(os.path.join(config.sharedir,"screen", time.strftime("%y%m%d" time.localtime()))) os.makedirs(os.path.join(config.sharedir,"screen", time.strftime("%y%m%d",time.localtime())))
shutil.copytree(os.path.join(config.workdir,"screen", time.strftime("%y%m%d" time.localtime())), os.path.join(config.sharedir,"screen", time.strftime("%y%m%d" time.localtime()))) shutil.copy(os.path.join(config.workdir,"screen", time.strftime("%y%m%d",time.localtime()))+"\\"+str(pid)+".png", os.path.join(config.sharedir,"screen", time.strftime("%y%m%d",time.localtime())))
#文件夹的移动和删除 #文件夹的移动和删除
@ -248,3 +251,155 @@ def removeFolder(pid):
now_time = time.time() now_time = time.time()
if (now_time - file_time) > 259200: if (now_time - file_time) > 259200:
shutil.rmtree(os.path.join(config.workdir, 'finished', file), ignore_errors=True) shutil.rmtree(os.path.join(config.workdir, 'finished', file), ignore_errors=True)
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 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 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 remove_gray_and_sharpening(jpg_path):
#low_y_limit = 25000
high_y_limit = 13000
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, 1000)
high_x_thresh, high_y_frequency = high_find_histogram_range(input_image, high_y_limit)
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)
cv2.imwrite(jpg_path, high_output_image, [cv2.IMWRITE_JPEG_QUALITY, 95]) # 保存图片的质量是原图的 95%
#读取指定路径判断是否对齐成功
def isAlignNums(strPid):
#拼接路径
csvPath = os.path.join(config.workdir, strPid, strPid+"_align.csv")
print(csvPath)
#判断文件是否存在
if os.path.exists(csvPath) == False:
return "rebuild"
#读取文件行数
lines = ""
with open(csvPath, 'r') as f:
lines = f.readlines()
#获取长度
lines = len(lines) - 1
#获取pid对应的 photo1 和 photo2 的数量
photo1Num = 0
photo2Num = 0
for file in os.listdir(os.path.join(config.workdir, strPid, 'photo1')):
if file.endswith('.jpg'):
photo1Num += 1
for file in os.listdir(os.path.join(config.workdir, strPid, 'photo2')):
if file.endswith('.jpg'):
photo2Num += 1
#获取图片总数
totalPhotos = photo1Num + photo2Num
#比对对齐数量
if totalPhotos - lines >= 4:
return "rebuild"
return True
#消息通知
def notify(content):
if content == "":
return "content 不能为空"
for user_agent_id in config.notify_user_Ids:
data = {
'userId': user_agent_id,
'message': content,
}
headers = {'Content-Type': 'application/json'}
message_send_url = "https://mp.api.suwa3d.com/api/qyNotify/sendMessage?userId="+user_agent_id+"&message="+content
response = requests.post(message_send_url, data=json.dumps(data), headers=headers)

149
libs/foot_mark_seam.py

@ -0,0 +1,149 @@
import bpy
import bmesh
def active_object(obj):
bpy.context.view_layer.objects.active = obj
obj.select_set(True)
def get_obj_max_foot(workdir,filename,filename_tex):
# 1.模型导入和初始化
# 删除当前场景中的所有对象:
# use_global=False表示只删除当前场景中的对象,而不会影响到其他场景中的对象;confirm=False表示删除时不需要确认。
bpy.ops.object.delete(use_global=False, confirm=False)
bpy.ops.import_scene.obj(filepath=filename) # 导入指定路径的 OBJ 格式模型文件
bpy.context.scene.unit_settings.scale_length = 0.001 # 将场景的长度单位缩放为0.001,相当于将长度单位从默认的米缩小为毫米
bpy.context.scene.unit_settings.length_unit = 'CENTIMETERS' # 将场景的长度单位设置为厘米
bpy.context.scene.unit_settings.mass_unit = 'GRAMS' # 将场景的质量单位设置为克
obj = bpy.context.selected_objects[0] # 获取了当前选中的对象列表,然后通过 [0] 取得列表中的第一个对象
bpy.context.view_layer.objects.active = obj # 将变量 obj 设置为当前活动对象
obj.select_set(True) # 将变量 obj 的选择状态设置为 True,表示选中该对象
pid = obj.name # 获取该对象的名字
# 对选定的对象进行对齐操作
bpy.ops.object.align(align_mode='OPT_1', relative_to='OPT_1', align_axis={'Z'})
# 设置选中对象的原点,参数1:将原点设置为对象的质心,参数2:使用对象的几何中心作为参考
bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS', center='MEDIAN')
# 将选中对象的位置坐标分别设置为 (0, 0),即将对象移动到世界坐标系的原点位置
obj.location[0] = 0
obj.location[1] = 0
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) # 将选中对象的位置、旋转和缩放应用到对象的数据中
# 2.选择要复制的对象
obj_duplicate = obj.copy()
obj_duplicate.data = obj.data.copy()
bpy.context.collection.objects.link(obj_duplicate)
# obj_duplicate.location.x += 5.0
bpy.ops.object.select_all(action='DESELECT') # 取消选中全部对象
# 3.处理复制的对象的脚底缝合边
# 选中复制对象
bpy.context.view_layer.objects.active = obj_duplicate
obj_duplicate.select_set(True)
selected_obj = bpy.context.active_object # 获取当前选中的对象
bpy.context.view_layer.objects.active = selected_obj # 将对象转换到编辑模式
# 切换到3D视图编辑模式
bpy.context.area.type = 'VIEW_3D'
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT') # 选择所有的边
# 切换到UV编辑器
bpy.context.area.type = 'IMAGE_EDITOR'
pid_img = f"{pid}Tex1.jpg"
bpy.ops.image.open(filepath=filename_tex, directory=workdir,
files=[{"name": pid_img, "name": pid_img}], relative_path=True,
show_multiview=False)
bpy.context.area.ui_type = 'UV'
bpy.ops.uv.select_all(action='SELECT') # 选择所有UV贴图顶点
# 标记所有沿孤岛的边为缝合边
bpy.ops.uv.seams_from_islands()
bpy.context.area.type = 'VIEW_3D'
bpy.ops.object.mode_set(mode='OBJECT')
# 获取世界坐标系下z轴接近0的顶点的索引
z_zero_vertex_indices = []
for i, vertex in enumerate(selected_obj.data.vertices):
world_vertex = selected_obj.matrix_world @ vertex.co
if abs(world_vertex.z) < 0.2:
z_zero_vertex_indices.append(i)
# 将对象转换回对象模式
bpy.ops.object.mode_set(mode='OBJECT')
# 创建一个新的顶点组,并将z_zero_vertices中的顶点添加到该顶点组中
vg = selected_obj.vertex_groups.new(name="z_zero_vertices")
for index in z_zero_vertex_indices:
vg.add([index], 1.0, 'REPLACE')
# 将选中的顶点设置为活动顶点
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='DESELECT')
bpy.ops.object.vertex_group_select() # 选中待处理的顶点
bpy.ops.mesh.mark_seam(clear=True) # 取消所选区域内的缝合边
bpy.ops.mesh.region_to_loop() # 选择选定面周围的边界边!!!
bpy.ops.mesh.select_mode(type="EDGE") # 转换为线模式
bpy.ops.mesh.mark_seam(clear=False) # 标记所选的线为缝合边
# 选中脚底顶点组
bpy.ops.uv.select_all(action='DESELECT')
bpy.ops.object.vertex_group_set_active(group='z_zero_vertices') # 设置活动顶点组
bpy.ops.object.vertex_group_select() # 选择分配给活动顶点组的所有顶点
bpy.ops.uv.unwrap()
# 处理贴图脚底部分孤岛,其他孤岛保持不变
# (1)反选模型顶点,方便贴图固定不需要处理的区域
bpy.ops.mesh.select_all(action='INVERT')
bpy.context.area.type = 'IMAGE_EDITOR' # 切换到贴图模式
bpy.context.area.ui_type = 'UV'
bpy.ops.uv.pin(clear=False)
bpy.ops.object.vertex_group_set_active(group='z_zero_vertices') # 设置活动顶点组
bpy.ops.object.vertex_group_select() # 选择分配给活动顶点组的所有顶点
# (2)脚底部位UV展开,平均孤岛比例,重新排列孤岛
bpy.ops.uv.select_all(action='SELECT')
bpy.ops.uv.average_islands_scale()
bpy.ops.uv.pack_islands(margin=0.001)
bpy.context.area.type = 'VIEW_3D'
bpy.ops.object.mode_set(mode='OBJECT')
# 4. 烘焙模式,参数设置
bpy.ops.object.select_all(action='DESELECT') # 取消选中全部对象
# # 选中原始对象
bpy.context.view_layer.objects.active = obj
obj.select_set(True)
# 选中复制对象
bpy.context.view_layer.objects.active = obj_duplicate
obj_duplicate.select_set(True)
bpy.context.scene.render.engine = 'CYCLES'
bpy.context.scene.cycles.device = 'GPU'
bpy.context.scene.cycles.preview_samples = 1
bpy.context.scene.cycles.samples = 1
bpy.context.scene.cycles.bake_type = 'DIFFUSE'
bpy.context.scene.render.bake.use_pass_direct = False
bpy.context.scene.render.bake.use_pass_indirect = False
bpy.context.scene.render.bake.use_selected_to_active = True
bpy.context.scene.render.bake.cage_extrusion = 0.01
bpy.ops.object.bake(type='DIFFUSE') # 开始 Bake
# 5. 导出模型和贴图
bpy.ops.object.select_all(action='DESELECT') # 取消选中全部对象
# 选中复制对象
bpy.context.view_layer.objects.active = obj_duplicate
obj_duplicate.select_set(True)
bpy.ops.wm.obj_export(filepath=filename, export_selected_objects=True)
bpy.context.area.type = 'IMAGE_EDITOR' # 切换到
bpy.ops.image.save_as(filepath=filename_tex)
bpy.context.area.type = 'TEXT_EDITOR' # 切换到文本编辑器
if __name__ == '__main__':
workdir = 'E:\\117080\\print_model'
# filename = f'{workdir}\\117080_12cm_x1.obj'
filename = f'{workdir}\\117080.obj'
filename_tex = f'{workdir}\\117080Tex1.jpg'
save_obj = f"{workdir}\\bake\\117080Tex1.obj"
save_tex = f"{workdir}\\bake\\117080Tex1.jpg"
get_obj_max_foot()

46
libs/libs.py

@ -1,7 +1,9 @@
import os, time, json, requests, shutil, oss2, psutil import os, time, json, requests, shutil, oss2, psutil
from tqdm import tqdm from tqdm import tqdm
from PIL import Image, ImageEnhance from PIL import Image, ImageEnhance
import config,libs_db import config,libs_db,common
import threading
from concurrent.futures import ThreadPoolExecutor
def find_blender_bin_path(): def find_blender_bin_path():
base_path = 'C:\\Program Files\\Blender Foundation\\' base_path = 'C:\\Program Files\\Blender Foundation\\'
@ -222,7 +224,7 @@ def set_photo_join_type(workdir, pid, photoN, camera_id, mesh = '0', texture='0'
with open(filename, 'w') as f: with open(filename, 'w') as f:
f.writelines(lines) f.writelines(lines)
def down_from_oss(oss_client, workdir, pid, per=100): def down_from_oss(oss_client, workdir, pid, per=100,photoPath=""):
start_time = time.time() start_time = time.time()
path = os.path.join(workdir, pid) path = os.path.join(workdir, pid)
if os.path.exists(path): if os.path.exists(path):
@ -237,20 +239,52 @@ def down_from_oss(oss_client, workdir, pid, per=100):
filelist = oss2.ObjectIteratorV2(oss_client, prefix=prefix) filelist = oss2.ObjectIteratorV2(oss_client, prefix=prefix)
for file in tqdm(filelist): for file in tqdm(filelist):
filename = file.key.split('/')[-1] filename = file.key.split('/')[-1]
localfile = ""
# print('正在下载:', file.key) # print('正在下载:', file.key)
if filename.endswith('_1.jpg'): if photoPath == "":
localfile = os.path.join(path, 'photo1', filename) if filename.endswith('_1.jpg'):
localfile = os.path.join(path, 'photo1', filename)
else:
localfile = os.path.join(path, 'photo2', filename)
else: else:
localfile = os.path.join(path, 'photo2', filename) if photoPath=="1":
if filename.endswith('_1.jpg'):
localfile = os.path.join(path, 'photo1', filename)
else:
if filename.endswith('_8.jpg'):
localfile = os.path.join(path, 'photo2', filename)
if localfile == "":
continue
style = f'image/resize,p_{per}' style = f'image/resize,p_{per}'
if per == 100: if per == 100:
oss_client.get_object_to_file(file.key, localfile) oss_client.get_object_to_file(file.key, localfile)
else: else:
oss_client.get_object_to_file(file.key, localfile, process=style) oss_client.get_object_to_file(file.key, localfile, process=style)
#判断localfile 是否有包含 photo2
#遍历处理photo2的数数据
# if str(psid) == "96" or str(pid) == "118994":
# path = os.path.join(workdir, pid, 'photo2')
# files = []
# for fileName in os.listdir(path):
# if ".jpg" in fileName:
# files.append(path+"\\"+fileName)
# beginTime = time.time()
# with ThreadPoolExecutor(max_workers=6) as executor:
# executor.map(process_image, files)
# print(f'{localfile}灰度处理费时{diff_time(beginTime)}')
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 图片下载完成, 共费时{diff_time(start_time)}') print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 图片下载完成, 共费时{diff_time(start_time)}')
#灰度处理图片
def process_image(localfile):
if ".jpg" in localfile:
common.remove_gray_and_sharpening(localfile)
def get_defineDistances(psid): def get_defineDistances(psid):
res = '' res = ''
distances = libs_db.get_floor_sticker_distances(psid).split(';') distances = libs_db.get_floor_sticker_distances(psid).split(';')

26
libs/libs_db.py

@ -17,8 +17,7 @@ def get_task(task_type):
try: try:
with pymysqlAlias() as conn: with pymysqlAlias() as conn:
cursor = conn.cursor() cursor = conn.cursor()
sql = f'select task_key from tasks where status = 0 order by priority desc, id asc limit 1 for update'
sql = f'select task_key from tasks where status = 0 order by priority desc, id asc limit 1'
# print(f'sql: {sql}') # print(f'sql: {sql}')
cursor.execute(sql) cursor.execute(sql)
data = cursor.fetchone() data = cursor.fetchone()
@ -49,6 +48,9 @@ def add_task(data):
#新增任务到分布式处理任务表中 {"task_type":key,"task_key":pid,"psid":psid} #新增任务到分布式处理任务表中 {"task_type":key,"task_key":pid,"psid":psid}
def add_task_distributed(data): def add_task_distributed(data):
flag = isInTaskDistributed(data["task_key"])
if flag:
return "already"
try: try:
with pymysqlAlias() as conn: with pymysqlAlias() as conn:
cursor = conn.cursor() cursor = conn.cursor()
@ -66,8 +68,8 @@ def start_task(data):
cursor = conn.cursor() cursor = conn.cursor()
hostname = socket.gethostname() hostname = socket.gethostname()
sql = f'update tasks set status = 1, hostname = "{hostname}", started_at = now(), updated_at = now() where task_key = "{data["task_key"]} and status = 0"' sql = f'update tasks set status = 1, hostname = "{hostname}", started_at = now(), updated_at = now() where status = 0 and task_key = {data["task_key"]}'
# print(f'sql: {sql}') print(f'开始任务sql: {sql}')
cursor.execute(sql) cursor.execute(sql)
conn.commit() conn.commit()
except Exception as e: except Exception as e:
@ -159,3 +161,19 @@ def isStudioConfigDistribute(psid):
except Exception as e: except Exception as e:
print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行change_to_new_make_psid()异常: {str(e)}") print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行change_to_new_make_psid()异常: {str(e)}")
return "error" return "error"
#判断是否已经存在了
def isInTaskDistributed(task_key):
try:
with pymysqlAlias() as conn:
cursor = conn.cursor()
sql = f'select count(*) from task_distributed where status = 0 and task_key = "{task_key}"'
cursor.execute(sql)
result = cursor.fetchone()
if result[0] == 0:
return False
else:
return True
except Exception as e:
print(f"{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())} 执行isInTaskDistributed()异常: {str(e)}")
return "error"

5
libs/main_service_db.py

@ -192,10 +192,7 @@ def get_task_distributed_step1():
try: try:
with pymysqlAlias() as conn: with pymysqlAlias() as conn:
cursor = conn.cursor(pymysql.cursors.DictCursor) cursor = conn.cursor(pymysql.cursors.DictCursor)
sql = 'select * from task_distributed where status =0 order by priority desc limit 1' sql = 'select * from task_distributed where status =0 order by priority desc limit 1 for update'
if where:
sql += f' and {where}'
cursor.execute(sql) cursor.execute(sql)
result = cursor.fetchone() result = cursor.fetchone()
# 关闭游标和连接 # 关闭游标和连接

12
logic/logic_main_service.py

@ -43,9 +43,10 @@ def get_task_distributed():
return 'no_data' return 'no_data'
else: else:
#优先处理step1 和 step3 #优先处理step1 和 step3
resultData = main_service_db.get_task_distributed_step1()
#R11 R12的主机如果已经有在处理step2了,则不能再处理step2,只能处理step1 step3 #R11 R12的主机如果已经有在处理step2了,则不能再处理step2,只能处理step1 step3
resultData = need_run_step_no_step2() #resultData = need_run_step_no_step2()
if resultData == "no": if resultData is None:
#return "no" #return "no"
#R11 R12的主机 可以执行step1 2 3 的任务 #R11 R12的主机 可以执行step1 2 3 的任务
#如果R11 R12的主机目前没有正在执行step2,则优先处理step2, #如果R11 R12的主机目前没有正在执行step2,则优先处理step2,
@ -63,7 +64,8 @@ def get_task_distributed():
#没有任何可执行的 #没有任何可执行的
return "no" return "no"
resultData["hostname"] = hostname resultData = {"hostname":hostname,"run_step":"step1","task_distributed_id":resultData["id"],"task_key":resultData["task_key"]}
#resultData["hostname"] = hostname
flagRes = update_main_and_add_detail(resultData) flagRes = update_main_and_add_detail(resultData)
if flagRes == "error": if flagRes == "error":
print(f'出现错误,有可能是多个进程获取同一个任务了') print(f'出现错误,有可能是多个进程获取同一个任务了')
@ -213,8 +215,8 @@ def need_run_step_no_step1():
xstep = need_run_stepx(row["id"]) xstep = need_run_stepx(row["id"])
#print("查询非step1的任务列表",xstep,row["id"]) #print("查询非step1的任务列表",xstep,row["id"])
if xstep == "step2": if xstep == "step2":
if common.task_need_high_model_or_photo3(row["task_key"]) and hostname != "R11" and hostname != "R12": # if common.task_need_high_model_or_photo3(row["task_key"]) and hostname != "R11" and hostname != "R12":
continue # continue
#没有正在执行的step1,则返回该任务 #没有正在执行的step1,则返回该任务
return {"hostname":hostname,"run_step":xstep,"task_distributed_id":row["id"],"task_key":row["task_key"]} return {"hostname":hostname,"run_step":xstep,"task_distributed_id":row["id"],"task_key":row["task_key"]}
return "no" return "no"

5
main_service.py

@ -1,6 +1,6 @@
import sys,socket,time,platform import sys,socket,time,platform
from logic import logic_main_service from logic import logic_main_service
import logging import logging,atexit
import main_step1,main_step2,main_step3 import main_step1,main_step2,main_step3
if platform.system() == 'Windows': if platform.system() == 'Windows':
#线上正式运行 #线上正式运行
@ -8,8 +8,9 @@ if platform.system() == 'Windows':
#本地测试 #本地测试
else: else:
sys.path.append('/data/deploy/make3d/make2/libs/') sys.path.append('/data/deploy/make3d/make2/libs/')
import main_service_db,config import main_service_db,config,common
if __name__ == '__main__': if __name__ == '__main__':
atexit.register(common.notify,socket.gethostname()+"分布式建模任务已经停止")
if len(sys.argv) == 2: if len(sys.argv) == 2:
print(sys.argv[1]) print(sys.argv[1])
os.system(f'python main_step1.py {sys.argv[1]}') os.system(f'python main_step1.py {sys.argv[1]}')

5
main_step1.py

@ -1,12 +1,12 @@
import os, sys, time, shlex, subprocess, shutil, requests, cv2, numpy as np import os, sys, time, shlex, subprocess, shutil, requests, cv2, numpy as np
from PIL import Image from PIL import Image
import platform import platform,socket,atexit
if platform.system() == 'Windows': if platform.system() == 'Windows':
sys.path.append('e:\\libs\\') sys.path.append('e:\\libs\\')
#sys.path.append('libs') #sys.path.append('libs')
else: else:
sys.path.append('/data/deploy/make3d/make2/libs/') sys.path.append('/data/deploy/make3d/make2/libs/')
import config, libs, libs_db,main_service_db import config, libs, libs_db,main_service_db,common
def filter_dark_texture_image(pid): def filter_dark_texture_image(pid):
start_time = time.time() start_time = time.time()
@ -204,6 +204,7 @@ def main(pid, experience=False, makeloop=True,task_distributed_id="",isNoColorTe
if __name__ == '__main__': if __name__ == '__main__':
# 取云端redis任务,完成第一步的数据预处理后,将数据放入共享存储目录,将第二步任务塞入本地mysql队列 # 取云端redis任务,完成第一步的数据预处理后,将数据放入共享存储目录,将第二步任务塞入本地mysql队列
# 默认循环值守,可传参数运行单一任务,以方便调试 # 默认循环值守,可传参数运行单一任务,以方便调试
atexit.register(common.notify,socket.gethostname()+"建模任务已经停止")
pid = '0' pid = '0'
isNoColorTexture = "" isNoColorTexture = ""
if len(sys.argv) == 2: if len(sys.argv) == 2:

73
main_step2.py

@ -29,7 +29,7 @@ def make3d(pid):
# psid = libs.getPSid(pid) # psid = libs.getPSid(pid)
# if int(psid) == 80: # if int(psid) == 80:
# change_rcbox_deepth(str(pid),0.03) # change_rcbox_deepth(str(pid),0.03)
psid = libs.getPSid(pid)
simplify_value = 1000000 * libs.getHeadCount(pid) simplify_value = 1000000 * libs.getHeadCount(pid)
add_photo3 = ' ' add_photo3 = ' '
#判断是否存在photo3 #判断是否存在photo3
@ -64,48 +64,43 @@ def make3d(pid):
cmd = f'{config.rcbin} {config.r1["init"]} \ cmd = f'{config.rcbin} {config.r1["init"]} \
-addFolder "{os.path.join(config.workdir, pid, "photo1")}" -addFolder "{os.path.join(config.workdir, pid, "photo2")}" {add_photo3} \ -addFolder "{os.path.join(config.workdir, pid, "photo1")}" -addFolder "{os.path.join(config.workdir, pid, "photo2")}" {add_photo3} \
-importControlPointsMeasurements "{os.path.join(config.workdir, pid, f"{pid}.controlPoints.csv")}" \ -importControlPointsMeasurements "{os.path.join(config.workdir, pid, f"{pid}.controlPoints.csv")}" \
-align -save' -align -exportRegistration "{os.path.join(config.workdir,"make2", "config","exportRegistration.xml")}" "{os.path.join(config.workdir, pid,str(pid)+"_align.csv")}" -save'
#不存在point文件的时候就要用自动点击的方式 cmd = cmd + f' "{os.path.join(config.workdir, pid, f"{pid}_wait.rcproj")}"'
if isExistPoint == False:
cmd = cmd + f' "{os.path.join(config.workdir, pid, f"{pid}_wait.rcproj")}"'
else:
cmd = cmd + f' "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" -quit'
print(cmd) print(cmd)
cmd = shlex.split(cmd) cmd = shlex.split(cmd)
res = subprocess.run(cmd) res = subprocess.run(cmd)
time.sleep(2) time.sleep(2)
if isExistPoint == False:
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 定位点导入完成') print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 定位点导入完成')
time.sleep(3)
# defind_distance
#死循环阻塞获取
while True:
print("循环阻塞开始")
time.sleep(3) time.sleep(3)
# defind_distance #判断是否有 pid_1 的的值
#死循环阻塞获取 print(pid+"_1")
while True: if redisLocal.lpos('model:auto_distance',pid+"_1") == None:
print("循环阻塞开始") continue
time.sleep(3) shutil.move(os.path.join(config.workdir, pid, f'{pid}_wait.rcproj'), os.path.join(config.workdir, pid, f'{pid}.rcproj'))
#判断是否有 pid_1 的的值 print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 定义定位点距离完成')
print(pid+"_1") #将 controlpoints_0.dat 文件拷贝到 oss 上作为公共的使用
if redisLocal.lpos('model:auto_distance',pid+"_1") == None: common.uploadControlPointsOss(pid)
continue
shutil.move(os.path.join(config.workdir, pid, f'{pid}_wait.rcproj'), os.path.join(config.workdir, pid, f'{pid}.rcproj')) #最后处理掉redis中的值
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 定义定位点距离完成') redisLocal.lrem('model:auto_distance', 0, pid+"_1")
#将 controlpoints_0.dat 文件拷贝到 oss 上作为公共的使用 break
common.uploadControlPointsOss(pid) print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),"循环阻塞结束,判断是否对齐成功")
#最后处理掉redis中的值
redisLocal.lrem('model:auto_distance', 0, pid+"_1")
break
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),"循环阻塞结束,开始建模")
else:
#修改rcproj文件 controlpoints fileName 的引入
flag = common.changeRcprojControlpointsFile(pid)
if flag == False:
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 获取及修改controlpoints失败')
return
print("使用公共point文件的方式进行建模")
#查看对齐的数量
alignRes = common.isAlignNums(str(pid))
if alignRes == "rebuild":
os.system(f'python d:\\make2\\tools\push_cmd.py rebuild {pid}')
os.system(f'python d:\\make2\\main_service.py')
return
#区域的设置 建模 #区域的设置 建模
#update #update
cmdSmall = "-align" cmdSmall = "-align"
@ -115,7 +110,10 @@ def make3d(pid):
#{config.r1["init"]} #{config.r1["init"]}
if common.task_need_high_model(pid): if common.task_need_high_model(pid):
calulate_type = '-mvsHigh' if str(psid) == "41" or str(psid) == "85":
calulate_type = "-mvs"
else:
calulate_type = '-mvsHigh'
else: else:
calulate_type = '-mvs' calulate_type = '-mvs'
@ -164,7 +162,10 @@ def make3d(pid):
else: # new version else: # new version
#判断是否要进行高精模 #判断是否要进行高精模
if common.task_need_high_model(pid): if common.task_need_high_model(pid):
calulate_type = 'calculateHighModel' if str(psid) == "41" or str(psid) == "85":
calulate_type = "calculateNormalModel"
else:
calulate_type = 'calculateHighModel'
else: else:
calulate_type = 'calculateNormalModel' calulate_type = 'calculateNormalModel'

8
main_step3.py

@ -6,7 +6,7 @@ if platform.system() == 'Windows':
#sys.path.append('libs') #sys.path.append('libs')
else: else:
sys.path.append('/data/deploy/make3d/make2/libs/') sys.path.append('/data/deploy/make3d/make2/libs/')
import config, libs, libs_db,main_service_db,common import config, libs, libs_db,main_service_db,common,foot_mark_seam
def bmesh_copy_from_object(obj, transform=True, triangulate=True, apply_modifiers=False): def bmesh_copy_from_object(obj, transform=True, triangulate=True, apply_modifiers=False):
"""Returns a transformed, triangulated copy of the mesh""" """Returns a transformed, triangulated copy of the mesh"""
@ -89,6 +89,10 @@ def base_fix(pid):
bpy.context.object.location[1] = 0 bpy.context.object.location[1] = 0
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
#处理脚底UV
# basepath = os.path.join(config.workdir, pid, 'output')
# foot_mark_seam.get_obj_max_foot(basepath,os.path.join(basepath, f'{pid}.obj'),os.path.join(basepath, f'{pid}.jpg'))
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 模型基础校正完成,共费时{libs.diff_time(start_time)}') print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 模型基础校正完成,共费时{libs.diff_time(start_time)}')
def export_and_update_obj(pid): def export_and_update_obj(pid):
@ -153,7 +157,7 @@ def export_and_update_glbs(pid):
# f.close() # f.close()
# 先生成审核模型 # 先生成审核模型
faces_dest = 300000 * headcount faces_dest = 500000 * headcount
# 减面 # 减面
faces_current = len(bpy.data.objects[pid_objname].data.polygons) faces_current = len(bpy.data.objects[pid_objname].data.polygons)
print(f'当前面数:{faces_current},目标面数:{faces_dest}') print(f'当前面数:{faces_current},目标面数:{faces_dest}')

35
manual_service.py

@ -30,18 +30,21 @@ def check_pid_file(pid):
else: else:
shutil.rmtree(os.path.join(path, file)) shutil.rmtree(os.path.join(path, file))
#判断photo1 和 photo2 目录里的文件是否存在xmp 文件,存在的话就删除 #判断photo1 和 photo2 目录里的文件是否存在xmp 文件,存在的话就删除
for file in os.listdir(os.path.join(path, 'photo1')): for file in os.listdir(os.path.join(path, 'photo1')):
if not file.endswith('.xmp'): if file.endswith('.xmp'):
os.remove(os.path.join(path, 'photo1', file)) os.remove(os.path.join(path, 'photo1', file))
for file in os.listdir(os.path.join(path, 'photo2')): for file in os.listdir(os.path.join(path, 'photo2')):
if not file.endswith('.xmp'): if file.endswith('.xmp'):
os.remove(os.path.join(path, 'photo2', file)) os.remove(os.path.join(path, 'photo2', file))
#根据参数初始化操作 #根据参数初始化操作
def cmd_run(pid,usePhoto = "1",lock=False): def cmd_run(pid,usePhoto = "1",lock=False):
pid = str(pid)
#检测文件并且下载处理文件
check_pid_file(pid)
start_time = time.time() start_time = time.time()
#文件路径 #文件路径
@ -61,7 +64,7 @@ def cmd_run(pid,usePhoto = "1",lock=False):
usePhoto = "photo"+str(usePhoto) usePhoto = "photo"+str(usePhoto)
#执行命令 #执行命令
cmd = f'{config.rcbin} {config.r2["init"]} -setInstanceName {pid} \ cmd = f'{config.rcbin} {config.r2["init"]} -setInstanceName "{pid}" \
-save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" \ -save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" \
-addFolder "{os.path.join(config.workdir, pid, usePhoto)}" -selectAllImages \ -addFolder "{os.path.join(config.workdir, pid, usePhoto)}" -selectAllImages \
-detectMarkers "D:\\make2\\config\\detectMarkers.config.xml" \ -detectMarkers "D:\\make2\\config\\detectMarkers.config.xml" \
@ -81,20 +84,36 @@ def cmd_run(pid,usePhoto = "1",lock=False):
#复制xmp文件 #复制xmp文件
for xmp in os.listdir(sourceFile): for xmp in os.listdir(sourceFile):
if xmp.endswith('.xmp'): if xmp.endswith('.xmp'):
shutil.copy(os.path.join(sourceFile, xmp), os.path.join(targetFile,xmp)) if usePhoto == "photo1":
shutil.copy(os.path.join(sourceFile, xmp), os.path.join(targetFile,xmp.replace('_1.xmp', '_8.xmp')))
if usePhoto == "photo2":
shutil.copy(os.path.join(sourceFile, xmp), os.path.join(targetFile,xmp.replace('_8.xmp', '_1.xmp')))
#如果是photo2的话,就要将photo2 的 xmp 重命名成 _8.xmp
# if usePhoto == "photo2":
# for xmp in os.listdir(sourceFile):
# if xmp.endswith('.xmp'):
# #重名名.xmp 结尾的文件
# os.rename(os.path.join(sourceFile, xmp), os.path.join(sourceFile,xmp.replace('_1.xmp', '_8.xmp')))
# print("坐标复制完成")
# exit()
#将两组图片进行重新对齐 然后重建区域 #将两组图片进行重新对齐 然后重建区域
psid = libs.getPSid(pid) psid = libs.getPSid(pid)
cmd = f'{config.rcbin} {config.r2["init"]} -setInstanceName {pid} \ cmd = f'{config.rcbin} -setInstanceName {pid} \
-load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" {config.r["setTextureFalse"]} \ -load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" {config.r["setTextureFalse"]} \
-addFolder "{targetFile}" -selectAllImages \ -addFolder "{targetFile}" -selectAllImages \
-detectMarkers "D:\\make2\\config\\detectMarkers.config.xml" \ -detectMarkers "D:\\make2\\config\\detectMarkers.config.xml" \
{libs.get_defineDistances(psid)} -update -align -align {config.r2["setRegion"]} \ {libs.get_defineDistances(psid)} -update -align -align {config.r2["setRegion"]} \
{exportxmp} \ {exportxmp} \
-exportReconstructionRegion "{os.path.join(config.workdir, pid, f"{pid}.rcbox")}" \ -exportReconstructionRegion "{os.path.join(config.workdir, pid, f"{pid}.rcbox")}" \
-selectImage "'+os.path.join(config.workdir,pid,'photo2')+'\*" -enableTexturingAndColoring true' -selectImage "{os.path.join(config.workdir,pid,"photo2")}/*" -enableTexturingAndColoring true \
-save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}"' -save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" -quit'
print(cmd) print(cmd)
cmd = shlex.split(cmd) cmd = shlex.split(cmd)
res = subprocess.run(cmd) res = subprocess.run(cmd)

147
manual_single.py

@ -0,0 +1,147 @@
import os, sys, time, shlex, subprocess, shutil, requests, cv2, numpy as np
from PIL import Image
import platform
if platform.system() == 'Windows':
sys.path.append('e:\\libs\\')
#sys.path.append('libs')
else:
sys.path.append('/data/deploy/make3d/make2/libs/')
import config, libs, libs_db,main_service_db
# 2. 手动操作建模做成建模
# 2.0 检测是否存在项目,不存在就下载,存在就清除项目其它无用的文件
# 2.1 初始化工程, 根据参数 加入 photo1 或者 photo 2 的 照片, 对齐 , 导出坐标, 将坐标复制到 另外一个文件夹, 测距, 重建区域, 然后调用step2
#根据pid 检测是否存在项目,不存在就下载,存在就清除项目其它无用的文件
def check_pid_file(pid):
#检测是否存在目录
path = os.path.join(config.workdir, pid)
if not os.path.exists(path):
#不存在就在就下载目录
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 开始计算相机位姿...')
start_time = time.time()
libs.down_from_oss(config.oss_bucket, config.workdir, pid,100,"2")
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} 图片下载完成,共费时{libs.diff_time(start_time)}')
else:
#存在的话就检测是否有photo1 和 photo2 之外的目录或者文件,有的话就删除
for file in os.listdir(path):
if file != 'photo1' and file != 'photo2':
if os.path.isfile(os.path.join(path, file)):
os.remove(os.path.join(path, file))
else:
shutil.rmtree(os.path.join(path, file))
#判断photo1 和 photo2 目录里的文件是否存在xmp 文件,存在的话就删除
for file in os.listdir(os.path.join(path, 'photo1')):
if file.endswith('.xmp'):
os.remove(os.path.join(path, 'photo1', file))
for file in os.listdir(os.path.join(path, 'photo2')):
if file.endswith('.xmp'):
os.remove(os.path.join(path, 'photo2', file))
#根据参数初始化操作
def cmd_run(pid,usePhoto = "2",lock=False):
pid = str(pid)
#检测文件并且下载处理文件
check_pid_file(pid)
start_time = time.time()
#文件路径
#photo1_path = os.path.join(config.workdir, pid, 'photo1')
photo2_path = os.path.join(config.workdir, pid, 'photo2')
#计算文件里的数量
#photos1_count = len(os.listdir(photo1_path))
photos2_count = len(os.listdir(photo2_path))
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} photo2数量{photos2_count}')
#xmp 坐标是要用 lock的 还是 unlock 的
if lock:
exportxmp = ' -exportXMP "D:\\make2\\config\\exportXMP.config.lock.xml" '
else:
exportxmp = ' -exportXMP "D:\\make2\\config\\exportXMP.config.xml" '
usePhoto = "photo"+str(usePhoto)
#执行命令
cmd = f'{config.rcbin} {config.r2["init"]} -setInstanceName "{pid}" \
-save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" \
-addFolder "{os.path.join(config.workdir, pid, usePhoto)}" -selectAllImages \
-detectMarkers "D:\\make2\\config\\detectMarkers.config.xml" \
-align -align \
{exportxmp} \
-save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" -quit'
print(cmd)
cmd = shlex.split(cmd)
res = subprocess.run(cmd)
#根据参数转变路劲,复制photo1 里的xmp 文件到 photo2 里,或者 photo2 里的xmp 文件到 photo1 里
# sourceFile = photo1_path
targetFile = photo2_path
# if usePhoto == "photo2":
# sourceFile = photo2_path
# targetFile = photo1_path
# #复制xmp文件
# for xmp in os.listdir(sourceFile):
# if xmp.endswith('.xmp'):
# if usePhoto == "photo1":
# shutil.copy(os.path.join(sourceFile, xmp), os.path.join(targetFile,xmp.replace('_1.xmp', '_8.xmp')))
# if usePhoto == "photo2":
# shutil.copy(os.path.join(sourceFile, xmp), os.path.join(targetFile,xmp.replace('_8.xmp', '_1.xmp')))
#如果是photo2的话,就要将photo2 的 xmp 重命名成 _8.xmp
# if usePhoto == "photo2":
# for xmp in os.listdir(sourceFile):
# if xmp.endswith('.xmp'):
# #重名名.xmp 结尾的文件
# os.rename(os.path.join(sourceFile, xmp), os.path.join(sourceFile,xmp.replace('_1.xmp', '_8.xmp')))
# print("坐标复制完成")
# exit()
#将两组图片进行重新对齐 然后重建区域
psid = libs.getPSid(pid)
cmd = f'{config.rcbin} -setInstanceName {pid} \
-load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}"\
-detectMarkers "D:\\make2\\config\\detectMarkers.config.xml" \
{libs.get_defineDistances(psid)} -update -align -align -align -align -align -align {config.r2["setRegion"]} \
{exportxmp} \
-exportReconstructionRegion "{os.path.join(config.workdir, pid, f"{pid}.rcbox")}" \
-selectImage "{os.path.join(config.workdir,pid,"photo2")}/*" -enableTexturingAndColoring true \
-save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" -quit'
print(cmd)
cmd = shlex.split(cmd)
res = subprocess.run(cmd)
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} step1完成,共费时{libs.diff_time(start_time)}')
#调用step2
time.sleep(2)
os.system(f'python main_step2.py {pid}')
if __name__ == '__main__':
if len(sys.argv) == 2:
pids = sys.argv[1].split(',')
for pid in pids:
cmd_run(pid,usePhoto = "1",lock=False)
elif len(sys.argv) == 3:
pids = sys.argv[1].split(',')
for pid in pids:
if sys.argv[2] == '2':
cmd_run(pid,usePhoto = "2",lock=False)
else:
cmd_run(pid,usePhoto = "1",lock=False)
elif len(sys.argv) == 4:
pids = sys.argv[1].split(',')
usePhoto = sys.argv[2]
lock = sys.argv[3]
for pid in pids:
cmd_run(pid,usePhoto = usePhoto,lock=lock)
else:
print(f'useage: python {sys.argv[0]} pid1,pid2,pid3 photo = 1/2 lock = True/False')
sys.exit(1)

20
timer/get_task_to_db.py

@ -1,10 +1,10 @@
import platform,sys,redis,time,requests,json import platform,sys,redis,time,requests,json,atexit
if platform.system() == 'Windows': if platform.system() == 'Windows':
sys.path.append('e:\\libs\\') sys.path.append('e:\\libs\\')
else: else:
sys.path.append('/data/deploy/make3d/make2/libs/') sys.path.append('/data/deploy/make3d/make2/libs/')
import config,libs,libs_db import config,libs,libs_db,common
r = redis.Redis(host="106.14.158.208",password="kcV2000",port=6379,db=6) r = redis.Redis(host="106.14.158.208",password="kcV2000",port=6379,db=6)
def getPSid(pid): def getPSid(pid):
res = requests.get("https://mp.api.suwa3d.com/api/customerP3dLog/photoStudio",params={"pid":pid}) res = requests.get("https://mp.api.suwa3d.com/api/customerP3dLog/photoStudio",params={"pid":pid})
@ -43,21 +43,17 @@ def readTask(key):
print("走新的建模系统不是分布式插入-重建工单",key,pid,psid) print("走新的建模系统不是分布式插入-重建工单",key,pid,psid)
libs_db.add_task(taskData) libs_db.add_task(taskData)
else: else:
if int(psid) <= 90 and int(psid) != 29 and int(psid) != 56:
if int(psid) == 41 or int(psid) == 85: print("走分布式建模",key,pid,psid)
taskData["priority"] = 0 if int(psid) == 41 or int(psid) == 85:
print("走分布式建模系统插入",key,pid,psid) taskData["priority"] = 0
libs_db.add_task_distributed(taskData)
if libs_db.isStudioConfigDistribute(psid):
print("走分布式建模系统插入",key,pid,psid)
libs_db.add_task_distributed(taskData) libs_db.add_task_distributed(taskData)
else: else:
print("走新的建模系统不是分布式插入",key,pid,psid) print("非分布式建模",key,pid,psid)
libs_db.add_task(taskData) libs_db.add_task(taskData)
#程序主入口 #程序主入口
if __name__ == '__main__': if __name__ == '__main__':
atexit.register(common.notify,"定时读取建模任务已经停止")
#print(r.llen('model:make10')) #print(r.llen('model:make10'))
#开启死循环 #开启死循环
while True: while True:

4
tools/push_cmd.py

@ -17,6 +17,8 @@ def main(cmd, order_id):
key = 'model:make10' key = 'model:make10'
elif cmd == 'foot': # print_id elif cmd == 'foot': # print_id
key = 'model:foot' key = 'model:foot'
elif cmd == 'rebuild': #pid
key = 'model:rebuild'
if order_id == 'view': if order_id == 'view':
for i in r.lrange(key, 0, -1): for i in r.lrange(key, 0, -1):
@ -142,7 +144,7 @@ if __name__ == '__main__':
r = config.redis_remote r = config.redis_remote
#pid 可能是多个的,用逗号分隔,查询的时候接口应该也要支持多个的 #pid 可能是多个的,用逗号分隔,查询的时候接口应该也要支持多个的
if cmd == 'make3d' or cmd == 'make3d10': if cmdName == 'make3d' or cmdName == 'make3d10' or cmdName == 'rebuild':
main(cmdName, pid) main(cmdName, pid)
elif cmd != "": elif cmd != "":
cmd(cmdName,pid) cmd(cmdName,pid)

3
建模碎片步骤.txt

@ -0,0 +1,3 @@
#建模完成,需要减面 smooth 封闭洞 清理模型 贴图
%bin% -delegateTo %pid% -simplify 3000000 -smooth -closeHoles -cleanModel -calculateTexture -save "D:\123446\123446.rcproj" -exportSelectedModel "D:\123446\output\123446.obj" "d:\make2\config\ModelExportParams.xml" -quit
Loading…
Cancel
Save