Browse Source

first commit

master
dongchangxi 1 year ago
parent
commit
7a2b784979
  1. 0
      doc/建模碎片步骤.txt
  2. BIN
      export_build_info/__pycache__/export_already_build.cpython-310.pyc
  3. 0
      export_build_info/already.txt
  4. 125
      export_build_info/check.py
  5. 0
      export_build_info/err.pid
  6. 90
      export_build_info/finish.txt
  7. 0
      export_build_info/finished.txt
  8. 340
      export_build_info/main_step1.py
  9. 267
      export_build_info/main_step2.py
  10. 185
      export_build_info/manual_service.py
  11. 27
      export_build_info/pids/人物.txt
  12. 28
      export_build_info/pids/动物.txt
  13. 393
      export_build_info/pids/单人.txt
  14. 307
      export_build_info/pids/双人.txt
  15. 28
      export_build_info/pids/多人.txt
  16. 13
      install.txt
  17. 13
      libs/install.txt
  18. 101
      main_repeat_texture.py
  19. 68
      old_step2.py
  20. 499
      pid.text
  21. 5
      step.text
  22. 1028
      suwa_cut_foot_cut_normal_data.txt
  23. BIN
      task_distributed_error.log
  24. 18
      test.py
  25. 21
      test1.py
  26. 202
      timer/external_order_glb.py
  27. 28
      timer/init_timer.py
  28. 16
      tools/push_cmd.py
  29. 40
      yj_local_build/ModelExportParams.xml
  30. 17
      yj_local_build/config.json
  31. 26
      yj_local_build/config.py
  32. 7
      yj_local_build/detectMarkers.config.xml
  33. 6
      yj_local_build/exportControlPoints.config.xml
  34. 8
      yj_local_build/exportXMP.config.lock.xml
  35. 139
      yj_local_build/libs.py
  36. 233
      yj_local_build/main_step1.py

0
建模碎片步骤.txt → doc/建模碎片步骤.txt

BIN
export_build_info/__pycache__/export_already_build.cpython-310.pyc

Binary file not shown.

0
export_build_info/already.txt

125
export_build_info/check.py

@ -1,125 +0,0 @@ @@ -1,125 +0,0 @@
import os, sys, time, shlex, subprocess, shutil, requests, cv2, numpy as np
from PIL import Image
import platform,socket,atexit
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,common
arrPids = [184219,184215,184209,184206,184201,184199,184164,184087,184076,184069,184059,184029,184013,183993,183952,183888,183882,183868,183824,183817,183815,183812,183791,183777,183715,183705,183670,183613,183573,182974,182983,182985,182989,182997,183007,183051,183060,183054,183053,183097,183119,183108,183139,183141,183155,183163,183169,183180,183191,183196,183214,183244,183266,183278,183275,183309,183402,183422,183440,182974,182964,182958,182956,182916,182855,182854,182820,182787,182800,182809,182780,182772,182770,182766,182754,182742,182740,182723,182707,182647,182643,182614,182595,182563,182557,182547,182546,182538,182530,182517,182498,182478,182452,182386,182352,182285,182266,182260,182230,182224]
r12Pids = [184219,184215,184209,184069,184059,183868,183817,183791,183613,183573,182974,182983,182985,182989,182997,183007,183051,183060,183054,183053,183097,183119,183108,183139,183141,183155,183163,183169,183180,183191,183196,183214,183244,183266,183278,183275,183309,183402,183422,183440,182974,182964,182958,182855,182854]
print(f"处理的数据长度--{len(arrPids)}")
i=0
noPids = ''
for pid in r12Pids:
pid = str(pid)
path = f"D://{pid}/mask"
#判断是否存在文件夹
if not os.path.exists(path):
continue
#判断文件夹是否为空
if len(os.listdir(path)) == 0:
continue
i+=1
#检查 depth 和 mask 的文件创建时间是否差异比较大
fileDepth = f"D://{pid}/depth"
fileMask = f"D://{pid}/mask"
diffDepthTime = []
dfffMaskTime = []
arrTimeDepth = []
arrTimeMask = []
for file in os.listdir(fileDepth):
createTime = os.path.getctime(f"{fileDepth}/{file}")
updateTime = os.path.getmtime(f"{fileDepth}/{file}")
# print(updateTime - createTime)
diffDepthTime.append(updateTime - createTime)
arrTimeDepth.append(os.path.getctime(f"{fileDepth}/{file}"))
for file in os.listdir(fileMask):
createTime = os.path.getctime(f"{fileMask}/{file}")
updateTime = os.path.getmtime(f"{fileMask}/{file}")
dfffMaskTime.append(updateTime - createTime)
arrTimeMask.append(os.path.getctime(f"{fileMask}/{file}"))
#打印出 两者的 最大 和最小的时间信息
print(f"pid: {pid} depth: { (max(arrTimeDepth) - min(arrTimeDepth))/60 }, diffdepth: {max(diffDepthTime)}, mask: { (max(arrTimeMask) - min(arrTimeMask))/60},diffmask: {max(dfffMaskTime)}")
# print(f"pid: {pid} diffdepth: {max(arrTimeDepth)} diffmask: {max(arrTimeMask)}")
diffDepth = (max(arrTimeDepth) - min(arrTimeDepth))/60
diffMask = (max(arrTimeMask) - min(arrTimeMask))/60
if diffDepth > 5 or diffMask > 5:
print(f"异常数据 pid: {pid} depth: {diffDepth} mask: {diffMask}")
break
#复制文件到指定目录
maskPath = f"D://{pid}/mask"
depthPath = f"D://{pid}/depth"
regPath = f"D://{pid}/reg"
imageList = f"D://{pid}/{pid}_imageList.txt"
outFila = f"D://{pid}/reg/{pid}_registration.out"
sourcePath = f"D://model_info/{pid}"
if os.path.exists(sourcePath):
shutil.rmtree(sourcePath)
if not os.path.exists(sourcePath):
os.makedirs(sourcePath)
#复制文件
shutil.copytree(maskPath, f"D://model_info/{pid}/mask")
shutil.copytree(depthPath, f"D://model_info/{pid}/depth")
shutil.copy(imageList, f"D://model_info/{pid}/{pid}_imageList.txt")
shutil.copy(outFila, f"D://model_info/{pid}/{pid}_registration.out")
#遍历reg文件夹
for file in os.listdir(regPath):
if file == f"{pid}_registration.out":
continue
if "_1.jpg" in file:
sourceTempPath = f"D://model_info/{pid}/reg/photo1"
if not os.path.exists(sourceTempPath):
os.makedirs(sourceTempPath)
shutil.copy(f"{regPath}/{file}", f"{sourceTempPath}/{file}")
if "_8.jpg" in file:
sourceTempPath = f"D://model_info/{pid}/reg/photo2"
if not os.path.exists(sourceTempPath):
os.makedirs(sourceTempPath)
shutil.copy(f"{regPath}/{file}", f"{sourceTempPath}/{file}")
#shutil.copy(f"{regPath}/{file}", f"D://model_info/{pid}/reg/{file}")
#移除 reg 里的 {pid}_registration.out
print(f"处理完成 pid: {pid}")
# shutil.copytree(f"D://{pid}", f"D://{pid}_bak")
# cmd = f'{config.rcbin} {config.r2["init"]} -setInstanceName {pid} \
# -load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}"'# -quit
# print(cmd)
# cmd = shlex.split(cmd)
# res = subprocess.run(cmd)
#print(i)

0
export_build_info/err.pid

90
export_build_info/finish.txt

@ -1,90 +0,0 @@ @@ -1,90 +0,0 @@
146134
146134
146598
183716
185381
183400
187752
184871
184956
185326
187651
187802
187811
187800
183096
187804
184956
187808
187898
187865
187870
187886
187912
185102
185102
185102
187450
185102
187989
188170
188117
188128
188200
188297
188310
188344
185101
188425
188428
188431
188560
188494
188564
188757
188779
188807
188865
188827
188910
188907
188913
188942
188964
189045
189051
189203
189214
189218
189228
189246
189242
189373
189312
189388
189913
189911
189932
189946
189106
186427
186544
190092
190112
188681
190138
188688
189172
183292
189178
184093
183080
189608
189625
189618
189170
189623
190151
183309
190214
188521

0
export_build_info/finished.txt

340
export_build_info/main_step1.py

