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 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) 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 -save' #不存在point文件的时候就要用自动点击的方式 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) cmd = shlex.split(cmd) res = subprocess.run(cmd) time.sleep(2) if isExistPoint == False: 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()),"循环阻塞结束,开始建模") 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文件的方式进行建模") #区域的设置 建模 #update cmdSmall = "-align" #使用公共point文件的时候,就不能使用update , 而是要用 align if isExistPoint == True: cmdSmall = "-align" #{config.r1["init"]} if common.task_need_high_model(pid): 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 -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): 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' 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 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)