Browse Source

切片下载数据处理

master
dongchangxi 3 weeks ago
parent
commit
fd1de8c3d0
  1. 2
      script/factory_sliceing_v2/main.py
  2. 38
      script/factory_sliceing_v2/utils/funcs.py
  3. 70
      script/factory_sliceing_v2/utils/small_machine_transform.py

2
script/factory_sliceing_v2/main.py

@ -117,7 +117,7 @@ def main(work_dir=None):
def testMain(): def testMain():
global currentDir global currentDir
currentDir = "/Users/dcx/code/make2/script/factory_sliceing_v2/tempData" currentDir = "/Users/dcx/code/make2/script/factory_sliceing_v2/tempData"
versionId = '10158' #'10153 10158' versionId = '10153' #'10153 10158'
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 正在处理版次ID={versionId}') print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 正在处理版次ID={versionId}')
res = step1(versionId) res = step1(versionId)
print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 处理完成,res={res}') print(f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())} 处理完成,res={res}')

38
script/factory_sliceing_v2/utils/funcs.py

@ -324,6 +324,22 @@ def _process_single_item(v, arrDownloadPath, dirNewName, dirPath, isSmallMachine
# 将 homo_matrix 转换为 JSON 字符串 # 将 homo_matrix 转换为 JSON 字符串
homo_matrix_json = json.dumps(homo_matrix) homo_matrix_json = json.dumps(homo_matrix)
# 检查必要文件是否存在
if not blender_bin_path or not os.path.exists(blender_bin_path):
error_msg = f"Blender 可执行文件不存在: {blender_bin_path}"
log(error_msg)
return False, error_msg
if not os.path.exists(transform_script_path):
error_msg = f"转换脚本文件不存在: {transform_script_path}"
log(error_msg)
return False, error_msg
if not os.path.exists(objsLocal):
error_msg = f"OBJ 文件不存在: {objsLocal}"
log(error_msg)
return False, error_msg
# 构建命令参数列表(使用列表形式,避免 shell 转义问题) # 构建命令参数列表(使用列表形式,避免 shell 转义问题)
cmd = [ cmd = [
blender_bin_path, blender_bin_path,
@ -334,10 +350,14 @@ def _process_single_item(v, arrDownloadPath, dirNewName, dirPath, isSmallMachine
f'--objPathName={objsLocal}', f'--objPathName={objsLocal}',
f'--trans={homo_matrix_json}' f'--trans={homo_matrix_json}'
] ]
log(f"准备执行 Blender 命令")
log(f"执行 Blender 命令: {' '.join(cmd[:4])} ... (参数已隐藏)") log(f" Blender路径: {blender_bin_path}")
log(f" 脚本路径: {transform_script_path}")
log(f" OBJ文件: {objsLocal}")
log(f" 完整命令: {' '.join(cmd[:4])} ... (参数已隐藏)")
try: try:
log(f"开始执行 Blender 转换命令...")
# 使用 subprocess 执行命令,捕获输出和错误 # 使用 subprocess 执行命令,捕获输出和错误
# 在 Windows 上,Blender 输出可能是 UTF-8,需要指定编码并处理错误 # 在 Windows 上,Blender 输出可能是 UTF-8,需要指定编码并处理错误
result = subprocess.run( result = subprocess.run(
@ -350,17 +370,23 @@ def _process_single_item(v, arrDownloadPath, dirNewName, dirPath, isSmallMachine
check=False # 不自动抛出异常,手动检查返回码 check=False # 不自动抛出异常,手动检查返回码
) )
log(f"Blender 命令执行完成, 返回码: {result.returncode}")
# 无论成功失败都输出详细信息
if result.stdout:
log(f"Blender stdout 输出: {result.stdout}")
if result.stderr:
log(f"Blender stderr 输出: {result.stderr}")
if result.returncode != 0: if result.returncode != 0:
error_output = result.stderr if result.stderr else result.stdout error_output = result.stderr if result.stderr else result.stdout
error_msg = f"调用blender 执行 python 文件失败, error={result.returncode}, fileName={fileName}" error_msg = f"调用blender 执行 python 文件失败, 返回码={result.returncode}, fileName={fileName}"
if error_output: if error_output:
error_msg += f", 错误信息: {error_output[:500]}" # 限制错误信息长度 error_msg += f", 错误信息: {error_output[:10000000]}" # 增加错误信息长度限制
log(error_msg) log(error_msg)
return False, error_msg return False, error_msg
log(f"调用blender 执行 python 文件成功, fileName={fileName}") log(f"调用blender 执行 python 文件成功, fileName={fileName}")
if result.stdout:
log(f"Blender 输出: {result.stdout[:200]}") # 记录部分输出用于调试
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
error_msg = f"调用blender 执行超时(超过5分钟), fileName={fileName}" error_msg = f"调用blender 执行超时(超过5分钟), fileName={fileName}"

70
script/factory_sliceing_v2/utils/small_machine_transform.py

@ -1,6 +1,7 @@
import os,time,sys,argparse import os,time,sys,argparse
import numpy as np import numpy as np
import json import json
import warnings
def findBpyModule(): def findBpyModule():
@ -17,12 +18,56 @@ def custom_mesh_transform(vertices, transform_matrix):
返回: 返回:
变换后的顶点数组 (N, 3) 变换后的顶点数组 (N, 3)
""" """
# 验证变换矩阵
transform_matrix = np.array(transform_matrix, dtype=np.float64)
# 检查矩阵形状
if transform_matrix.shape != (4, 4):
raise ValueError(f"变换矩阵必须是 4x4 矩阵,当前形状: {transform_matrix.shape}")
# 检查矩阵中是否包含无效值(NaN 或 Inf)
if np.any(np.isnan(transform_matrix)) or np.any(np.isinf(transform_matrix)):
invalid_count = np.sum(np.isnan(transform_matrix)) + np.sum(np.isinf(transform_matrix))
raise ValueError(f"变换矩阵包含无效值 (NaN/Inf): {invalid_count} 个无效元素\n矩阵:\n{transform_matrix}")
# 检查矩阵行列式(对于齐次变换矩阵,最后一行应该是 [0, 0, 0, 1])
# 如果矩阵接近奇异,行列式会接近0
det = np.linalg.det(transform_matrix[:3, :3]) # 只检查3x3旋转/缩放部分
if abs(det) < 1e-10:
print(f"警告: 变换矩阵的3x3部分行列式接近0 (det={det:.2e}),可能导致数值不稳定")
# 检查最后一行是否为 [0, 0, 0, 1](齐次变换矩阵的标准形式)
last_row = transform_matrix[3, :]
if not np.allclose(last_row, [0, 0, 0, 1], atol=1e-6):
print(f"警告: 变换矩阵最后一行不是标准形式 [0,0,0,1],而是: {last_row}")
# 1. 顶点转齐次坐标 (N, 3) → (N, 4) # 1. 顶点转齐次坐标 (N, 3) → (N, 4)
homogeneous_vertices = np.hstack((vertices, np.ones((vertices.shape[0], 1)))) homogeneous_vertices = np.hstack((vertices, np.ones((vertices.shape[0], 1))))
# 2. 应用变换矩阵:矩阵乘法 (4x4) * (4xN) → (4xN) # 2. 应用变换矩阵:矩阵乘法 (4x4) * (4xN) → (4xN)
# 捕获警告并检查结果
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always") # 捕获所有警告
transformed_homogeneous = transform_matrix @ homogeneous_vertices.T transformed_homogeneous = transform_matrix @ homogeneous_vertices.T
# 如果有警告,记录详细信息
if w:
warning_msgs = [str(warning.message) for warning in w]
print(f"警告: 矩阵乘法过程中出现 {len(w)} 个警告:")
for msg in warning_msgs:
print(f" - {msg}")
print(f"变换矩阵:\n{transform_matrix}")
print(f"矩阵包含 NaN: {np.any(np.isnan(transform_matrix))}")
print(f"矩阵包含 Inf: {np.any(np.isinf(transform_matrix))}")
if not np.any(np.isnan(transform_matrix)) and not np.any(np.isinf(transform_matrix)):
print(f"矩阵最大值: {np.nanmax(transform_matrix):.6e}")
print(f"矩阵最小值: {np.nanmin(transform_matrix):.6e}")
# 检查结果是否包含无效值
if np.any(np.isnan(transformed_homogeneous)) or np.any(np.isinf(transformed_homogeneous)):
invalid_count = np.sum(np.isnan(transformed_homogeneous)) + np.sum(np.isinf(transformed_homogeneous))
raise ValueError(f"变换后的顶点包含无效值 (NaN/Inf): {invalid_count} 个无效元素")
# 3. 转回非齐次坐标 (3xN) → (N, 3) # 3. 转回非齐次坐标 (3xN) → (N, 3)
transformed_vertices = transformed_homogeneous[:3, :].T transformed_vertices = transformed_homogeneous[:3, :].T
return transformed_vertices return transformed_vertices
@ -48,8 +93,9 @@ def transform_save(obj_path,homo_matrix):
# log("错误: bpy 模块不可用。此函数只能在 Blender 环境中运行。") # log("错误: bpy 模块不可用。此函数只能在 Blender 环境中运行。")
# log("请使用 Blender 的 Python 解释器运行此脚本,或通过 Blender 命令行运行。") # log("请使用 Blender 的 Python 解释器运行此脚本,或通过 Blender 命令行运行。")
# raise ImportError("bpy 模块不可用。此函数只能在 Blender 环境中运行。") # raise ImportError("bpy 模块不可用。此函数只能在 Blender 环境中运行。")
print("开始转换数据")
obj_name = obj_path.split("/")[-1] obj_name = obj_path.split("/")[-1]
print(f"obj_name={obj_name}")
# 清除场景 # 清除场景
bpy.ops.object.select_all(action='SELECT') bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False) bpy.ops.object.delete(use_global=False)
@ -74,8 +120,28 @@ def transform_save(obj_path,homo_matrix):
mesh_data.vertices.foreach_get('co', original_vertices) mesh_data.vertices.foreach_get('co', original_vertices)
original_vertices = original_vertices.reshape(-1, 3) original_vertices = original_vertices.reshape(-1, 3)
try:
transformed_vertices = custom_mesh_transform(original_vertices, reconstructed_matrix) transformed_vertices = custom_mesh_transform(original_vertices, reconstructed_matrix)
# 验证转换后的顶点是否有效
if np.any(np.isnan(transformed_vertices)) or np.any(np.isinf(transformed_vertices)):
invalid_count = np.sum(np.isnan(transformed_vertices)) + np.sum(np.isinf(transformed_vertices))
error_msg = f"错误: 转换后的顶点包含无效值 (NaN/Inf): {invalid_count} 个无效元素, obj_name={obj_name}"
print(error_msg)
print(f"变换矩阵:\n{reconstructed_matrix}")
raise ValueError(error_msg)
print(f"转换成功: {len(transformed_vertices)} 个顶点")
print(f"顶点坐标范围: X[{transformed_vertices[:, 0].min():.2f}, {transformed_vertices[:, 0].max():.2f}], "
f"Y[{transformed_vertices[:, 1].min():.2f}, {transformed_vertices[:, 1].max():.2f}], "
f"Z[{transformed_vertices[:, 2].min():.2f}, {transformed_vertices[:, 2].max():.2f}]")
except Exception as e:
error_msg = f"转换顶点时发生错误, obj_name={obj_name}, error={str(e)}"
print(error_msg)
print(f"变换矩阵:\n{reconstructed_matrix}")
raise
offset = np.array([-380, -345, 0]) offset = np.array([-380, -345, 0])
transformed_vertices += offset transformed_vertices += offset
print(f"已对模型 {obj_name} 应用偏移: {offset}") print(f"已对模型 {obj_name} 应用偏移: {offset}")
@ -123,5 +189,5 @@ if __name__ == "__main__":
except json.JSONDecodeError as e: except json.JSONDecodeError as e:
print(f"错误: 无法解析 trans 参数为 JSON: {e}") print(f"错误: 无法解析 trans 参数为 JSON: {e}")
sys.exit(1) sys.exit(1)
print("进入转换方法")
transform_save(args.objPathName, homo_matrix) transform_save(args.objPathName, homo_matrix)
Loading…
Cancel
Save