@ -1,340 +0,0 @@ @@ -1,340 +0,0 @@
import os, sys, time, shlex, subprocess, shutil, requests, cv2, numpy as np
from PIL import Image
import platform,socket,atexit
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,common
def filter_dark_texture_image(pid):
start_time = time.time()
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 开始检测射灯异常图片...')
def get_image_v(image):
# 图片左上角和右上角各取200*200区域,计算V通道均值
left_rect = image[0:200, 0:200]
right_rect = image[0:200, -200:]
left_hsv = cv2.cvtColor(left_rect, cv2.COLOR_BGR2HSV)
left_v = left_hsv[:, :, 2]
left_avg_v = np.mean(left_v)
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 图片左上角V通道均值:{left_avg_v}')
right_hsv = cv2.cvtColor(right_rect, cv2.COLOR_BGR2HSV)
right_v = right_hsv[:, :, 2]
right_avg_v = np.mean(right_v)
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 图片右上角V通道均值:{right_avg_v}')
return (left_avg_v + right_avg_v) / 2
v_list = []
for filename in os.listdir(os.path.join(config.workdir, pid, 'photo2')):
if filename.endswith(".jpg"):
image = cv2.imread(os.path.join(config.workdir, pid, 'photo2', filename))
v = get_image_v(image)
item = {'filename': filename, 'v': v}
v_list.append(item)
v_list.sort(key=lambda x: x['v'])
v_list = v_list[5: -5]
avg_v = np.mean([item['v'] for item in v_list])
for item in v_list:
if abs(item['v'] - avg_v) > 50:
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 图片{item["filename"]} V通道值{item["v"]},低于平均值{avg_v},将不参与贴图')
libs.set_photo_join_type(config.workdir, pid, 'photo2', item['filename'].split('_')[0], mesh='1', texture='0')
# 复制xmp文件到photo3目录,如果photo3目录存在的话
if os.path.exists(os.path.join(config.workdir, pid, 'photo3')):
shutil.copyfile(os.path.join(config.workdir, pid, 'photo2', item['filename'].replace('jpg', 'xmp')), os.path.join(config.workdir, pid, 'photo3', item['filename'].replace('jpg', 'xmp')))
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 射灯异常图片检测完成,共费时{libs.diff_time(start_time)}')
def detect_markers(psid, pid):
def fix_region():
region_filename = os.path.join(config.workdir, pid, f'{pid}.rcbox')
with open(region_filename, 'r') as f:
lines = f.readlines()
lines = [line.replace('"NONE" globalCoordinateSystemWkt="NONE" globalCoordinateSystemName="NONE"', '"+proj=geocent +ellps=WGS84 +no_defs" globalCoordinateSystemName="local:1 - Euclidean"') for line in lines]
start_time = time.time()
add_photo3 = ' '
textpicCmd = ' '
if os.path.exists(os.path.join(config.workdir, pid, 'photo3')):
add_photo3 = ' -addFolder "' + os.path.join(config.workdir, pid, 'photo3') + '" '
textpicCmd ='-selectImage "'+os.path.join(config.workdir,pid,'photo3')+'\*" -enableTexturingAndColoring true'
textpicCmd ='-selectImage "'+os.path.join(config.workdir,pid,'photo2')+'\*" -enableTexturingAndColoring false'
else:
textpicCmd ='-selectImage "'+os.path.join(config.workdir,pid,'photo2')+'\*" -enableTexturingAndColoring true'
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, "photo1")}" {config.r["setTextureFalse"]} -align -addFolder "{os.path.join(config.workdir, pid, "photo2")}" \
{add_photo3} -align -selectAllImages \
-detectMarkers "D:\\make2\\config\\detectMarkers.config.xml" \
{libs.get_defineDistances(psid)} -align -align -update {config.r2["setRegion"]} \
-exportXMP "D:\\make2\\config\\exportXMP.config.xml" \
-exportControlPointsMeasurements "{os.path.join(config.workdir, pid, f"{pid}.controlPoints.csv")}" "D:\\make2\\config\\exportControlPoints.config.xml" \
-exportReconstructionRegion "{os.path.join(config.workdir, pid, f"{pid}.rcbox")}" \
{textpicCmd} -save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" -quit'
print(cmd)
cmd = shlex.split(cmd)
res = subprocess.run(cmd)
time.sleep(3)
fix_region()
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 定位点检测完成, 共费时{libs.diff_time(start_time)}')
if os.path.exists(os.path.join(config.workdir, pid, 'photo3')):
for filename in os.listdir(os.path.join(config.workdir, pid, 'photo2')):
if filename.endswith('_8.xmp'):
# photo3 exist, 设置photo2的xmp文件,不参与贴图
libs.set_photo_join_type(config.workdir, pid, 'photo2', filename.split('_')[0], mesh='1', texture='0')
for filename in os.listdir(os.path.join(config.workdir, pid, 'photo3')):
if filename.endswith('_8.xmp'):
# photo3 exist, 设置photo3的xmp文件,不参与建模
libs.set_photo_join_type(config.workdir, pid, 'photo3', filename.split('_')[0], mesh='0', texture='1')
def step1(pid, experience=False, makeloop=True,task_distributed_id="",isNoColorTexture=""):
libs_db.start_task({"task_type": "make", "task_key": pid})
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 开始处理{pid}建模任务')
psid = libs.getPSid(pid)
# 更新云端任务状态
res = requests.post(config.urls['update_status_modeling_url'], data={'id': pid})
print('更新建模中状态:', res.text)
# 下载图片
start_time = time.time()
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} 开始下载图片...')
libs.down_from_oss(config.oss_bucket, config.workdir, pid)
try:
if str(psid) == "86":
#移除指定文件
os.remove(f"D:\{pid}\photo1\\21_1.jpg")
os.remove(f"D:\{pid}\photo2\\21_8.jpg")
if str(psid) == "29":
#移除指定文件
os.remove(f"D:\{pid}\photo1\\15_1.jpg")
os.remove(f"D:\{pid}\photo2\\15_8.jpg")
except Exception as e:
print("移除异常")
#旋转图片
os.system(f'python D:\\make2\\photo2rotate.py -w d:\ -p {pid} -i photo1 -o photo1')
os.system(f'python D:\\make2\\photo2rotate.py -w d:\ -p {pid} -i photo2 -o photo2')
os.system(f'python D:\\make2\\export_build_info\\gen_xmps_for_build_info.py {pid}')
#print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} 图片下载完成,共费时{libs.diff_time(start_time)}')
os.system(f'python main_step2.py {pid}')
# start_time = time.time()
# # TODO: 上报图片采集数量,更新影棚相机状态
# # 处理图片,如果experience=True,将图片缩减一半,已节省建模时间和算力成本
# # if experience:
# # libs.resize_photos(os.path.join(config.workdir, pid, 'photo1'))
# # libs.resize_photos(os.path.join(config.workdir, pid, 'photo2'))
# # 根据配置调整photo2曝光,均衡贴图亮度,可能产生photo3
# libs.adjust_photos(config.workdir, pid)
# # TODO: 检测模糊异常图片,上报微信通知
# # TODO: 处理图片,去反光算法
# # 检测图片定位点,定位异常及时上报微信通知给客服人员,人工判断是否需要重新拍摄或更换地贴。定义定位点距离,导出相机位姿信息
# detect_markers(psid, pid)
# # 处理图片,检测photo2中的异常图片不参与贴图,以免破坏贴图效果,默认不检测射灯异常图片,以节省算力成本
# if not makeloop:
# filter_dark_texture_image(pid)
# # 处理图片,暗部提亮,提高贴图效果
# # TODO: 处理图片,去遮挡处理,提高建模与贴图质量
# # 加入photo2,计算重建区域,导出重建区域与相机位姿配置信息
# # cal_reconstruction_region(psid, pid)
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} step1图片预处理完成,共费时{libs.diff_time(start_time)}')
# if os.path.exists(os.path.join(config.sharedir, pid)):
# shutil.rmtree(os.path.join(config.sharedir, pid), ignore_errors=True)
# shutil.copytree(os.path.join(config.workdir, pid), os.path.join(config.sharedir, pid))
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} step1任务完成,移动到共享目录')
# #指定photo2某些图片不参与贴图
# #是否不参与贴图,true 不参与贴图
# if isNoColorTexture == "NoColorTexture":
# arrNoTextureColorPics = config.noTextureColorPics
# if arrNoTextureColorPics is not None and len(arrNoTextureColorPics) > 0:
# for camcerIndex in arrNoTextureColorPics:
# #拼装坐标文件名称
# filename = os.path.join(config.sharedir, pid,"photo2",str(camcerIndex)+"_8.xmp")
# #判断文件是否存在
# if os.path.exists(filename):
# #存在就设置不参与贴图
# libs.set_photo_join_type(config.workdir, pid, 'photo2', camcerIndex, mesh='0', texture='0')
# #移除当前文件夹
# shutil.rmtree(os.path.join(config.workdir, pid))
# # TODO: 更新本地step1任务状态,加入step2任务队列
# if task_distributed_id == "":#不是分布式任务的时候就自动往下个步骤走,是分布式任务的时候就就执行当前任务
# if makeloop:
# os.system(f'python main_step2.py {pid}')
# else:
# os.system(f'python main_step2.py {pid}')
# # if os.path.exists(os.path.join(config.sharedir, pid)):
# # shutil.rmtree(os.path.join(config.sharedir, pid), ignore_errors=True)
# # shutil.move(os.path.join(config.workdir, pid), config.sharedir)
# # print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} step1任务完成,移动到共享目录')
# else:
# #分布式服务执行完后,需要更新任务状态,更新字表的finished_at字段
# main_service_db.update_task_distributed_detail({"task_distributed_id":task_distributed_id,"finished_at":time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())})
# print("step1完成,休息6s")
# time.sleep(4)
# return
def main(pid, experience=False, makeloop=True,task_distributed_id="",isNoColorTexture=""):
if pid == '0':
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 开始进入本地任务值守模式...')
while True:
# 取云端redis多个key任务,TODO:后续要改为api调用
experience = False
pid = libs_db.get_task('make_experience')
if pid == '':
time.sleep(3)
pid = libs_db.get_task('make')
if pid == '':
time.sleep(3)
continue
else:
experience = False
step1(pid, experience, makeloop,task_distributed_id,isNoColorTexture)
else:
step1(pid, experience, makeloop,task_distributed_id,isNoColorTexture)
def is_already(pid):
#读取已经完成的pid
with open("D://make2/export_build_info/finished.txt", 'r') as f:
lines = f.readlines()
for line in lines:
print("line",str(line.strip()))
if str(pid) == str(line.strip()):
print("匹配成功")
return True
return False
if __name__ == '__main__':
isNoColorTexture = ""
if len(sys.argv) == 2:
v = sys.argv[1]
#判断是否是数字
if v.isdigit():
#print(f"正在处理输入的pid-{v}")
main(str(v), experience=False, makeloop=False,task_distributed_id="",isNoColorTexture=isNoColorTexture)
else:
filePath = f"D://make2/export_build_info/pids/{v}.txt"
if not os.path.exists(filePath):
print(f"{filePath} 文件不存在")
strPids = ""
with open("D://make2/pid.text","r") as f:
lines = f.readlines()
for line in lines:
strPids = str(line.strip())
errPids = ""
with open("D://make2/errPid.text","r") as f:
lines = f.readlines()
for line in lines:
errPids = str(line.strip())
arrErrPids = errPids.split(",")
arrPids = strPids.split(",")
ii = 0
with open(filePath, 'r') as f:
lines = f.readlines()
for line in lines:
pid = str(line.strip())
if pid == "":
break
#判断是否存在了目录或者已经是处理过了
# tempFile = f"D://{pid}//finish.txt"
# if os.path.exists(tempFile):
# continue
if str(pid) in arrErrPids:
continue
if str(pid) in arrPids:
# print(f"已处理过{pid}")
ii += 1
continue
print(f"正在处理{pid}- 完成{ii}")
main(str(pid), experience=False, makeloop=False,task_distributed_id="",isNoColorTexture=isNoColorTexture)
ii += 1
print(f"已经完成-{ii}")
else:
print("cmd like python main_step1.py pid/单人/多人/双人/动物/人物")
# # 取云端redis任务,完成第一步的数据预处理后,将数据放入共享存储目录,将第二步任务塞入本地mysql队列
# # 默认循环值守,可传参数运行单一任务,以方便调试
# #atexit.register(common.notify,socket.gethostname()+"建模任务已经停止")
# # pid = '0'
# isNoColorTexture = ""
# # if len(sys.argv) == 2:
# # pids = sys.argv[1].split(',')
# # for pid in pids:
# already = [184219,184215,184209,184069,184059,183868,183817,183791,183613,183054,182855,182854,184206,184201,184199,184164,184087,184076,184029,184013,183993,183952,183888,183882,183824,183815,183812]
# arrPids = [184219,184215,184209,184206,184201,184199,184164,184087,184076,184069,184059,184029,184013,183993,183952,183888,183882,183868,183824,183817,183815,183812,183791,183777,183715,183705,183670,183613,183573,182974,182983,182985,182989,182997,183007,183051,183060,183054,183053,183097,183119,183108,183139,183141,183155,183163,183169,183180,183191,183196,183214,183244,183266,183278,183275,183309,183402,183422,183440,182974,182964,182958]
# #,182956,182916,182855,182854,182820,182787,182800,182809,182780,182772,182770,182766,182754,182742,182740,182723,182707,182647,182643,182614,182595,182563,182557,182547,182546,182538,182530,182517,182498,182478,182452,182386,182352,182285,182266,182260,182230,182224
# i = 0
# for pid in arrPids:
# if pid in already:
# continue
# print("正在处理-",pid)
# if is_already(str(pid)) == True:
# continue
# # i += 1
# # continue
# #写入到
# with open("D://make2/export_build_info/finished.txt", 'a+') as f:
# f.write(f"{pid}\n")
# main(str(pid), experience=False, makeloop=False,task_distributed_id="",isNoColorTexture=isNoColorTexture)
# print("已处理-",i)
# #exit()
# # if len(sys.argv) == 3:
# # experience = False
# # if sys.argv[2] == '1':
# # print('演示测试...')
# # experience = False
# # elif sys.argv[2] == 'NoColorTexture':
# # isNoColorTexture = "NoColorTexture"
# # pids = sys.argv[1].split(',')
# # for pid in pids:
# # main(pid, experience=experience, makeloop=False,task_distributed_id="",isNoColorTexture=isNoColorTexture)
# # exit()
# # main(pid, experience=False, makeloop=True,task_distributed_id="",isNoColorTexture=isNoColorTexture)

