|
|
|
|
@ -1,6 +1,7 @@
@@ -1,6 +1,7 @@
|
|
|
|
|
import os,time,sys,argparse |
|
|
|
|
import numpy as np |
|
|
|
|
import json |
|
|
|
|
import warnings |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def findBpyModule(): |
|
|
|
|
@ -17,11 +18,55 @@ def custom_mesh_transform(vertices, transform_matrix):
@@ -17,11 +18,55 @@ def custom_mesh_transform(vertices, transform_matrix):
|
|
|
|
|
返回: |
|
|
|
|
变换后的顶点数组 (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) |
|
|
|
|
homogeneous_vertices = np.hstack((vertices, np.ones((vertices.shape[0], 1)))) |
|
|
|
|
|
|
|
|
|
# 2. 应用变换矩阵:矩阵乘法 (4x4) * (4xN) → (4xN) |
|
|
|
|
transformed_homogeneous = transform_matrix @ homogeneous_vertices.T |
|
|
|
|
# 捕获警告并检查结果 |
|
|
|
|
with warnings.catch_warnings(record=True) as w: |
|
|
|
|
warnings.simplefilter("always") # 捕获所有警告 |
|
|
|
|
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) |
|
|
|
|
transformed_vertices = transformed_homogeneous[:3, :].T |
|
|
|
|
@ -48,8 +93,9 @@ def transform_save(obj_path,homo_matrix):
@@ -48,8 +93,9 @@ def transform_save(obj_path,homo_matrix):
|
|
|
|
|
# log("错误: bpy 模块不可用。此函数只能在 Blender 环境中运行。") |
|
|
|
|
# log("请使用 Blender 的 Python 解释器运行此脚本,或通过 Blender 命令行运行。") |
|
|
|
|
# raise ImportError("bpy 模块不可用。此函数只能在 Blender 环境中运行。") |
|
|
|
|
|
|
|
|
|
print("开始转换数据") |
|
|
|
|
obj_name = obj_path.split("/")[-1] |
|
|
|
|
print(f"obj_name={obj_name}") |
|
|
|
|
# 清除场景 |
|
|
|
|
bpy.ops.object.select_all(action='SELECT') |
|
|
|
|
bpy.ops.object.delete(use_global=False) |
|
|
|
|
@ -74,7 +120,27 @@ def transform_save(obj_path,homo_matrix):
@@ -74,7 +120,27 @@ def transform_save(obj_path,homo_matrix):
|
|
|
|
|
mesh_data.vertices.foreach_get('co', original_vertices) |
|
|
|
|
original_vertices = original_vertices.reshape(-1, 3) |
|
|
|
|
|
|
|
|
|
transformed_vertices = custom_mesh_transform(original_vertices, reconstructed_matrix) |
|
|
|
|
try: |
|
|
|
|
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]) |
|
|
|
|
transformed_vertices += offset |
|
|
|
|
@ -123,5 +189,5 @@ if __name__ == "__main__":
@@ -123,5 +189,5 @@ if __name__ == "__main__":
|
|
|
|
|
except json.JSONDecodeError as e: |
|
|
|
|
print(f"错误: 无法解析 trans 参数为 JSON: {e}") |
|
|
|
|
sys.exit(1) |
|
|
|
|
|
|
|
|
|
print("进入转换方法") |
|
|
|
|
transform_save(args.objPathName, homo_matrix) |