|
|
|
@ -152,127 +152,6 @@ def compute_mesh_center(vertices): |
|
|
|
centroid = np.array([sum_x / n, sum_y / n, sum_z / n]) |
|
|
|
centroid = np.array([sum_x / n, sum_y / n, sum_z / n]) |
|
|
|
return centroid |
|
|
|
return centroid |
|
|
|
|
|
|
|
|
|
|
|
def load_and_show(base_path, json_name="3DPrintLayout.json"): |
|
|
|
|
|
|
|
# 加载并变换所有模型 |
|
|
|
|
|
|
|
transformed_meshes = load_and_transform_models(base_path, {}, json_name) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if not transformed_meshes: |
|
|
|
|
|
|
|
print("没有加载到任何模型,请检查错误信息") |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
print(f"成功加载并变换了 {len(transformed_meshes)} 个模型") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 可视化所有模型 |
|
|
|
|
|
|
|
print("显示所有模型... (按'Q'退出)") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
from packaging import version |
|
|
|
|
|
|
|
o3d_version = version.parse(o3d.__version__) |
|
|
|
|
|
|
|
# 新版本 draw_geometries 参数 |
|
|
|
|
|
|
|
if o3d_version >= version.parse("0.13.0"): |
|
|
|
|
|
|
|
o3d.visualization.draw_geometries( |
|
|
|
|
|
|
|
transformed_meshes, |
|
|
|
|
|
|
|
window_name="模型展示", |
|
|
|
|
|
|
|
mesh_show_back_face=True, |
|
|
|
|
|
|
|
mesh_show_wireframe=False |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
# 旧版本 draw_geometries 参数 |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
o3d.visualization.draw_geometries( |
|
|
|
|
|
|
|
transformed_meshes, |
|
|
|
|
|
|
|
window_name="模型展示", |
|
|
|
|
|
|
|
point_show_normal=False, |
|
|
|
|
|
|
|
mesh_show_back_face=True |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
|
|
|
|
print(f"使用 draw_geometries 可视化失败: {e}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def setup_orthographic_camera(vis, meshes, ortho_width=15.0, camera_height=20.0): |
|
|
|
|
|
|
|
""" |
|
|
|
|
|
|
|
设置精确的正交投影相机 |
|
|
|
|
|
|
|
""" |
|
|
|
|
|
|
|
view_control = vis.get_view_control() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 计算场景边界框以确定合适的正交参数 |
|
|
|
|
|
|
|
all_points = [] |
|
|
|
|
|
|
|
for mesh in meshes: |
|
|
|
|
|
|
|
if hasattr(mesh, 'vertices'): |
|
|
|
|
|
|
|
points = np.asarray(mesh.vertices) |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
points = np.asarray(mesh.points) |
|
|
|
|
|
|
|
all_points.append(points) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if all_points: |
|
|
|
|
|
|
|
all_points = np.vstack(all_points) |
|
|
|
|
|
|
|
bbox_min = np.min(all_points, axis=0) |
|
|
|
|
|
|
|
bbox_max = np.max(all_points, axis=0) |
|
|
|
|
|
|
|
scene_center = (bbox_min + bbox_max) / 2 |
|
|
|
|
|
|
|
scene_size = np.max(bbox_max - bbox_min) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 设置观察点为场景中心 |
|
|
|
|
|
|
|
view_control.set_lookat(scene_center) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 设置相机在场景上方,俯视场景 |
|
|
|
|
|
|
|
view_control.set_front([0, 0, -1]) # 看向负Z轴(从上向下) |
|
|
|
|
|
|
|
view_control.set_up([0, 1, 0]) # Y轴向上 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
# 启用正交投影 |
|
|
|
|
|
|
|
view_control.set_orthogonal(True) |
|
|
|
|
|
|
|
# 根据场景大小设置正交投影宽度 |
|
|
|
|
|
|
|
view_control.set_orthogonal_width(max(scene_size * 1.2, ortho_width)) |
|
|
|
|
|
|
|
print(f"正交投影已设置: 宽度={max(scene_size * 1.2, ortho_width):.2f}") |
|
|
|
|
|
|
|
except AttributeError: |
|
|
|
|
|
|
|
# 回退到透视投影模拟 |
|
|
|
|
|
|
|
view_control.set_zoom(0.1) |
|
|
|
|
|
|
|
print("使用透视投影模拟正交效果") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return True |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def auto_fit_to_view(vis, meshes): |
|
|
|
|
|
|
|
""" |
|
|
|
|
|
|
|
自动调整视图以显示所有模型 |
|
|
|
|
|
|
|
""" |
|
|
|
|
|
|
|
view_control = vis.get_view_control() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 方法1: 使用 Open3D 的自动适配功能 |
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
view_control.fit_to_geometry(meshes) |
|
|
|
|
|
|
|
print("已自动适配视图以显示所有模型") |
|
|
|
|
|
|
|
return True |
|
|
|
|
|
|
|
except: |
|
|
|
|
|
|
|
pass |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 方法2: 手动计算并设置 |
|
|
|
|
|
|
|
all_points = [] |
|
|
|
|
|
|
|
for mesh in meshes: |
|
|
|
|
|
|
|
if hasattr(mesh, 'vertices'): |
|
|
|
|
|
|
|
points = np.asarray(mesh.vertices) |
|
|
|
|
|
|
|
elif hasattr(mesh, 'points'): |
|
|
|
|
|
|
|
points = np.asarray(mesh.points) |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
continue |
|
|
|
|
|
|
|
all_points.append(points) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if all_points: |
|
|
|
|
|
|
|
all_points = np.vstack(all_points) |
|
|
|
|
|
|
|
bbox_min = np.min(all_points, axis=0) |
|
|
|
|
|
|
|
bbox_max = np.max(all_points, axis=0) |
|
|
|
|
|
|
|
scene_center = (bbox_min + bbox_max) / 2 |
|
|
|
|
|
|
|
scene_size = np.max(bbox_max - bbox_min) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 设置合适的视角和缩放 |
|
|
|
|
|
|
|
view_control.set_lookat(scene_center) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 根据场景大小设置 zoom |
|
|
|
|
|
|
|
zoom_level = max(0.05, min(1.0, 10.0 / scene_size)) |
|
|
|
|
|
|
|
zoom_level = 0.5 |
|
|
|
|
|
|
|
view_control.set_zoom(zoom_level) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print(f"手动适配视图: 场景大小 {scene_size:.2f}, zoom {zoom_level:.3f}") |
|
|
|
|
|
|
|
return True |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return False |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def set_orthographic_camera(view_control, desired_width=1920, desired_height=1080): |
|
|
|
def set_orthographic_camera(view_control, desired_width=1920, desired_height=1080): |
|
|
|
""" |
|
|
|
""" |
|
|
|
通过相机参数设置正交投影,并确保尺寸匹配 |
|
|
|
通过相机参数设置正交投影,并确保尺寸匹配 |
|
|
|
|