267
export_build_info/main_step2.py

@ -1,267 +0,0 @@ @@ -1,267 +0,0 @@
import os, sys, time, shutil, subprocess, shlex
import platform
import pyautogui as ag
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,common,main_service_db,computerRecboxCenterByPoint
import export_already_build
redisLocal = config.redis_local
def load_model(pid):
cmd = f'{config.rcbin} {config.r1["init"]} -load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}"'
print(cmd)
cmd = shlex.split(cmd)
res = subprocess.run(cmd)
def get_rcver():
rcbin = '"C:\\Program Files\\Capturing Reality\\RealityCapture\\RealityCapture.exe"'
if os.path.getsize(rcbin[1:-1]) == 20783616:
return 1
else:
return 2
def make3d(pid):
if get_rcver() == 1: # old version
#修改重建区域的大小
common.change_rcbox_s(pid,"1")
#获取影棚id
# psid = libs.getPSid(pid)
# if int(psid) == 80:
# change_rcbox_deepth(str(pid),0.03)
psid = libs.getPSid(pid)
simplify_value = 1000000 * libs.getHeadCount(pid)
add_photo3 = ' '
#判断是否存在photo3
if os.path.exists(os.path.join(config.workdir, pid, 'photo3')):
add_photo3 = ' -addFolder "' + os.path.join(config.workdir, pid, 'photo3') + '" -align -align '
#存在photo3 的情况下,photo2 不参与贴图
#遍历获取photo2 目录下的所有文件
directory = os.path.join(config.workdir, pid, 'photo2')
for root, dirs, files in os.walk(directory):
for file in files:
#判断file 是否以 _8.xmp 结尾
if file.endswith("_8.xmp") == False:
continue
#修改文件内容不参与贴图
libs.set_photo_join_type(config.workdir, pid, 'photo2', file.split("_")[0], mesh='0', texture='0')
else:
pass
#设置photo2参与贴图,因为有的时候贴图会黑
directory = os.path.join(config.workdir, pid, 'photo2')
for root, dirs, files in os.walk(directory):
for file in files:
#判断file 是否以 _8.xmp 结尾
if file.endswith("_8.xmp") == False:
continue
#修改文件内容不参与贴图
libs.set_photo_join_type(config.workdir, pid, 'photo2', file.split("_")[0], mesh='0', texture='1')
if get_rcver() == 1: # old version
#判断oss 上是否存在 controlpoints 文件
isExistPoint = common.isExistControlPointsOss(pid)
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} \
-importControlPointsMeasurements "{os.path.join(config.workdir, pid, f"{pid}.controlPoints.csv")}" \
-align -exportRegistration "{os.path.join(config.workdir,"make2", "config","exportRegistration.xml")}" "{os.path.join(config.workdir, pid,str(pid)+"_align.csv")}" -save'
cmd = cmd + f' "{os.path.join(config.workdir, pid, f"{pid}_wait.rcproj")}"'
print(cmd)
cmd = shlex.split(cmd)
res = subprocess.run(cmd)
time.sleep(2)
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)
#判断是否有 pid_1 的的值
print(pid+"_1")
if redisLocal.lpos('model:auto_distance',pid+"_1") == None:
continue
shutil.move(os.path.join(config.workdir, pid, f'{pid}_wait.rcproj'), os.path.join(config.workdir, pid, f'{pid}.rcproj'))
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 定义定位点距离完成')
#将 controlpoints_0.dat 文件拷贝到 oss 上作为公共的使用
common.uploadControlPointsOss(pid)
#最后处理掉redis中的值
redisLocal.lrem('model:auto_distance', 0, pid+"_1")
break
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),"循环阻塞结束,判断是否对齐成功")
#查看对齐的数量
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
cmdSmall = "-align"
#使用公共point文件的时候,就不能使用update , 而是要用 align
if isExistPoint == True:
cmdSmall = "-align"
#{config.r1["init"]}
if common.task_need_high_model(pid):
if str(psid) == "41" or str(psid) == "85":
calulate_type = "-mvs"
else:
calulate_type = '-mvsHigh'
else:
calulate_type = '-mvs'
#翻转相机的线向下
cmd = f'{config.rcbin} -load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" {cmdSmall} \
-set "sfmEnableCameraPrior=True" -align -set "sfmEnableCameraPrior=False" -align -save "{os.path.join(config.workdir, pid, f"{pid}_point.rcproj")}" '
cmd = shlex.split(cmd)
res = subprocess.run(cmd)
#执行完成后命令会触发导出点云的定时程序
while True:
print("判断是否导出点云文件循环阻塞开始")
time.sleep(3)
#判断是否有 pid_1 的的值
print(pid+"_3")
if redisLocal.lpos('model:auto_distance',pid+"_3") == None:
continue
shutil.move(os.path.join(config.workdir, pid, f'{pid}_point.rcproj'), os.path.join(config.workdir, pid, f'{pid}.rcproj'))
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 导出点云文件完成')
#最后处理掉redis中的值
redisLocal.lrem('model:auto_distance', 0, pid+"_3")
break
#处理点云文件
centerRcboxValue = computerRecboxCenterByPoint.boxCenter(pid)
if centerRcboxValue > 0:
print("修改中心点的坐标",centerRcboxValue)
#修改中心点的值
common.change_rcbox_center(pid,centerRcboxValue)
cmd = f'{config.rcbin} -load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" -align \
-set "sfmEnableCameraPrior=True" -align -set "sfmEnableCameraPrior=False" -align -setReconstructionRegion "{os.path.join(config.workdir, pid, f"{pid}.rcbox")}" \
{calulate_type} -modelSelectMaximalConnectedComponent -modelInvertSelection -modelRemoveSelectedTriangles -closeHoles -clean -simplify {simplify_value} -smooth -unwrap -calculateTexture -renameModel {pid} -save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" -quit'
print(cmd)
cmd = shlex.split(cmd)
res = subprocess.run(cmd)
#保存在导出
# common.saveScreenImg(pid)
# time.sleep(1)
# ag.hotkey('alt', 'f4')
time.sleep(3)
#修改rcproj文件
flag = common.changeRcprojFile(pid)
if flag == False:
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} rcproj文件不存在')
return
#复制文件
shutil.copy(os.path.join(config.workdir, pid, f'{pid}.rcproj'), os.path.join(config.workdir, pid, f'{pid}_screen.rcproj'))
time.sleep(2)
#打开工程文件
cmd = f'{config.rcbin} -load "{os.path.join(config.workdir, pid, f"{pid}_screen.rcproj")}"'
cmd = shlex.split(cmd)
res = subprocess.run(cmd)
#创建指定文件夹
if not os.path.exists(os.path.join(config.workdir, pid, "output")):
os.makedirs(os.path.join(config.workdir, pid, "output"))
#判断output目录下是否有文件,有的话删除
files = os.listdir(os.path.join(config.workdir, pid, "output"))
#执行导出
cmd = f'{config.rcbin} -load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}"\
-exportModel "{pid}" "{os.path.join(config.workdir, pid, "output", f"{pid}.obj")}" "d:\\make2\\config\\ModelExportParams102.xml" -quit'
print(cmd)
cmd = shlex.split(cmd)
res = subprocess.run(cmd)
else: # new version
#判断是否要进行高精模
if common.task_need_high_model(pid):
if str(psid) == "41" or str(psid) == "85":
calulate_type = "calculateNormalModel"
else:
calulate_type = 'calculateHighModel'
else:
calulate_type = 'calculateNormalModel'
#创建指定文件夹
if not os.path.exists(os.path.join(config.workdir, pid, "output")):
os.makedirs(os.path.join(config.workdir, pid, "output"))
cmd = f'{config.rcbin} {config.r2["init"]} -setInstanceName {pid} \
-load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" \
-{calulate_type} \
-selectLargestModelComponent -invertTrianglesSelection -removeSelectedTriangles -simplify {simplify_value} -smooth -closeHoles -cleanModel -calculateTexture \
-save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" \
-exportSelectedModel "{os.path.join(config.workdir, pid, "output", f"{pid}.obj")}" "d:\\make2\\config\\ModelExportParams.xml" -quit'# -quit
print(cmd)
cmd = shlex.split(cmd)
res = subprocess.run(cmd)
export_already_build.exportInfo(pid)
# #阻塞判断是否导出完成
# while True:
# #判断 output 目录下是否存在 三个文件
# files = os.listdir(os.path.join(config.workdir, pid, "output"))
# if len(files) >= 3:
# break
def step2(pid,task_distributed_id=""):
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 开始建模任务step2')
#判断是否要从共享目录拷贝数据
if os.path.exists(os.path.join(config.sharedir, pid)) and not os.path.exists(os.path.join(config.workdir, pid)):
shutil.move(os.path.join(config.sharedir, pid), config.workdir)
else:
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 目录{os.path.join(config.sharedir, pid)}不存在,或{os.path.join(config.workdir, pid)}已存在')
# return
#最后还是要判断有没有存在目录
if not os.path.exists(os.path.join(config.workdir, pid)):
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 目录{os.path.join(config.workdir, pid)}不存在')
return
start_time = time.time()
make3d(pid)
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 建模任务step2完成,共费时{libs.diff_time(start_time)},任务已提交到step3')
# # 更新本地任务状态,加入step3任务队列
# if task_distributed_id == "":
# os.system(f'python d:\\make2\\main_step3.py {pid}')
# else:
# #暂时 step2 step3 一起连续执行
# print('step2 执行完,开始执行step3')
# os.system(f'python d:\\make2\\main_step3.py {pid}')
# main_service_db.update_task_distributed({"id":task_distributed_id,"status":2,"finished_at":time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())})
# main_service_db.update_task_distributed_detail({"task_distributed_id":task_distributed_id,"finished_at":time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())})
# #return
def main(pid):
if pid == '0':
while True:
# 取本地mysql队列任务,完成第二步的建模任务
step2(pid)
else:
step2(pid)
if __name__ == '__main__':
# 取本地mysql队列任务,完成第二步的建模任务
# 默认循环值守,可传参数运行单一任务,以方便调试
pid = '0'
if len(sys.argv) > 1:
pids = sys.argv[1].split(',')
for pid in pids:
main(pid)
exit()
main(pid)

