@ -1,14 +1,18 @@
import requests , time
import requests
import os , platform
import time
import os
import platform
import shutil
import shutil
import json
import json
import shlex
import shlex
import subprocess
from concurrent . futures import ThreadPoolExecutor , as_completed
from concurrent . futures import ThreadPoolExecutor , as_completed
from . oss_redis import ossClient
from . oss_redis import ossClient
from . logs import log
from . logs import log
from . oss_func import download_file_with_check , checkFileExists
from . oss_func import download_file_with_check , checkFileExists
from . changeFiles import changeObjFile , changeMtlFile
from . changeFiles import changeObjFile , changeMtlFile
from . small_machine_transform import transform_save
from . small_machine_transform import transform_save
ENV = ' prod '
ENV = ' prod '
url = ' https://mp.api.suwa3d.com '
url = ' https://mp.api.suwa3d.com '
if ENV == ' dev ' :
if ENV == ' dev ' :
@ -17,11 +21,11 @@ elif ENV == 'prod':
url = ' https://mp.api.suwa3d.com '
url = ' https://mp.api.suwa3d.com '
#根据打印ID 获取下载目录
# 根据打印ID 获取下载目录
def getDownloadDirByPrintId ( printIds ) :
def getDownloadDirByPrintId ( printIds ) :
#调用接口获取下载的路径
# 调用接口获取下载的路径
api_url = f " { url } /api/printOrder/getInfoByPrintIds "
api_url = f " { url } /api/printOrder/getInfoByPrintIds "
res = requests . post ( api_url , json = { " print_ids " : printIds } )
res = requests . post ( api_url , json = { " print_ids " : printIds } )
res = res . json ( )
res = res . json ( )
print ( f " 根据打印ID 获取下载目录, res= { res } " )
print ( f " 根据打印ID 获取下载目录, res= { res } " )
if res [ " code " ] == 1000 :
if res [ " code " ] == 1000 :
@ -29,9 +33,10 @@ def getDownloadDirByPrintId(printIds):
else :
else :
return False
return False
#根据批次id,进行切片中的状态变更
def requestApiToUpdateSliceStatus ( versionId , downloadCounts ) :
# 根据批次id,进行切片中的状态变更
api_url = f " { url } /api/printTypeSettingOrder/updateBatchSliceing?batch_id= { versionId } &download_counts= " + str ( downloadCounts )
def requestApiToUpdateSliceStatus ( versionId , downloadCounts ) :
api_url = f " { url } /api/printTypeSettingOrder/updateBatchSliceing?batch_id= { versionId } &download_counts= " + str ( downloadCounts )
log ( f ' 发起状态变更请求url= { api_url } , versionId= { versionId } ' )
log ( f ' 发起状态变更请求url= { api_url } , versionId= { versionId } ' )
try :
try :
# 添加超时参数,防止请求时间过长
# 添加超时参数,防止请求时间过长
@ -48,39 +53,40 @@ def requestApiToUpdateSliceStatus(versionId,downloadCounts):
log ( f ' 状态变更请求异常, error= { str ( e ) } ' )
log ( f ' 状态变更请求异常, error= { str ( e ) } ' )
return False
return False
#判断是否上传了 JSON 文件
# 判断是否上传了 JSON 文件
def checkJsonFileExists ( versionId ) :
def checkJsonFileExists ( versionId ) :
log ( f " 检测文件和图片是否存在, versionId= { versionId } " )
log ( f " 检测文件和图片是否存在, versionId= { versionId } " )
jsonFilePath = f ' batchPrint/ { versionId } / { versionId } .json '
jsonFilePath = f ' batchPrint/ { versionId } / { versionId } .json '
#判断oss 上是否存在
# 判断oss 上是否存在
jpgFilePath = f ' batchPrint/ { versionId } / { versionId } .jpg '
jpgFilePath = f ' batchPrint/ { versionId } / { versionId } .jpg '
if not ossClient ( ) . object_exists ( jsonFilePath ) :
if not ossClient ( ) . object_exists ( jsonFilePath ) :
log ( f ' JSON文件不存在: { jsonFilePath } ' )
log ( f ' JSON文件不存在: { jsonFilePath } ' )
return False , False
return False , False
if not ossClient ( ) . object_exists ( jpgFilePath ) :
if not ossClient ( ) . object_exists ( jpgFilePath ) :
log ( f ' JPG文件不存在: { jpgFilePath } ' )
log ( f ' JPG文件不存在: { jpgFilePath } ' )
return False , False
return False , False
log ( f " 文件和图片检测成功,存在, versionId= { versionId } " )
log ( f " 文件和图片检测成功,存在, versionId= { versionId } " )
return jsonFilePath , jpgFilePath
return jsonFilePath , jpgFilePath
# 检测本地文件是否存在
#检测本地文件是否存在
def checkLocalFileExists ( localFilePath ) :
def checkLocalFileExists ( localFilePath ) :
if not os . path . exists ( localFilePath ) :
if not os . path . exists ( localFilePath ) :
return False
return False
return True
return True
#读取JSON文件内容
# 读取JSON文件内容
def readJsonFile ( localFilePath ) :
def readJsonFile ( localFilePath ) :
with open ( localFilePath , ' r ' , encoding = ' utf-8 ' ) as f :
with open ( localFilePath , ' r ' , encoding = ' utf-8 ' ) as f :
jsonData = json . load ( f )
jsonData = json . load ( f )
return jsonData
return jsonData
#根据批次ID,获取批次信息
# 根据批次ID,获取批次信息
def getBatchInfo ( versionId ) :
def getBatchInfo ( versionId ) :
url1 = f " { url } /api/printTypeSettingOrder/getBatchInfoAndPrintMachineInfoByBatchId?batch_id= { versionId } "
url1 = f " { url } /api/printTypeSettingOrder/getBatchInfoAndPrintMachineInfoByBatchId?batch_id= { versionId } "
res = requests . get ( url1 )
res = requests . get ( url1 )
@ -91,13 +97,14 @@ def getBatchInfo(versionId):
else :
else :
return False
return False
#下载文件,读取文件内容,并且文件迁移至正确的目录里,不再放在临时目录里
def downloadJsonAndJpgFileAndMoveToCorrectDir ( versionId , currentDir ) :
# 下载文件,读取文件内容,并且文件迁移至正确的目录里,不再放在临时目录里
jsonFilePath , jpgFilePath = checkJsonFileExists ( versionId )
def downloadJsonAndJpgFileAndMoveToCorrectDir ( versionId , currentDir ) :
jsonFilePath , jpgFilePath = checkJsonFileExists ( versionId )
if jsonFilePath == False or jpgFilePath == False :
if jsonFilePath == False or jpgFilePath == False :
return False , False
return False , False
#将文件下载到临时目录,待会要判断是否什么类型机型
# 将文件下载到临时目录,待会要判断是否什么类型机型
tempDir = os . path . join ( currentDir , ' batchPrint ' , ' temp ' , versionId )
tempDir = os . path . join ( currentDir , ' batchPrint ' , ' temp ' , versionId )
if not os . path . exists ( tempDir ) :
if not os . path . exists ( tempDir ) :
os . makedirs ( tempDir )
os . makedirs ( tempDir )
@ -106,74 +113,73 @@ def downloadJsonAndJpgFileAndMoveToCorrectDir(versionId,currentDir):
ok = download_file_with_check ( jsonFilePath , localFilePath )
ok = download_file_with_check ( jsonFilePath , localFilePath )
if not ok :
if not ok :
log ( f " JSON 文件下载失败或不完整, versionId= { versionId } " )
log ( f " JSON 文件下载失败或不完整, versionId= { versionId } " )
return False , False
return False , False
#下载JPG文件
# 下载JPG文件
localJpgFilePath = os . path . join ( tempDir , f ' { versionId } .jpg ' )
localJpgFilePath = os . path . join ( tempDir , f ' { versionId } .jpg ' )
ok = download_file_with_check ( jpgFilePath , localJpgFilePath )
ok = download_file_with_check ( jpgFilePath , localJpgFilePath )
if not ok :
if not ok :
log ( f " JPG 文件下载失败或不完整, versionId= { versionId } " )
log ( f " JPG 文件下载失败或不完整, versionId= { versionId } " )
return False , False
return False , False
#根据批次ID,获取批次信息和打印机信息
# 根据批次ID,获取批次信息和打印机信息
batchMachineInfo = getBatchInfo ( versionId )
batchMachineInfo = getBatchInfo ( versionId )
if not batchMachineInfo :
if not batchMachineInfo :
log ( f " 获取批次信息和打印机信息失败, versionId= { versionId } " )
log ( f " 获取批次信息和打印机信息失败, versionId= { versionId } " )
return False , False
return False , False
# "batch_info": batchInfo,
# "batch_info": batchInfo,
# "print_machine_info": printMachineInfo,
# "print_machine_info": printMachineInfo,
machineInfo = batchMachineInfo [ " print_machine_info " ]
machineInfo = batchMachineInfo [ " print_machine_info " ]
print ( f " machineInfo= { machineInfo [ ' id ' ] } " )
print ( f " machineInfo= { machineInfo [ ' id ' ] } " )
dirNewName = " "
dirNewName = " "
if str ( machineInfo [ " machine_type " ] ) == ' 1 ' :
if str ( machineInfo [ " machine_type " ] ) == ' 1 ' :
dirNewName = os . path . join ( currentDir , ' batchPrint ' , versionId + ' _small_No ' + str ( machineInfo [ ' id ' ] ) )
dirNewName = os . path . join ( currentDir , ' batchPrint ' , versionId + ' _small_No ' + str ( machineInfo [ ' id ' ] ) )
else :
else :
dirNewName = os . path . join ( currentDir , ' batchPrint ' , versionId + ' _big_No ' + str ( machineInfo [ ' id ' ] ) )
dirNewName = os . path . join ( currentDir , ' batchPrint ' , versionId + ' _big_No ' + str ( machineInfo [ ' id ' ] ) )
#判断目录是否存在,存在就删除
# 判断目录是否存在,存在就删除
if os . path . exists ( dirNewName ) :
if os . path . exists ( dirNewName ) :
shutil . rmtree ( dirNewName )
shutil . rmtree ( dirNewName )
#创建目录
# 创建目录
os . makedirs ( dirNewName )
os . makedirs ( dirNewName )
#创建json子目录
# 创建json子目录
jsonSubDir = os . path . join ( dirNewName , ' json ' )
jsonSubDir = os . path . join ( dirNewName , ' json ' )
if not os . path . exists ( jsonSubDir ) :
if not os . path . exists ( jsonSubDir ) :
os . makedirs ( jsonSubDir )
os . makedirs ( jsonSubDir )
# 将数据移动过来
#将数据移动过来
shutil . move ( localFilePath , os . path . join ( jsonSubDir , ' 3DPrintLayout.json ' ) )
shutil . move ( localFilePath , os . path . join ( jsonSubDir , ' 3DPrintLayout.json ' ) )
shutil . move ( localJpgFilePath , os . path . join ( jsonSubDir , f ' { versionId } .jpg ' ) )
shutil . move ( localJpgFilePath , os . path . join ( jsonSubDir , f ' { versionId } .jpg ' ) )
#检测文件是否移动成功
# 检测文件是否移动成功
if not os . path . exists ( os . path . join ( jsonSubDir , ' 3DPrintLayout.json ' ) ) :
if not os . path . exists ( os . path . join ( jsonSubDir , ' 3DPrintLayout.json ' ) ) :
log ( f " JSON文件不存在, versionId= { versionId } " )
log ( f " JSON文件不存在, versionId= { versionId } " )
return False , False
return False , False
if not os . path . exists ( os . path . join ( jsonSubDir , f ' { versionId } .jpg ' ) ) :
if not os . path . exists ( os . path . join ( jsonSubDir , f ' { versionId } .jpg ' ) ) :
log ( f " JPG文件不存在, versionId= { versionId } " )
log ( f " JPG文件不存在, versionId= { versionId } " )
return False , False
return False , False
log ( f " 文件移动成功, versionId= { versionId } " )
log ( f " 文件移动成功, versionId= { versionId } " )
#返回目录路径
# 返回目录路径
return dirNewName , machineInfo
return dirNewName , machineInfo
#整合json文件,读取对应的数据,返回数据结构
# 整合json文件,读取对应的数据,返回数据结构
def getJsonData ( dirNewName ) :
def getJsonData ( dirNewName ) :
jsonFilePath = os . path . join ( dirNewName , ' json ' , ' 3DPrintLayout.json ' )
jsonFilePath = os . path . join ( dirNewName , ' json ' , ' 3DPrintLayout.json ' )
if not os . path . exists ( jsonFilePath ) :
if not os . path . exists ( jsonFilePath ) :
log ( f " JSON文件不存在, dirNewName= { dirNewName } " )
log ( f " JSON文件不存在, dirNewName= { dirNewName } " )
return False
return False
#读取JSON文件内容
# 读取JSON文件内容
jsonData = readJsonFile ( jsonFilePath )
jsonData = readJsonFile ( jsonFilePath )
#读取models
# 读取models
models = jsonData . get ( ' models ' , [ ] )
models = jsonData . get ( ' models ' , [ ] )
if not models :
if not models :
log ( f " models不存在, dirNewName= { dirNewName } " )
log ( f " models不存在, dirNewName= { dirNewName } " )
return False
return False
listData = [ ]
listData = [ ]
#遍历models
# 遍历models
for model in models :
for model in models :
file_name = model . get ( ' file_name ' , ' ' )
file_name = model . get ( ' file_name ' , ' ' )
#分割数据
# 分割数据
arrFileName = file_name . split ( ' _ ' )
arrFileName = file_name . split ( ' _ ' )
orderId = arrFileName [ 0 ]
orderId = arrFileName [ 0 ]
pid = arrFileName [ 1 ]
pid = arrFileName [ 1 ]
@ -181,14 +187,12 @@ def getJsonData(dirNewName):
size = arrFileName [ 3 ]
size = arrFileName [ 3 ]
counts = arrFileName [ 4 ] . replace ( " x " , " " ) . replace ( " .obj " , " " )
counts = arrFileName [ 4 ] . replace ( " x " , " " ) . replace ( " .obj " , " " )
#检测这些数据
# 检测这些数据
if not orderId or not pid or not printId or not size or not counts :
if not orderId or not pid or not printId or not size or not counts :
log ( f " 数据不完整, orderId= { orderId } , pid= { pid } , printId= { printId } , size= { size } , counts= { counts } " )
log ( f " 数据不完整, orderId= { orderId } , pid= { pid } , printId= { printId } , size= { size } , counts= { counts } " )
return False
return False
# 创建数据结构
#创建数据结构
modelInfo = {
modelInfo = {
" orderId " : orderId ,
" orderId " : orderId ,
" printId " : printId ,
" printId " : printId ,
@ -198,27 +202,27 @@ def getJsonData(dirNewName):
" file_name " : file_name ,
" file_name " : file_name ,
}
}
listData . append ( modelInfo )
listData . append ( modelInfo )
#检测数据长度
# 检测数据长度
if len ( listData ) == 0 :
if len ( listData ) == 0 :
log ( f " 数据长度为0, dirNewName= { dirNewName } " )
log ( f " 数据长度为0, dirNewName= { dirNewName } " )
return False
return False
#返回数据结构
# 返回数据结构
return listData
return listData
# 读取 json 文件,获取 homo_matrix 数据,根据 file_name 获取 homo_matrix 数据
# 读取 json 文件,获取 homo_matrix 数据,根据 file_name 获取 homo_matrix 数据
def getHomoMatrixByFileName ( dirNewName , fileName ) :
def getHomoMatrixByFileName ( dirNewName , fileName ) :
jsonFilePath = os . path . join ( dirNewName , ' json ' , ' 3DPrintLayout.json ' )
jsonFilePath = os . path . join ( dirNewName , ' json ' , ' 3DPrintLayout.json ' )
if not os . path . exists ( jsonFilePath ) :
if not os . path . exists ( jsonFilePath ) :
log ( f " JSON文件不存在, dirNewName= { dirNewName } " )
log ( f " JSON文件不存在, dirNewName= { dirNewName } " )
return False
return False
#读取JSON文件内容
# 读取JSON文件内容
jsonData = readJsonFile ( jsonFilePath )
jsonData = readJsonFile ( jsonFilePath )
if not jsonData :
if not jsonData :
log ( f " 读取JSON文件内容失败, dirNewName= { dirNewName } " )
log ( f " 读取JSON文件内容失败, dirNewName= { dirNewName } " )
return False
return False
for model in jsonData [ " models " ] :
for model in jsonData [ " models " ] :
log ( f " jsonData= { model [ ' file_name ' ] } == { fileName } " )
log ( f " jsonData= { model [ ' file_name ' ] } == { fileName } " )
if model [ " file_name " ] == fileName :
if model [ " file_name " ] == fileName :
@ -227,7 +231,7 @@ def getHomoMatrixByFileName(dirNewName,fileName):
return False
return False
#处理单个数据项:下载文件、修改关联路径、转换数据(如果是小机台)
# 处理单个数据项:下载文件、修改关联路径、转换数据(如果是小机台)
def _process_single_item ( v , arrDownloadPath , dirNewName , dirPath , isSmallMachine ) :
def _process_single_item ( v , arrDownloadPath , dirNewName , dirPath , isSmallMachine ) :
"""
"""
处理单个数据项的函数 , 用于多线程处理
处理单个数据项的函数 , 用于多线程处理
@ -247,10 +251,10 @@ def _process_single_item(v, arrDownloadPath, dirNewName, dirPath, isSmallMachine
if str ( tempv [ " print_order_id " ] ) == str ( v [ " printId " ] ) :
if str ( tempv [ " print_order_id " ] ) == str ( v [ " printId " ] ) :
info = tempv
info = tempv
break
break
if not info :
if not info :
return False , f " 未找到匹配的下载路径信息, printId= { v [ ' printId ' ] } "
return False , f " 未找到匹配的下载路径信息, printId= { v [ ' printId ' ] } "
filePath = info [ " path " ]
filePath = info [ " path " ]
pid = info [ " pid " ]
pid = info [ " pid " ]
orderId = info [ " order_id " ]
orderId = info [ " order_id " ]
@ -258,8 +262,8 @@ def _process_single_item(v, arrDownloadPath, dirNewName, dirPath, isSmallMachine
size = info [ " real_size " ]
size = info [ " real_size " ]
counts = info [ " quantity " ]
counts = info [ " quantity " ]
fileName = v [ " file_name " ]
fileName = v [ " file_name " ]
#判断文件是否存在
# 判断文件是否存在
ossJpgFilePath = f " { filePath } /printId_ { printId } Tex1.jpg "
ossJpgFilePath = f " { filePath } /printId_ { printId } Tex1.jpg "
if not checkFileExists ( ossJpgFilePath ) :
if not checkFileExists ( ossJpgFilePath ) :
ossJpgFilePath = f " { filePath } / { pid } Tex1.jpg "
ossJpgFilePath = f " { filePath } / { pid } Tex1.jpg "
@ -272,12 +276,13 @@ def _process_single_item(v, arrDownloadPath, dirNewName, dirPath, isSmallMachine
{ " ossPath " : f " { filePath } / { pid } .obj " , " localPath " : os . path . join ( dirPath , localObjName ) } ,
{ " ossPath " : f " { filePath } / { pid } .obj " , " localPath " : os . path . join ( dirPath , localObjName ) } ,
{ " ossPath " : f " { filePath } / { pid } .mtl " , " localPath " : os . path . join ( dirPath , loaclMtlName ) } ,
{ " ossPath " : f " { filePath } / { pid } .mtl " , " localPath " : os . path . join ( dirPath , loaclMtlName ) } ,
]
]
#遍历下载文件
# 遍历下载文件
beginTime = time . time ( )
beginTime = time . time ( )
objsLocal = " "
objsLocal = " "
for objFiles in arrDownloadFiles :
for objFiles in arrDownloadFiles :
#判断 mtl 和 jpg 文件是否存在,存在就不在下载了
downloadBeginTime = time . time ( )
# 判断 mtl 和 jpg 文件是否存在,存在就不在下载了
if " mtl " in objFiles [ " localPath " ] or " jpg " in objFiles [ " localPath " ] :
if " mtl " in objFiles [ " localPath " ] or " jpg " in objFiles [ " localPath " ] :
if os . path . exists ( objFiles [ " localPath " ] ) :
if os . path . exists ( objFiles [ " localPath " ] ) :
continue
continue
@ -288,18 +293,20 @@ def _process_single_item(v, arrDownloadPath, dirNewName, dirPath, isSmallMachine
log ( error_msg )
log ( error_msg )
return False , error_msg
return False , error_msg
#下载成功之后要修改文件之间的关联路径
log ( f " 下载文件耗时: { time . time ( ) - downloadBeginTime } 秒 - { objFiles [ ' localPath ' ] } " )
# 下载成功之后要修改文件之间的关联路径
if objFiles [ " localPath " ] . endswith ( " .obj " ) :
if objFiles [ " localPath " ] . endswith ( " .obj " ) :
beginChangeTime = time . time ( )
objsLocal = objFiles [ " localPath " ]
objsLocal = objFiles [ " localPath " ]
changeObjFile ( objFiles [ " localPath " ] , f " { orderId } _ { pid } .mtl " )
changeObjFile ( objFiles [ " localPath " ] , f " { orderId } _ { pid } .mtl " )
log ( f " 修改obj关联耗时: { time . time ( ) - beginChangeTime } 秒 - { objFiles [ ' localPath ' ] } " )
if objFiles [ " localPath " ] . endswith ( " .mtl " ) :
if objFiles [ " localPath " ] . endswith ( " .mtl " ) :
changeMtlFile ( objFiles [ " localPath " ] , f " { orderId } _ { pid } Tex1.jpg " )
changeMtlFile ( objFiles [ " localPath " ] , f " { orderId } _ { pid } Tex1.jpg " )
endTime = time . time ( )
endTime = time . time ( )
log ( f " 下载文件和修改文件之间的关联路径 : 耗时 { endTime - beginTime } 秒 - { fileName } " )
log ( f " 下载文件和修改文件之间的关联路径 : 耗时 { endTime - beginTime } 秒 - { fileName } " )
#如果是小机台,则要转换数据
# 如果是小机台,则要转换数据
if isSmallMachine :
if isSmallMachine :
timeBegin = time . time ( )
timeBegin = time . time ( )
homo_matrix = getHomoMatrixByFileName ( dirNewName , localObjName )
homo_matrix = getHomoMatrixByFileName ( dirNewName , localObjName )
@ -308,27 +315,65 @@ def _process_single_item(v, arrDownloadPath, dirNewName, dirPath, isSmallMachine
log ( error_msg )
log ( error_msg )
return False , error_msg
return False , error_msg
#通过blender 调用执行 python 文件
# 通过blender 调用执行 python 文件
blender_bin_path = findBpyModule ( )
blender_bin_path = findBpyModule ( )
# 获取 small_machine_transform.py 的绝对路径
# 获取 small_machine_transform.py 的绝对路径
script_dir = os . path . dirname ( os . path . abspath ( __file__ ) )
script_dir = os . path . dirname ( os . path . abspath ( __file__ ) )
transform_script_path = os . path . join ( script_dir , ' small_machine_transform.py ' )
transform_script_path = os . path . join ( script_dir , ' small_machine_transform.py ' )
# 将 homo_matrix 转换为 JSON 字符串,并对路径进行转义
# 将 homo_matrix 转换为 JSON 字符串
homo_matrix_json = json . dumps ( homo_matrix )
homo_matrix_json = json . dumps ( homo_matrix )
# 使用 shlex.quote 来安全地转义路径和参数
transform_script_path_quoted = shlex . quote ( transform_script_path )
# 构建命令参数列表(使用列表形式,避免 shell 转义问题)
objsLocal_quoted = shlex . quote ( objsLocal )
cmd = [
homo_matrix_quoted = shlex . quote ( homo_matrix_json )
blender_bin_path ,
error = os . system ( f " { blender_bin_path } -b -P { transform_script_path_quoted } -- --objPathName= { objsLocal_quoted } --trans= { homo_matrix_quoted } " )
' --background ' ,
if error != 0 :
' --python ' ,
error_msg = f " 调用blender 执行 python 文件失败, error= { error } , fileName= { fileName } "
transform_script_path ,
' -- ' ,
f ' --objPathName= { objsLocal } ' ,
f ' --trans= { homo_matrix_json } '
]
log ( f " 执行 Blender 命令: { ' ' . join ( cmd [ : 4 ] ) } ... (参数已隐藏) " )
try :
# 使用 subprocess 执行命令,捕获输出和错误
# 在 Windows 上,Blender 输出可能是 UTF-8,需要指定编码并处理错误
result = subprocess . run (
cmd ,
capture_output = True ,
text = True ,
encoding = ' utf-8 ' , # 指定 UTF-8 编码
errors = ' replace ' , # 遇到无法解码的字符时替换为占位符,而不是抛出异常
timeout = 300 , # 5分钟超时
check = False # 不自动抛出异常,手动检查返回码
)
if result . returncode != 0 :
error_output = result . stderr if result . stderr else result . stdout
error_msg = f " 调用blender 执行 python 文件失败, error= { result . returncode } , fileName= { fileName } "
if error_output :
error_msg + = f " , 错误信息: { error_output [ : 500 ] } " # 限制错误信息长度
log ( error_msg )
return False , error_msg
log ( f " 调用blender 执行 python 文件成功, fileName= { fileName } " )
if result . stdout :
log ( f " Blender 输出: { result . stdout [ : 200 ] } " ) # 记录部分输出用于调试
except subprocess . TimeoutExpired :
error_msg = f " 调用blender 执行超时(超过5分钟), fileName= { fileName } "
log ( error_msg )
return False , error_msg
except Exception as e :
error_msg = f " 调用blender 执行时发生异常: { str ( e ) } , fileName= { fileName } "
log ( error_msg )
log ( error_msg )
return False , error_msg
return False , error_msg
log ( f " 调用blender 执行 python 文件成功, error= { error } , fileName= { fileName } " )
timeEnd = time . time ( )
timeEnd = time . time ( )
log ( f " 转换数据时间: 耗时 { timeEnd - timeBegin } 秒 - { objsLocal } " )
log ( f " 转换数据时间: 耗时 { timeEnd - timeBegin } 秒 - { objsLocal } " )
return True , " "
return True , " "
except Exception as e :
except Exception as e :
error_msg = f " 处理数据项时发生异常, fileName= { v . get ( ' file_name ' , ' unknown ' ) } , error= { str ( e ) } "
error_msg = f " 处理数据项时发生异常, fileName= { v . get ( ' file_name ' , ' unknown ' ) } , error= { str ( e ) } "
@ -336,13 +381,13 @@ def _process_single_item(v, arrDownloadPath, dirNewName, dirPath, isSmallMachine
return False , error_msg
return False , error_msg
#json文件进行下载对应的数据 和转换数据,传递目录路径
# json文件进行下载对应的数据 和转换数据,传递目录路径
def downloadDataByOssAndTransformSave ( dirNewName , isSmallMachine = False , max_workers = 10 ) :
def downloadDataByOssAndTransformSave ( dirNewName , isSmallMachine = False , max_workers = 1 ) :
listData = getJsonData ( dirNewName )
listData = getJsonData ( dirNewName )
if not listData :
if not listData :
log ( f " 获取数据失败, dirNewName= { dirNewName } " )
log ( f " 获取数据失败, dirNewName= { dirNewName } " )
return False
return False
#遍历数据
# 遍历数据
arrPrintId = [ ]
arrPrintId = [ ]
arrPrintDataInfo = [ ]
arrPrintDataInfo = [ ]
for modelInfo in listData :
for modelInfo in listData :
@ -352,28 +397,28 @@ def downloadDataByOssAndTransformSave(dirNewName,isSmallMachine=False, max_worke
" file_name " : modelInfo . get ( ' file_name ' ) ,
" file_name " : modelInfo . get ( ' file_name ' ) ,
} )
} )
#调用接口获取下载的路径
# 调用接口获取下载的路径
arrDownloadPath = getDownloadDirByPrintId ( arrPrintId )
arrDownloadPath = getDownloadDirByPrintId ( arrPrintId )
if not arrDownloadPath :
if not arrDownloadPath :
log ( f " 获取下载路径失败, arrPrintId= { arrPrintId } " )
log ( f " 获取下载路径失败, arrPrintId= { arrPrintId } " )
return False
return False
dirPath = os . path . join ( dirNewName , ' data ' )
dirPath = os . path . join ( dirNewName , ' data ' )
if not os . path . exists ( dirPath ) :
if not os . path . exists ( dirPath ) :
os . makedirs ( dirPath )
os . makedirs ( dirPath )
#使用多线程并发处理数据
# 使用多线程并发处理数据
log ( f " 开始多线程处理数据, 共 { len ( listData ) } 个项目, 线程数= { max_workers } " )
log ( f " 开始多线程处理数据, 共 { len ( listData ) } 个项目, 线程数= { max_workers } " )
beginTime = time . time ( )
beginTime = time . time ( )
# 使用线程池并发处理
# 使用线程池并发处理
with ThreadPoolExecutor ( max_workers = max_workers ) as executor :
with ThreadPoolExecutor ( max_workers = max_workers ) as executor :
# 提交所有任务
# 提交所有任务
future_to_item = {
future_to_item = {
executor . submit ( _process_single_item , v , arrDownloadPath , dirNewName , dirPath , isSmallMachine ) : v
executor . submit ( _process_single_item , v , arrDownloadPath , dirNewName , dirPath , isSmallMachine ) : v
for v in listData
for v in listData
}
}
# 收集结果
# 收集结果
success_count = 0
success_count = 0
fail_count = 0
fail_count = 0
@ -392,27 +437,48 @@ def downloadDataByOssAndTransformSave(dirNewName,isSmallMachine=False, max_worke
fail_count + = 1
fail_count + = 1
error_msg = f " 处理数据项时发生异常: { str ( e ) } "
error_msg = f " 处理数据项时发生异常: { str ( e ) } "
log ( f " 处理异常: { v . get ( ' file_name ' , ' unknown ' ) } , 错误: { error_msg } ( { fail_count } / { len ( listData ) } ) " )
log ( f " 处理异常: { v . get ( ' file_name ' , ' unknown ' ) } , 错误: { error_msg } ( { fail_count } / { len ( listData ) } ) " )
endTime = time . time ( )
endTime = time . time ( )
log ( f " 多线程处理完成, 总耗时 { endTime - beginTime } 秒, 成功: { success_count } , 失败: { fail_count } , 总计: { len ( listData ) } " )
log ( f " 多线程处理完成, 总耗时 { endTime - beginTime } 秒, 成功: { success_count } , 失败: { fail_count } , 总计: { len ( listData ) } " )
# 如果有任何失败,返回 False
# 如果有任何失败,返回 False
if fail_count > 0 :
if fail_count > 0 :
log ( f " 部分任务处理失败,共 { fail_count } 个失败 " )
log ( f " 部分任务处理失败,共 { fail_count } 个失败 " )
return False
return False
return True
return True
def findBpyModule ( ) :
def findBpyModule ( ) :
# 返回 Blender 可执行文件路径(macOS)
# 返回 Blender 可执行文件路径
blender_bin_path = ' /Applications/Blender.app/Contents/MacOS/Blender '
blender_bin_path = ' /Applications/Blender.app/Contents/MacOS/Blender '
# 判断当前是 windows 还是 macOS
# 判断当前是 windows 还是 macOS
if platform . system ( ) == ' Windows ' :
if platform . system ( ) == ' Windows ' :
blender_bin_path = ' C: \\ Program Files \\ Blender Foundation \\ Blender 5.0 \\ blender.exe '
# Windows 上常见的 Blender 安装路径
possible_paths = [
' C: \\ Program Files \\ Blender Foundation \\ Blender 5.0 \\ blender.exe ' ,
' C: \\ Program Files \\ Blender Foundation \\ Blender 4.4 \\ blender.exe ' ,
' C: \\ Program Files \\ Blender Foundation \\ Blender 4.3 \\ blender.exe ' ,
' C: \\ Program Files \\ Blender Foundation \\ Blender 4.2 \\ blender.exe ' ,
' C: \\ Program Files \\ Blender Foundation \\ Blender 4.1 \\ blender.exe ' ,
' C: \\ Program Files \\ Blender Foundation \\ Blender 4.0 \\ blender.exe ' ,
]
# 查找存在的路径
for path in possible_paths :
if os . path . exists ( path ) :
blender_bin_path = path
break
else :
# 如果都没找到,使用默认路径
blender_bin_path = ' C: \\ Program Files \\ Blender Foundation \\ Blender 5.0 \\ blender.exe '
log ( f " 警告: 未找到 Blender 可执行文件,使用默认路径: { blender_bin_path } " )
else :
else :
blender_bin_path = ' /Applications/Blender.app/Contents/MacOS/Blender '
blender_bin_path = ' /Applications/Blender.app/Contents/MacOS/Blender '
# 检查路径是否存在
if not os . path . exists ( blender_bin_path ) :
error_msg = f " Blender 可执行文件不存在: { blender_bin_path } "
log ( error_msg )
raise FileNotFoundError ( error_msg )
return blender_bin_path
return blender_bin_path