185
export_build_info/manual_service.py

@ -1,185 +0,0 @@ @@ -1,185 +0,0 @@
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)
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 = "1",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} photo1数量{photos1_count} 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 -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")}" {config.r["setTextureFalse"]} \
-addFolder "{targetFile}" -selectAllImages \
-detectMarkers "D:\\make2\\config\\detectMarkers.config.xml" \
{libs.get_defineDistances(psid)} -update -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}')
os.system(f'python D://make2/export_build_info/main_step2.py {pid}')
def is_already(pid):
#读取已经完成的pid
with open("D://make2/export_build_info/finished.txt", 'r') as f:
lines = f.readlines()
for line in lines:
print("line",str(line.strip()))
if str(pid) == str(line.strip()):
print("匹配成功")
return True
return False
if __name__ == '__main__':
already = [184219,184215,184209,184069,184059,183868,183817,183791,183613,183054,182855,182854,184206,184201,184199,184164,184087,184076,184029,184013,183993,183952,183888,183882,183824,183815,183812]
arrPids = [184219,184215,184209,184206,184201,184199,184164,184087,184076,184069,184059,184029,184013,183993,183952,183888,183882,183868,183824,183817,183815,183812,183791,183777,183715,183705,183670,183613,183573,182974,182983,182985,182989,182997,183007,183051,183060,183054,183053,183097,183119,183108,183139,183141,183155,183163,183169,183180,183191,183196,183214,183244,183266,183278,183275,183309,183402,183422,183440,182974,182964,182958,182956,182916,182855,182854,182820,182787,182800,182809,182780,182772,182770,182766,182754,182742,182740,182723,182707,182647,182643,182614,182595,182563,182557,182547,182546,182538,182530,182517,182498,182478,182452,182386,182352,182285,182266,182260,182230,182224]
for pid in arrPids:
if pid in already:
continue
print("正在处理-",pid)
if is_already(str(pid)) == True:
continue
# i += 1
# continue
#写入到
with open("D://make2/export_build_info/finished.txt", 'a+') as f:
f.write(f"{pid}\n")
cmd_run(str(pid),usePhoto = "1",lock=False)
# 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)

27
export_build_info/pids/人物.txt

@ -1,27 +0,0 @@ @@ -1,27 +0,0 @@
181561
181559
180990
180772
180538
180256
179927
179657
179627
178838
178714
178616
178604
178332
177920
176655
184102
183728
183538
183524
183274
183316
183345
182867
182658
182638
182560

28
export_build_info/pids/动物.txt

@ -1,28 +0,0 @@ @@ -1,28 +0,0 @@
181307
181287
181267
180402
179617
179613
178991
178892
178814
178787
178471
178469
178400
178156
177899
177894
176236
184133
184039
183848
183769
183637
183127
183238
182450
182031
181977
181960

393
export_build_info/pids/单人.txt

@ -1,393 +0,0 @@ @@ -1,393 +0,0 @@
181763
181757
181754
181687
181652
181642
181619
181597
181574
181542
181526
181515
181482
181435
181421
181408
181391
181388
181367
181333
181329
181327
181304
181274
181261
181257
181248
181232
181231
181229
181205
181204
181203
181202
181191
181188
181177
181176
181145
181143
181139
181117
181115
181108
181097
181062
181050
181046
181040
181039
181023
181020
180961
180958
180944
180943
180904
180903
180869
180864
180862
180846
180839
180819
180781
180776
180771
180770
180670
180661
180648
180593
180591
180588
180581
180461
180455
180450
180429
180424
180394
180327
180314
180308
180297
180292
180291
180281
180273
180225
180185
180167
180156
180145
180125
180085
180084
180082
179980
179978
179975
179942
179935
179895
179861
179850
179849
179815
179722
179704
179695
179688
179676
179652
179646
179623
179621
179585
179555
179551
179493
179489
179474
179471
179470
179461
179457
179451
179430
179355
179344
179331
179316
179282
179229
179226
179219
179205
179204
179166
179160
179151
179149
179147
179139
178752
178743
178677
178675
178674
178624
178606
178594
178591
178528
178526
178521
178520
178519
178493
178457
178452
178447
178390
178388
178369
178364
178349
178348
178347
178330
178319
178303
178302
178294
178287
178269
178236
178220
178219
178214
178203
178191
178187
178164
178159
178129
178100
178098
178054
178051
178048
178042
178034
178016
177467
177465
177453
177449
177447
177443
177431
177430
177412
177360
177353
177350
177337
177327
177309
178008
177999
177998
177992
177991
177984
177973
177972
177971
177948
177852
177830
177820
177812
177763
177706
177681
177659
177648
177647
177641
177628
177613
177611
177550
177293
177288
177280
177277
177265
177262
177257
177225
177213
177198
177172
177159
177146
177152
177108
177095
177092
177048
177046
177035
176822
176752
176739
176688
176678
176631
176609
176602
176525
176338
176333
176314
176305
176249
176238
184219
184215
184209
184206
184201
184199
184164
184087
184076
184069
184059
184029
184013
183993
183952
183888
183882
183868
183824
183817
183815
183812
183791
183777
183715
183705
183670
183613
183573
182974
182983
182985
182989
182997
183007
183051
183060
183054
183053
183097
183119
183108
183139
183141
183155
183163
183169
183180
183191
183196
183214
183244
183266
183278
183275
183309
183402
183422
183440
182974
182964
182958
182956
182916
182855
182854
182820
182787
182800
182809
182780
182772
182770
182766
182754
182742
182740
182723
182707
182647
182643
182614
182595
182563
182557
182547
182546
182538
182530
182517
182498
182478
182452
182386
182352
182285
182266
182260
182230
182224
182223
182191
182185
182182
182179
182106
182101
182072
181966
181965
181937
181928
181925
181924
181923
181900
181895
181860
181847
181836
181833
181811
181809

307
export_build_info/pids/双人.txt

@ -1,307 +0,0 @@ @@ -1,307 +0,0 @@
181593
181384
181337
181318
181263
181240
181211
181197
181187
181140
181103
181091
181054
181027
180763
180690
180684
180677
180599
180576
180389
180342
180337
180277
180265
180253
180101
180083
179905
179842
179811
179808
179791
179786
179700
179634
179593
179576
179485
179459
179400
179351
178995
178898
178750
178746
178723
178680
178673
178654
178527
178482
178465
178430
178413
178409
178297
178286
178281
178105
178062
178026
178025
178019
178017
178004
177851
177678
177677
177646
177545
177520
177300
177080
176757
176743
176648
176290
176280
176273
176247
184082
184074
184068
184061
184041
183893
183890
183810
183755
183680
183656
183592
183591
183589
183025
183086
183104
183162
183444
182907
182915
182871
182804
182778
182718
182675
182664
182625
182623
182542
182510
182473
182455
182388
182365
182343
182316
181957
181948
181941

28
export_build_info/pids/多人.txt

@ -1,28 +0,0 @@ @@ -1,28 +0,0 @@
180891
180673
180584
180468
180164
180091
179992
179962
178627
178416
178255
178066
177983
177722
183832
183677
183183
183351
183361
183360
182853
182715
182630
182367
182253
182057
181868
181856

13
install.txt

@ -1,13 +0,0 @@ @@ -1,13 +0,0 @@
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip config set install.trusted-host pypi.tuna.tsinghua.edu.cn
python -m pip install --upgrade pip
pip install oss2 redis MySQLdb pillow numpy opencv-python bpy tqdm pyautogui psutil pywin32 pymysql
config
set bin="C:\Program Files\Capturing Reality\RealityCapture\RealityCapture.exe"
%bin% -disableOnlineCommunication -setInstanceName %pid%
%bin% -disableOnlineCommunication -delegateTo %pid%
%bin% -set "appCacheLocation=ProjectFolder"

13
libs/install.txt

@ -1,13 +0,0 @@ @@ -1,13 +0,0 @@
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
pip config set install.trusted-host pypi.tuna.tsinghua.edu.cn
python -m pip install --upgrade pip
pip install oss2 redis MySQLdb pillow numpy opencv-python bpy tqdm pyautogui psutil pywin32 pymysql
config
set bin="C:\Program Files\Capturing Reality\RealityCapture\RealityCapture.exe"
%bin% -disableOnlineCommunication -setInstanceName %pid%
%bin% -disableOnlineCommunication -delegateTo %pid%
%bin% -set "appCacheLocation=ProjectFolder"

101
main_repeat_texture.py

@ -1,101 +0,0 @@ @@ -1,101 +0,0 @@
#读取需要重新贴图的数据
import os,sys,time,shlex,subprocess,shutil
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 libs_db_repeat_texture
import libs,config
#读取 数据库的信息
def get_pid():
data = libs_db_repeat_texture.get_pid_task()
if data != None and data != "error":
return data[0],data[1]
else:
return None,None
#开始处理任务
def start_task(pid):
#下载Obj数据
print(f"处理{pid}任务")
print("开始下载{pid}数据")
# pid = str("175635")
complateCloudPath = libs.down_obj_from_oss_for_repeat_texture(config.workdir, pid,"auto")
if complateCloudPath == "error":
return -1,"error-从oss上下载出问题"
#下载下来之后重新加载obj 和texture
print("complateCloudPath",complateCloudPath)
outPath = os.path.join(config.workdir, pid, "output")
if os.path.exists(outPath):
print("移除文件夹")
#移除文件夹
shutil.rmtree(outPath)
cmd = f'{config.rcbin} {config.r2["init"]} -setInstanceName {pid} \
-load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" \
-importModel "{os.path.join(complateCloudPath, f"{pid}.obj")}" \
-calculateTexture -exportSelectedModel "{os.path.join(config.workdir, pid, "output", f"{pid}.obj")}" "d:\\make2\\config\\ModelExportParams0722.xml" -quit'
print(cmd)
cmd = shlex.split(cmd)
res = subprocess.run(cmd)
#检查out目录文件夹是否有多个 贴图文件。如果是的话只保留最新的一个,并且重命名为初始图像的名称
outFilePath = os.path.join(config.workdir, pid, "output")
arrTempImage = []
for file in os.listdir(outFilePath):
if file.endswith(".jpg") or file.endswith(".png"):
#字符串替换
fileTempName = file.replace(f"{pid}_u0_v0_diffuse","")
fileTempName = fileTempName.replace(".jpg","")
fileTempName = fileTempName.replace(".png","")
if "_" in fileTempName:
fileTempName = fileTempName.replace("_","")
arrTempImage.append(fileTempName)
print(arrTempImage)
if len(arrTempImage) > 1:
#获取 arrTempImage 中最大的值
arrTempImage.sort()
print(arrTempImage)
#获取最大值
maxValue = arrTempImage[-1]
for i in arrTempImage:
if i == "":
filePath1 = os.path.join(config.workdir, pid, "output",pid+"_u0_v0_diffuse.jpg")
filePath2 = os.path.join(config.workdir, pid, "output",pid+"_u0_v0_diffuse.png")
else:
filePath1 = os.path.join(config.workdir, pid, "output",pid+"_u0_v0_diffuse_"+str(i)+".jpg")
filePath2 = os.path.join(config.workdir, pid, "output",pid+"_u0_v0_diffuse_"+str(i)+".png")
if i != maxValue:
if os.path.exists(filePath1):
os.remove(filePath1)
if os.path.exists(filePath2):
os.remove(filePath2)
else:
if os.path.exists(filePath1):
os.rename(filePath1,os.path.join(config.workdir, pid, "output",pid+"_u0_v0_diffuse.jpg"))
if os.path.exists(filePath2):
os.rename(filePath2,os.path.join(config.workdir, pid, "output",pid+"_u0_v0_diffuse.jpg"))
#执行step3
os.system(f'python d:\\make2\\main_step3.py {pid}')
return 3,"success"
if __name__ == '__main__':
while True:
id,pid = get_pid()
print(f"读取的数据{pid}")
if pid != None:
#更新状态为2
libs_db_repeat_texture.update_status(id,2)
statusres,res = start_task(str(pid))
libs_db_repeat_texture.update_status(id,statusres)
else:
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}-没有任务')
time.sleep(10)

68
old_step2.py

@ -1,68 +0,0 @@ @@ -1,68 +0,0 @@
import os, sys, time, shutil, subprocess, shlex, json
import xml.etree.ElementTree as ET
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,common
def old_step2(pid):
cmd = f'"C:\\Program Files\\Capturing Reality\\RealityCapture\\RealityCapture.exe" -disableOnlineCommunication -set \"sfmEnableCameraPrior=False\" -set \"sfmMaxFeaturesPerMpx=20000\" -set \"sfmMaxFeaturesPerImage=200000\" -set \"sfmImagesOverlap=High\" -set \"sfmMaxFeatureReprojectionError=1\" -addFolder "D:\\{pid}\\photo1" -addFolder "D:\\{pid}\\photo2" -importControlPointsMeasurements "D:\\{pid}\\{pid}.controlPoints.csv" -align -save "D:\\{pid}\\{pid}.rcproj" -quit'
cmd = shlex.split(cmd)
res = subprocess.run(cmd)
time.sleep(2)
#修改rcproj文件
flag = common.changeRcprojControlpointsFile(pid)
if flag == False:
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} point文件不存在')
exit()
simplify_value = 1000000 * libs.getHeadCount(pid)
cmd = f'"C:\\Program Files\\Capturing Reality\\RealityCapture\\RealityCapture.exe" -load "D:\\{pid}\\{pid}.rcproj" -set "sfmEnableCameraPrior=True" -align -set "sfmEnableCameraPrior=False" -align -setReconstructionRegion "D:\\{pid}\\{pid}.rcbox" -mvs -modelSelectMaximalConnectedComponent -modelInvertSelection -modelRemoveSelectedTriangles -closeHoles -clean -simplify {simplify_value} -smooth -unwrap -calculateTexture -renameModel {pid} -save "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}" -quit'
cmd = shlex.split(cmd)
res = subprocess.run(cmd)
time.sleep(3)
#修改rcproj文件
flag = common.changeRcprojFile(pid)
if flag == False:
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} rcproj文件不存在')
exit()
#创建指定文件夹
if not os.path.exists(os.path.join(config.workdir, pid, "output")):
os.makedirs(os.path.join(config.workdir, pid, "output"))
#执行导出
cmd = f'{config.rcbin} -load "{os.path.join(config.workdir, pid, f"{pid}.rcproj")}"\
-exportModel "{pid}" "{os.path.join(config.workdir, pid, "output", f"{pid}.obj")}" "d:\\make2\\config\\ModelExportParams102.xml" -quit'
print(cmd)
cmd = shlex.split(cmd)
res = subprocess.run(cmd)
#阻塞判断是否导出完成
while True:
#判断 output 目录下是否存在 三个文件
files = os.listdir(os.path.join(config.workdir, pid, "output"))
if len(files) >= 3:
break
#暂时 step2 step3 一起连续执行
print('step2 执行完,开始执行step3')
os.system(f'python d:\\make2\\main_step3.py {pid}')
if __name__ == '__main__':
pid = '0'
if len(sys.argv) == 1:
exit()
else:
pids = sys.argv[1].split(',')
for pid in pids:
old_step2(str(pid))
exit()

499
pid.text

@ -1,499 +0,0 @@ @@ -1,499 +0,0 @@
189002
189819
190152
190141
190204
190210
190221
190234
190257
190264
190297
190377
190238
190409
190417
190144
190233
189879
190227
190463
190510
190531
164671
190241
190547
188521
190609
184467
188521
189772
188521
190724
190506
190509
190511
190578
183895
190584
190605
190611
190620
190635
190683
190684
190694
190697
190708
190726
183494
185507
188521
183494
190751
183895
190754
183895
189002
190784
190783
190795
190812
183895
190823
190837
190910
190838
190866
190905
190915
190927
190944
190939
190932
190379
190948
190959
190980
190975
190927
190996
190981
191001
190927
190992
182361
185080
191045
185416
191069
191082
191081
191103
191118
191116
191152
191180
191125
191227
191238
191246
191234
191275
191320
191283
191354
191388
191435
191441
191431
191380
191340
191350
191297
191472
191255
191268
191501
191192
191156
191517
191515
191525
191532
191261
191422
191024
191542
191587
191597
191676
191678
191711
191736
186628
191874
191937
191924
191945
191887
191868
191981
191885
191838
191882
191965
191822
191870
191920
191894
191811
191739
191681
191790
191738
191699
191781
191733
191746
191793
191829
191834
191907
191927
191969
191990
191998
192005
192021
192023
192026
191771
190829
192038
191906
192095
192107
192098
192123
191066
192150
192161
192178
191210
191849
191832
192093
192199
192208
192202
192213
192211
192204
183783
192220
192267
192223
190880
192288
188877
192283
192291
192079
192077
192072
192063
188201
192343
192353
192367
192373
192222
192399
192392
189979
189988
189996
190692
190709
191955
191912
192444
192438
187727
192479
192473
192469
192476
192140
192143
192158
192498
192169
192175
192186
192187
192197
192214
190362
192236
192239
192241
192242
192244
192248
192304
192261
192421
192425
192514
192162
192548
192550
184779
192495
192490
192583
192586
192591
192593
192595
184756
192235
187195
192378
192622
192129
192570
192566
192480
192481
192484
192482
192532
192624
192630
192682
192674
192690
192701
188185
192725
192729
192608
192732
192717
192609
192611
192612
192615
192744
192643
192650
192653
192659
192776
192664
192676
192680
192758
192759
192767
192775
192782
192783
185658
192838
192873
192875
192905
192895
192869
187718
188167
192929
192940
192955
192947
192907
192908
192887
192979
193038
193003
193005
192875
193112
193101
193085
193082
192986
192944
193132
193141
193058
193160
193074
193217
193239
192208
193285
193260
193287
193288
193298
193281
193335
193332
193349
193165
193185
193010
193231
193364
193295
193313
193339
193354
193357
193360
193375
193376
193377
193378
193353
193193
193454
192317
193405
193468
193475
193483
193479
193486
193508
193504
193511
193503
193520
193562
193571
193560
193237
193569
193591
193590
193593
193617
193615
193637
193625
193642
193646
193683
193671
193677
193616
193702
193700
193604
193721
193745
193770
193768
193758
193762
193636
193652
190141
193771
193781
193813
193806
193812
193818
193835
193863
193907
193832
193896
193903
193906
193380
193383
193384
193925
193386
193480
193387
193666
193711
193757
193934
193778
193795
193809
193822
193817
193843
193918
193876
193922
193567
193564
193551
192320
193117
193961
193969
193524
193547
193990
193995
194012
194022
194027
194021
194069
194048
194035
194070
194015
194018
194093
194098
194144
194104
194112
194119
194108
194126
194153
194163
194044
194047
194206
194004
194229
194218
194240
194242
194278
194271
194293
194081
194173
194176
194211
194245
194270
194285
194292
194294
194296
194300
194347
190480
190483
194258
194266,194276,194444,194419,194454,194471,194470,194473,194475,194480,194493,194497,194499,194480,194460,192716,194465,194514,194515,194527,194501,194500,194526,194531,194536,194540,194551,194564,194577,194582,194580,187324,194599,194601,194628,194625,194623,189048,186982,194627,194508,194510,189048,194640,194642,194654,194685,194686,194707,194720,194719,194744,194734,194634,194738,194760,194765,194764,194768,194774,190697,194566,194356,194365,194369,194806,194376,194064,194772,194097,194773,194100,194103,194812,194810,194223,194181,194178,194589,194588,186685,194831,194830,194832,194834,194854,194817,194878,191283,191321,194900,194904,194858,194901,194885,194916,194924,194925,194802,194927,194932,194906,194908,194911,194912,194914,194915,194917,194920,194953,194926,194928,194930,194935,194957,194817,190531,189819,194989,194987,194995,194996,192305,194998,195015,195013,195023,195018,195021,195032,195005,195050,189864,195067,195072,195091,195026,195031,195104,195029,195102,195051,195063,195093,195125,195146,193800,195160,195172,195154,195184,194210,186610,191005,187854,193794,

5
step.text

@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
old version
init:
'"C:\\Program Files\\Capturing Reality\\RealityCapture\\RealityCapture.exe" -disableOnlineCommunication -set \"sfmEnableCameraPrior=False\" -set \"sfmMaxFeaturesPerMpx=20000\" -set \"sfmMaxFeaturesPerImage=200000\" -set \"sfmImagesOverlap=High\" -set \"sfmMaxFeatureReprojectionError=1\" -addFolder "D:\\{pid}\\photo1" -addFolder "D:\\{pid}\\photo2" -importControlPointsMeasurements "D:\\{pid}\\{pid}..controlPoints.csv" -align -save'

1028
suwa_cut_foot_cut_normal_data.txt

File diff suppressed because it is too large Load Diff

BIN
task_distributed_error.log

Binary file not shown.

18
test.py

@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
import re
def extract_o_option(file_path):
pattern = re.compile(r'o\s+(\S+)')
with open(file_path, 'r') as file:
for line in file:
match = pattern.search(line)
if match:
return match.group(1)
return None
# 使用示例
file_path = 'C:/Users/Administrator/Desktop/29282/29282_9cm_x1.obj'
result = extract_o_option(file_path)
if result:
print(f'Found -o option with value: {result}')
else:
print('No -o option found')

21
test1.py

@ -1,21 +0,0 @@ @@ -1,21 +0,0 @@
# -*- coding: utf-8 -*-
import os
import oss2
# 填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
endpoint = 'https://oss-cn-shanghai.aliyuncs.com'
# 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
access_key_id = 'LTAI5tSj7s2mKZNqamT1x64v'
access_key_secret = 'iIqeBLB8R2U72pAwJbZZBB6tuB3ZF9'
# 指定文件所在的Bucket名称,例如examplebucket。
bucket_name = 'suwa3d-securedata'
# Object完整路径,完整路径中不能包含Bucket名称。
key = 'photos/141640/photo2/72_8.jpg'
# 指定Bucket实例,所有文件相关的方法都需要通过Bucket实例来调用。
bucket = oss2.Bucket(oss2.Auth(access_key_id, access_key_secret), endpoint, bucket_name)
style = 'image/bodies'
# 生成带签名的URL,并指定过期时间为10分钟。过期时间单位为秒。
url = bucket.sign_url('GET', key, 10 * 60, params={'x-oss-process': style})
print(url)

202
timer/external_order_glb.py

@ -0,0 +1,202 @@ @@ -0,0 +1,202 @@
import os, sys, time, bpy, math, requests, bmesh, json, shutil
from PIL import Image
import platform,redis
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,common,foot_mark_seam,libs_db_gpu
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 find_pid_objname(pid):
for obj in bpy.data.objects:
if obj.name.startswith(str(pid)):
return obj.name
#加载obj文件
def reload_obj(pid):
#下载obj文件
libs.down_obj_from_oss(config.workdir, pid, "print")
# obj = reload_obj(pid, action)
obj_filename = os.path.join(config.workdir,'print',pid,f'{pid}.obj')
bpy.ops.wm.read_homefile()
bpy.ops.object.delete(use_global=False, confirm=False)
bpy.ops.import_scene.obj(filepath=obj_filename)
bpy.context.scene.unit_settings.scale_length = 1
bpy.context.scene.unit_settings.length_unit = 'CENTIMETERS'
bpy.context.scene.unit_settings.mass_unit = 'GRAMS'
obj = bpy.context.selected_objects[0]
bpy.context.view_layer.objects.active = obj
obj.select_set(True)
def base_fix(pid):
# 统一blender环境
reload_obj(pid)
# 统一模型方向、位置、大小...
pid_objname = find_pid_objname(pid)
obj = bpy.data.objects[pid_objname]
bpy.data.objects[pid_objname].rotation_euler = (0, 0, 0)
# 检查当前模型是否正确使用 z 轴作为高度轴
if obj.dimensions.z < obj.dimensions.y:
# 如果 z 轴比 y 轴小,说明高度错误,应该旋转调整模型
print(f"警告:模型的高度轴(z)似乎不正确,使用 y 轴作为高度。正在修正模型方向...")
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True) # 应用当前变换
obj.rotation_euler[0] = math.radians(90) # 旋转模型 90 度,交换 z 和 y 轴
bpy.ops.object.transform_apply(rotation=True) # 应用旋转
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)
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 模型基础校正完成')
def export_and_update_glbs(pid):
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 开始导出并上传审核模型和3D相册模型glb文件...')
start_time = time.time()
#headcount = libs.getHeadCount(pid)
headcount = 1
pid_objname = find_pid_objname(pid)
obj = bpy.data.objects[pid_objname]
obj.select_set(True)
model_info = {}
model_info['headcount'] = headcount
model_info['faces'] = round(len(obj.data.polygons) / 10000)
model_info['height'] = round(obj.dimensions.y * 100)
# bpy.ops.wm.save_as_mainfile(filepath=os.path.join(config.workdir, pid, f'{pid}.blend'))
# 统一缩放到9cm标准尺寸
scale = 90 / bpy.data.objects[pid_objname].dimensions.y
bpy.data.objects[pid_objname].scale = (scale, scale, scale)
bpy.ops.object.transform_apply(scale=True)
# bpy.ops.wm.save_as_mainfile(filepath=os.path.join(config.workdir, pid, f'{pid}-9cm.blend'))
bm = bmesh_copy_from_object(obj)
model_info['volume'] = round(bm.calc_volume(), 2)
model_info['weight'] = round(model_info['volume'] * 1.226, 2)
print(f'{pid}的模型数据:{model_info}')
res = requests.get(f'{config.urls["upload_model_info_url"]}?pid={pid}&headcount={headcount}&faces={model_info["faces"]}&volume={model_info["volume"]}&weight={model_info["weight"]}&height={model_info["height"]}')
print('上传模型数据:', res.text)
# with open(os.path.join(config.sharedir, 'model_info', f'{pid}.json'), 'w') as f:
# json.dump(model_info, f)
# f.close()
# 先生成审核模型
faces_dest = 500000 * headcount
# 减面
faces_current = len(bpy.data.objects[pid_objname].data.polygons)
print(f'当前面数:{faces_current},目标面数:{faces_dest}')
bpy.ops.object.modifier_add(type='DECIMATE')
bpy.context.object.modifiers["Decimate"].ratio = faces_dest / faces_current
bpy.ops.object.modifier_apply(modifier="Decimate")
# glb_filename = os.path.join(config.workdir, pid, 'output', f'{pid}.glb')
# bpy.ops.export_scene.gltf(filepath=glb_filename, export_format='GLB', export_apply=True, export_jpeg_quality=75, export_draco_mesh_compression_enable=False)
# 再生成数字模型
faces_dest = 120000 * headcount
# 减面
faces_current = len(bpy.data.objects[pid_objname].data.polygons)
print(f'当前面数:{faces_current},目标面数:{faces_dest}')
bpy.ops.object.modifier_add(type='DECIMATE')
bpy.context.object.modifiers["Decimate"].ratio = faces_dest / faces_current
bpy.ops.object.modifier_apply(modifier="Decimate")
glb_filename = os.path.join(config.workdir,'print',pid,f'{pid}-3d.glb')
bpy.ops.export_scene.gltf(filepath=glb_filename, export_format='GLB', export_apply=True, export_jpeg_quality=75, export_draco_mesh_compression_enable=False)
# os.system(f'gltfpack -c -i {os.path.join(config.workdir, pid, "output", f"{pid}.glb")} -o {os.path.join(config.workdir, pid, "output", f"{pid}-pack.glb")}')
# config.oss_bucket.put_object_from_file(f'glbs/auto/{pid}.glb', os.path.join(config.workdir, pid, 'output', f'{pid}-pack.glb'))
config.oss_bucket.put_object_from_file(f'glbs/3d/{pid}.glb', os.path.join(config.workdir,'print',pid, f'{pid}-3d.glb'))
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} glb文件导出并上传完成,共费时{libs.diff_time(start_time)}')
#移除文件夹
shutil.rmtree(os.path.join(config.workdir,'print',pid))
#更新该笔订单的状态为 3000
requests.post("https://shop.api.suwa3d.com/api/printOrder/updateExternalOrderStatus", data={'pid': pid})
def createGlb(pid):
#移除文件夹
try:
shutil.rmtree(os.path.join(config.workdir,'print',pid))
except:
pass
base_fix(pid)
export_and_update_glbs(pid)
if __name__ == '__main__':
arrArgs = sys.argv
if len(arrArgs) == 2:
pid = arrArgs[1]
#判断是否是数字
if pid.isdigit():
print('请输入正确的pid')
createGlb(str(pid))
else:
r = redis.Redis(host="106.14.158.208",password="kcV2000",port=6379,db=6)
while True:
if r.llen('model:3dglb') == 0:
print('队列为空,等待10秒')
time.sleep(10)
continue
info = r.lpop('model:3dglb')
if info is None:
print('队列为空,等待10秒')
time.sleep(10)
pid = info.decode('utf-8')
if not pid.isdigit():
continue
createGlb(pid)

28
timer/init_timer.py

@ -1,8 +1,26 @@ @@ -1,8 +1,26 @@
import time,os
import os
import time as t
from datetime import datetime, time
def is_time_in_range(start_time_str, end_time_str):
# 获取当前时间
now = datetime.now().time()
# 转换字符串时间为时间对象
start_time = datetime.strptime(start_time_str, '%H:%M').time()
end_time = datetime.strptime(end_time_str, '%H:%M').time()
# 检查当前时间是否在指定范围内
return start_time <= now <= end_time
if __name__ == '__main__':
start_time_str = '07:00'
end_time_str = '23:59'
#开启死循环
while True:
#检测当前打印 和 脚底板 和 gs 队列长度
os.system("python E:\\make2\\tools\\push_cmd.py auto_view")
#一个小时检测一次
time.sleep(60*60)
#判断当前时间是否在 8:00-20:00 之间
if is_time_in_range(start_time_str, end_time_str):
#检测当前打印 和 脚底板 和 gs 队列长度
os.system("python E:\\make2\\tools\\push_cmd.py auto_view")
#一个小时检测一次
t.sleep(60*60)

16
tools/push_cmd.py

@ -21,6 +21,8 @@ def main(cmd, order_id): @@ -21,6 +21,8 @@ def main(cmd, order_id):
key = 'model:rebuild'
elif cmd == 'gs':
key = 'ai:ai_build'
elif cmd == 'gs_normals_image':
key="model:gs_normals_image"
if order_id == 'view':
if cmd == "rc_model_build":
@ -28,6 +30,7 @@ def main(cmd, order_id): @@ -28,6 +30,7 @@ def main(cmd, order_id):
print(f'当前{cmd}队列长度:{nums}')
notify(f'当前{cmd}队列长度:{nums}')
else:
print(f"key-{key}")
print(f'当前{cmd}队列长度:{r.llen(key)}')
notify(f'当前{cmd}队列长度:{r.llen(key)}')
@ -73,14 +76,17 @@ def cmd(cmdName,pid): @@ -73,14 +76,17 @@ def cmd(cmdName,pid):
key = 'model:foot'
if pid == 'view':
# for i in r.lrange(key, 0, -1):
# print(i)
temp = ""
for i in r.lrange(key, 0, -1):
print(i)
temp += i.decode('utf-8') + ","
print(temp)
print(f'当前{cmd}队列长度:{r.llen(key)}')
notify(f'当前{cmd}队列长度:{r.llen(key)}')
exit()
else:
for i in r.lrange(key, 0, -1):
print(i)
# for i in r.lrange(key, 0, -1):
# print(i)
print(f'当前{key}队列长度:{r.llen(key)}')
exit()
@ -180,7 +186,7 @@ if __name__ == '__main__': @@ -180,7 +186,7 @@ if __name__ == '__main__':
cmd = sys.argv[1]
order_id = 'view'
if cmd == "auto_view":
arrCmd = ["print","foot","gs","rc_model_build"]
arrCmd = ["print","foot","gs","rc_model_build","gs_normals_image"]
for cmdV in arrCmd:
main(cmdV, order_id)

40
yj_local_build/ModelExportParams.xml

@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
<Configuration>
<entry key="ModelExportFormatVersion" value="0"/>
<entry key="MvsMeshExportCamerasAsModelPart" value="false"/>
<entry key="MvsMeshExportTexturingAllowed" value="-1"/>
<entry key="MvsExportIsModelCoordinates" value="0"/>
<entry key="MvsExportIsGeoreferenced" value="0x1"/>
<entry key="MvsExportScaleZ" value="1.0"/>
<entry key="MvsMeshExportTileType" value="0"/>
<entry key="MvsMeshExportNormals" value="false"/>
<entry key="MvsExportScaleY" value="1.0"/>
<entry key="MvsMeshExportTexAlpha" value="false"/>
<entry key="MvsExportScaleX" value="1.0"/>
<entry key="MvsMeshExportTexImgFormat_Color8_0" value="jpg"/>
<entry key="MvsExportcoordinatesystemtype" value="0"/>
<entry key="MvsMeshExportTexPixFormat_Color8_0" value="32bppBGRA"/>
<entry key="MvsMeshExportNormalsAllowed" value="-1"/>
<entry key="MvsMeshExportNumberFormatAllowed" value="-1"/>
<entry key="MvsExportMoveZ" value="0.0"/>
<entry key="MvsExportMoveX" value="0.0"/>
<entry key="MvsExportMoveY" value="0.0"/>
<entry key="MvsExportNormalRange" value="ZeroToOne"/>
<entry key="MvsMeshExportInfoFile" value="true"/>
<entry key="MvsMeshExportByParts" value="0"/>
<entry key="MvsMeshExportClassificationAllowed" value="0"/>
<entry key="MvsMeshExportNumberFormat" value="5"/>
<entry key="MvsExportRotationY" value="0.0"/>
<entry key="MvsExportNormalFlipZ" value="false"/>
<entry key="MvsExportRotationX" value="0.0"/>
<entry key="MvsExportNormalFlipY" value="false"/>
<entry key="MvsMeshExportCamerasAllowed" value="0"/>
<entry key="MvsMeshExportColors" value="true"/>
<entry key="MvsExportNormalSpace" value="Mikktspace"/>
<entry key="MvsExportNormalFlipX" value="false"/>
<entry key="MvsExportTransformationPreset" value="[[Default]]"/>
<entry key="MvsExportRotationZ" value="0.0"/>
<entry key="MvsMeshExportFileTypeSelectionDisplay" value="0"/>
<entry key="MvsMeshExportTexOneFile" value="1"/>
<entry key="MvsMeshExportTexturing" value="-1"/>
<entry key="MvsMeshExportEmbeddTxrsAllowed" value="0"/>
</Configuration>

17
yj_local_build/config.json

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
{
"workdir": "D://",
"local_need_build": "/\\172.31.1.253/modeling/local_need_build",
"local_complate_build":"/\\172.31.1.253/modeling/local_complate_build",
"rcbin": "'C:\\Program Files\\Capturing Reality\\RealityCapture\\RealityCapture.exe'",
"urls": {
"update_status_modelsuccess_url": "http://172.16.20.13:8383/update_take_photo"
},
"r": {
"setTextureTrue": "-selectAllImages -enableTexturingAndColoring true",
"setTextureFalse": "-selectAllImages -enableTexturingAndColoring false"
},
"r2": {
"init": "-disableOnlineCommunication -setProjectCoordinateSystem Local:1 -setOutputCoordinateSystem epsg:4326 -set \"sfmEnableCameraPrior=False\" -set \"sfmMaxFeaturesPerMpx=20000\" -set \"sfmMaxFeaturesPerImage=200000\" -set \"sfmImagesOverlap=High\" -set \"sfmMaxFeatureReprojectionError=1\"",
"setRegion": "-setReconstructionRegionOnCPs 36h11:001 36h11:002 36h11:003 2.1 -moveReconstructionRegion 0 0 -2.1 -rotateReconstructionRegion 180 0 180 -setGroundPlaneFromReconstructionRegion -scaleReconstructionRegion 1.8 1.6 2.1 absolute center -moveReconstructionRegion 0 0 0.0025"
}
}

26
yj_local_build/config.py

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
workdir = 'D://' #建模过程数据存放的目录
local_need_build = '/\\172.31.1.253/modeling/local_need_build' #需要建模的数据存放目录
local_complate_build = '/\\172.31.1.253/modeling/local_complate_build' #建模完成的存放目录
rcbin = '"C:\\Program Files\\Capturing Reality\\RealityCapture\\RealityCapture.exe"'
urls = {
'update_status_modelsuccess_url': 'http://172.16.20.13:8383/update_take_photo',
}
r = {
"setTextureTrue" : "-selectAllImages -enableTexturingAndColoring true",
"setTextureFalse" : "-selectAllImages -enableTexturingAndColoring false",
}
r1 = {
"init" : "-disableOnlineCommunication -set \"sfmEnableCameraPrior=False\" -set \"sfmMaxFeaturesPerMpx=20000\" -set \"sfmMaxFeaturesPerImage=200000\" -set \"sfmImagesOverlap=High\" -set \"sfmMaxFeatureReprojectionError=1\"",
}
r2 = {
"init" : "-disableOnlineCommunication -setProjectCoordinateSystem Local:1 -setOutputCoordinateSystem epsg:4326 -set \"sfmEnableCameraPrior=False\" -set \"sfmMaxFeaturesPerMpx=20000\" -set \"sfmMaxFeaturesPerImage=200000\" -set \"sfmImagesOverlap=High\" -set \"sfmMaxFeatureReprojectionError=1\"",
"setRegion" : "-setReconstructionRegionOnCPs 36h11:001 36h11:002 36h11:003 2.1 -moveReconstructionRegion 0 0 -2.1 -rotateReconstructionRegion 180 0 180 -setGroundPlaneFromReconstructionRegion -scaleReconstructionRegion 1.8 1.6 2.1 absolute center -moveReconstructionRegion 0 0 0.0025"
}
rH = {
"init" : "-disableOnlineCommunication -set \"sfmEnableCameraPrior=False\" -set \"sfmMaxFeaturesPerMpx=10000\" -set \"sfmMaxFeaturesPerImage=80000\" -set \"sfmImagesOverlap=High\" -set \"sfmMaxFeatureReprojectionError=2\"",
}

7
yj_local_build/detectMarkers.config.xml

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
<Configuration id="{8D21413B-0848-49A9-BF6E-8EBCCA356BC7}">
<entry key="minMarkerMeasurements" value="0x1"/>
<entry key="generateMarkersPaperSize" value="0"/>
<entry key="generateMarkersMarkersPerPage" value="0x4"/>
<entry key="generateMarkersCount" value="0x4"/>
<entry key="markerType" value="AprilTag36h11"/>
</Configuration>

6
yj_local_build/exportControlPoints.config.xml

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
<Configuration id="{E80BAEB3-7A87-4889-B150-0CF6486D7089}">
<entry key="icpsAcc" value="4.0"/>
<entry key="csvCPMSep" value="2"/>
<entry key="icpsTmode" value="1"/>
<entry key="csvCPMIgn" value="false"/>
</Configuration>

8
yj_local_build/exportXMP.config.lock.xml

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
<Configuration id="{EC40D990-B2AF-42A4-9637-1208A0FD1322}">
<entry key="xmpMerge" value="true"/>
<entry key="xmpExGps" value="true"/>
<entry key="xmpFlags" value="true"/>
<entry key="xmpCalibGroups" value="true"/>
<entry key="xmpCamera" value="3"/>
<entry key="xmpRig" value="true"/>
</Configuration>

139
yj_local_build/libs.py

@ -0,0 +1,139 @@ @@ -0,0 +1,139 @@
import os, time, json, requests, shutil, psutil
from tqdm import tqdm
from PIL import Image, ImageEnhance
import config
from concurrent.futures import ThreadPoolExecutor
def find_blender_bin_path():
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)
# def resize_photos(photo_path, ratio=0.5):
# for filename in os.listdir(photo_path):
# if filename.endswith('.jpg'):
# img = Image.open(os.path.join(photo_path, filename))
# img = rotate_image(img)
# w, h = img.size
# img = img.resize((int(w * ratio), int(h * ratio)))
# img.save(os.path.join(photo_path, filename))
# def rotate_image(image):
# # 检查图像的EXIF数据是否包含方向信息
# try:
# exif = image._getexif()
# orientation = exif.get(0x0112)
# except:
# orientation = None
# # 根据方向信息旋转图像
# if orientation == 3:
# image = image.rotate(180, expand=True)
# elif orientation == 6:
# image = image.rotate(270, expand=True)
# elif orientation == 8:
# image = image.rotate(90, expand=True)
# return image
# def get_ps_adjust_photo_para(psid):
# res = requests.get(config.urls['get_ps_adjust_photo_para_url'], params={'id': psid})
# print(res.json())
# paras = res.json()['data']
# brightness_factor, saturation_factor, temperature_factor = float(paras['brightness']), float(paras['saturation']), float(paras['colorTemperature'])
# return brightness_factor, saturation_factor, temperature_factor
# def getPSid(pid):
# res = requests.get(config.urls['get_psid_url'], params={'pid': pid})
# print('get_psid_url:', res.url)
# print('res:', res.text)
# res = json.loads(res.text)
# return str(res['data'])
# def getHeadCount(pid):
# return 1
# res = requests.get(config.urls['get_printinfo_url'], params={'id': pid})
# print('get_printinfo_url:', res.url)
# print('res:', res.text)
# if res.status_code != 200:
# print('获取人数失败,程序退出')
# exit(1)
# res = json.loads(res.text)
# return res['data']['headcount']
# def get_ps_type(pid):
# # return 1:圆形影棚 2:方形影棚
# #res = requests.get(config.urls['get_ps_type_url'], params={'pid': pid})
# return 2
# def find_valid_camera_on_oss(pid):
# if get_ps_type(pid) == 1:
# print('当前拍照影棚为:圆形影棚')
# cameras = (103, 93, 113)
# else:
# print('当前拍照影棚为:方形影棚')
# cameras = (74, 64, 84)
# find_camera = 0
# for camera in cameras:
# objectkey = f'photos/{pid}/photo2/{camera}_8.jpg'
# find = config.oss_bucket.object_exists(objectkey)
# if find:
# find_camera = camera
# break
# print('找到有效正脸相机:', find_camera)
# if find_camera == 0:
# print('{cameras}没有找到照片,程序退出')
# exit(1)
# return find_camera
# def set_photos_join_type(workdir, pid, photoN, mesh = '0', texture='0'):
# photoN_path = os.path.join(workdir, pid, photoN)
# for xmp in os.listdir(photoN_path):
# if xmp.endswith('.xmp'):
# xmp_path = os.path.join(photoN_path, xmp)
# with open(xmp_path, 'r') as f:
# lines = f.readlines()
# lines = [line.replace('xcr:InMeshing="0"', f'xcr:InMeshing="{mesh}"') for line in lines]
# lines = [line.replace('xcr:InMeshing="1"', f'xcr:InMeshing="{mesh}"') for line in lines]
# lines = [line.replace('xcr:InTexturing="0"', f'xcr:InTexturing="{texture}"') for line in lines]
# lines = [line.replace('xcr:InTexturing="1"', f'xcr:InTexturing="{texture}"') for line in lines]
# with open(xmp_path, 'w') as f:
# f.writelines(lines)
def set_photo_join_type(workdir, pid, photoN, camera_id, mesh = '0', texture='0'):
if photoN == 'photo1':
filename = os.path.join(workdir, pid, photoN, f'{camera_id}_1.xmp')
else:
filename = os.path.join(workdir, pid, photoN, f'{camera_id}_8.xmp')
with open(filename, 'r') as f:
lines = f.readlines()
lines = [line.replace('xcr:InMeshing="0"', f'xcr:InMeshing="{mesh}"') for line in lines]
lines = [line.replace('xcr:InMeshing="1"', f'xcr:InMeshing="{mesh}"') for line in lines]
lines = [line.replace('xcr:InTexturing="0"', f'xcr:InTexturing="{texture}"') for line in lines]
lines = [line.replace('xcr:InTexturing="1"', f'xcr:InTexturing="{texture}"') for line in lines]
with open(filename, 'w') as f:
f.writelines(lines)
def diff_time(start_time):
# 按照分:秒的方式返回时间差
end_time = time.time()
diff = end_time - start_time
m, s = divmod(diff, 60)
return f'{int(m)}{int(s)}'

233
yj_local_build/main_step1.py

@ -0,0 +1,233 @@ @@ -0,0 +1,233 @@
import os, sys, time, shlex, subprocess, shutil, requests, cv2, numpy as np
from PIL import Image
import json
with open('config.json', 'r') as f:
config = json.load(f)
def set_photo_join_type(workdir, pid, photoN, camera_id, mesh = '0', texture='0'):
if photoN == 'photo1':
filename = os.path.join(workdir, pid, photoN, f'{camera_id}_1.xmp')
else:
filename = os.path.join(workdir, pid, photoN, f'{camera_id}_8.xmp')
with open(filename, 'r') as f:
lines = f.readlines()
lines = [line.replace('xcr:InMeshing="0"', f'xcr:InMeshing="{mesh}"') for line in lines]
lines = [line.replace('xcr:InMeshing="1"', f'xcr:InMeshing="{mesh}"') for line in lines]
lines = [line.replace('xcr:InTexturing="0"', f'xcr:InTexturing="{texture}"') for line in lines]
lines = [line.replace('xcr:InTexturing="1"', f'xcr:InTexturing="{texture}"') for line in lines]
with open(filename, 'w') as f:
f.writelines(lines)
def diff_time(start_time):
# 按照分:秒的方式返回时间差
end_time = time.time()
diff = end_time - start_time
m, s = divmod(diff, 60)
return f'{int(m)}{int(s)}'
def filter_dark_texture_image(pid):
start_time = time.time()
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 开始检测射灯异常图片...')
def get_image_v(image):
# 图片左上角和右上角各取200*200区域,计算V通道均值
left_rect = image[0:200, 0:200]
right_rect = image[0:200, -200:]
left_hsv = cv2.cvtColor(left_rect, cv2.COLOR_BGR2HSV)
left_v = left_hsv[:, :, 2]
left_avg_v = np.mean(left_v)
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 图片左上角V通道均值:{left_avg_v}')
right_hsv = cv2.cvtColor(right_rect, cv2.COLOR_BGR2HSV)
right_v = right_hsv[:, :, 2]
right_avg_v = np.mean(right_v)
# print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 图片右上角V通道均值:{right_avg_v}')
return (left_avg_v + right_avg_v) / 2
v_list = []
for filename in os.listdir(os.path.join(config['workdir'], pid, 'photo2')):
if filename.endswith(".jpg"):
image = cv2.imread(os.path.join(config['workdir'], pid, 'photo2', filename))
v = get_image_v(image)
item = {'filename': filename, 'v': v}
v_list.append(item)
v_list.sort(key=lambda x: x['v'])
v_list = v_list[5: -5]
avg_v = np.mean([item['v'] for item in v_list])
for item in v_list:
if abs(item['v'] - avg_v) > 50:
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 图片{item["filename"]} V通道值{item["v"]},低于平均值{avg_v},将不参与贴图')
set_photo_join_type(config['workdir'], pid, 'photo2', item['filename'].split('_')[0], mesh='1', texture='0')
# 复制xmp文件到photo3目录,如果photo3目录存在的话
if os.path.exists(os.path.join(config['workdir'], pid, 'photo3')):
shutil.copyfile(os.path.join(config['workdir'], pid, 'photo2', item['filename'].replace('jpg', 'xmp')), os.path.join(config['workdir'], pid, 'photo3', item['filename'].replace('jpg', 'xmp')))
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 射灯异常图片检测完成,共费时{diff_time(start_time)}')
def detect_markers(psid, pid):
def fix_region():
region_filename = os.path.join(config['workdir'], pid, f'{pid}.rcbox')
with open(region_filename, 'r') as f:
lines = f.readlines()
lines = [line.replace('"NONE" globalCoordinateSystemWkt="NONE" globalCoordinateSystemName="NONE"', '"+proj=geocent +ellps=WGS84 +no_defs" globalCoordinateSystemName="local:1 - Euclidean"') for line in lines]
start_time = time.time()
textpicCmd ='-selectImage "'+os.path.join(config['workdir'],pid,'photo2')+'\*" -enableTexturingAndColoring true'
#获取当前的工作目录
dirCurr = os.getcwd()
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, "photo1")}" {config["r"]["setTextureFalse"]} -align -addFolder "{os.path.join(config["workdir"], pid, "photo2")}" \
-align -selectAllImages \
-detectMarkers "{dirCurr}\detectMarkers.config.xml" \
-defineDistance 36h11:001 36h11:002 1 -defineDistance 36h11:002 36h11:004 1 -defineDistance 36h11:004 36h11:003 1 -defineDistance 36h11:003 36h11:001 1 -align -align -update {config["r2"]["setRegion"]} \
-exportXMP "{dirCurr}\exportXMP.config.xml" \
-exportControlPointsMeasurements "{os.path.join(config["workdir"], pid, f"{pid}.controlPoints.csv")}" "{dirCurr}\exportControlPoints.config.xml" \
-exportReconstructionRegion "{os.path.join(config["workdir"], pid, f"{pid}.rcbox")}" \
{textpicCmd} -save "{os.path.join(config["workdir"], pid, f"{pid}.rcproj")}" -quit'
print(cmd)
cmd = shlex.split(cmd)
res = subprocess.run(cmd)
time.sleep(3)
fix_region()
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid: {pid} 定位点检测完成, 共费时{diff_time(start_time)}')
def step1(pid,headsCount):
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 开始处理{pid}建模任务')
start_time = time.time()
# 检测图片定位点,定位异常及时上报微信通知给客服人员,人工判断是否需要重新拍摄或更换地贴。定义定位点距离,导出相机位姿信息
detect_markers(0, pid)
# 处理图片,检测photo2中的异常图片不参与贴图,以免破坏贴图效果,默认不检测射灯异常图片,以节省算力成本
filter_dark_texture_image(pid)
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} {pid} step1图片预处理完成,共费时{diff_time(start_time)}')
# os.system(f'python {os.getcwd()}/main_step2.py {pid}')
step2(pid,headsCount)
def step2(pid,headsCount):
dirCurr = os.getcwd()
simplify_value = 1000000 * int(headsCount)
calulate_type = 'calculateNormalModel'
cmd = f'{config["rcbin"]} {config["r2"]["init"]} -setInstanceName {pid} \
-load "{os.path.join(config["workdir"], pid, f"{pid}.rcproj")}" \
-{calulate_type} \
-selectLargestModelComponent -invertTrianglesSelection -removeSelectedTriangles -simplify {simplify_value} -smooth -closeHoles -cleanModel -calculateTexture \
-save "{os.path.join(config["workdir"], pid, f"{pid}.rcproj")}" \
-exportSelectedModel "{os.path.join(config["workdir"], pid, "output", f"{pid}.obj")}" "{dirCurr}\\ModelExportParams.xml" -quit'
print(cmd)
cmd = shlex.split(cmd)
res = subprocess.run(cmd)
#阻塞判断是否导出完成
while True:
#判断 output 目录下是否存在 三个文件
files = os.listdir(os.path.join(config['workdir'], pid, "output"))
if len(files) >= 3:
break
#将导出的文件移动到指定目录
sourceDir = config["local_complate_build"]
#判断目录是否存在,不存在就创建
if not os.path.exists(sourceDir):
os.makedirs(sourceDir)
#将 output 目录里的文件移动到指定目录
shutil.move(os.path.join(config['workdir'], pid, "output"),os.path.join(sourceDir,pid))
#发起请求告知后端建模完成
try:
res = requests.post(url, data={'id': pid,'status':5000})
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid:{pid} 任务完成- {res.text}')
except Exception as e:
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid:{pid} - 建模完成状态变更失败 - {e}')
def main(pid,headsCount):
step1(pid, headsCount)
if __name__ == '__main__':
try:
url = config['urls']['update_status_modelsuccess_url']
if url == "":
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 请配置建模完成回调地址')
exit()
# 取云端redis任务,完成第一步的数据预处理后,将数据放入共享存储目录,将第二步任务塞入本地mysql队列
# 默认循环值守,可传参数运行单一任务,以方便调试
pid = '0'
if len(sys.argv) == 3:
pids = sys.argv[1].split(',')
headsCount = sys.argv[2]
for pid in pids:
main(pid,headsCount)
exit()
#获取文件夹下的所有文件
needBuildDir = config['local_need_build']
workdir = config['workdir']
if workdir == '':
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 请配置建模工作目录')
exit()
#不存在就创建工作目录
if not os.path.exists(workdir):
os.makedirs(workdir)
if not os.path.exists(needBuildDir):
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 需要建模目录不存在- {needBuildDir}')
exit()
except Exception as e:
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 初始化异常 - {e}')
#遍历文件夹下的所有文件进行处理
try:
while True:
time.sleep(5)
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 建模任务循环开始')
for pid in os.listdir(needBuildDir):
if not os.path.isdir(os.path.join(needBuildDir,pid)):
continue
#判断是否存在 canDo.txt 文件,如果不存在就跳过
if not os.path.exists(os.path.join(needBuildDir,pid,"canDo.txt")):
continue
#读取 canDo.txt 文件内容
headsCounts = 1
with open(os.path.join(needBuildDir,pid,"canDo.txt"),"r") as f:
headsCounts = f.read()
#判断文件夹里是否存在 do.txt , 如果存在就跳过,不存在就创建
if os.path.exists(os.path.join(needBuildDir,pid,"do.txt")):
continue
else:
with open(os.path.join(needBuildDir,pid,"do.txt"),"w") as f:
f.write("1")
#判断是否已经存在了,存在就删除
if os.path.exists(os.path.join(workdir,pid)):
shutil.rmtree(os.path.join(workdir,pid))
#将文件夹移动到工作目录
shutil.move(os.path.join(needBuildDir,pid),os.path.join(workdir,pid))
#执行建模流程,建模中的流程
try:
requests.post(url, data={'id': pid,'status':4000})
except Exception as e:
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} pid:{pid} - 状态变更失败 - {e}')
#continue
main(pid,headsCounts)
except Exception as e:
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 建模任务循环异常 - {e}')
exit()
Loading…
Cancel
Save