Files
innovate_project/3D_construction/script/demo_ideal_model.py
2025-11-02 21:36:35 +08:00

113 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# demo_final_beautiful.py
# 最终美化版:无图例,专注焊缝模型本身的高质量渲染。
# 运行python demo_final_beautiful.py
import numpy as np
import open3d as o3d
from typing import Dict
def get_final_ideal_ground_truth() -> Dict:
"""
使用你提供的最终版理想坐标。
"""
print("--- Using your final provided ideal coordinates. ---")
final_3_seams = {
'bottom_left': {
'start_3d': np.array([-142.2 + 8.9, 0.0, 0.0]),
'end_3d': np.array([-2.7, 0.0, 0.0])
},
'middle': {
'start_3d': np.array([0.0, 0.0, 0.0]),
'end_3d': np.array([0.0, -50.3, 0.0])
},
'top_left': {
'start_3d': np.array([0.0, 0.0, 5.2]),
'end_3d': np.array([0.0, 0.0, 142.5])
}
}
return final_3_seams
def rotation_matrix_from_vectors(vec_from: np.ndarray, vec_to: np.ndarray) -> np.ndarray:
"""计算从 vec_from 到 vec_to 的旋转矩阵。"""
a = vec_from / (np.linalg.norm(vec_from) + 1e-12)
b = vec_to / (np.linalg.norm(vec_to) + 1e-12)
v = np.cross(a, b)
c = np.clip(np.dot(a, b), -1.0, 1.0)
s = np.linalg.norm(v)
if s < 1e-12:
return np.eye(3) if c > 0.0 else -np.eye(3)
kmat = np.array([[0, -v[2], v[1]], [v[2], 0, -v[0]], [-v[1], v[0], 0]], dtype=float)
return np.eye(3) + kmat + kmat @ kmat * ((1.0 - c) / (s ** 2))
def visualize_beautiful_model(seams: Dict):
"""
【最终美化版】可视化:
- 使用PBR材质增加金属质感。
- 增加灯光,增强立体感。
- 设置一个好的初始视角。
"""
print("\n--- Visualizing Final Target Model (High Quality Render) ---")
colors = {'bottom_left': [0.8, 0.1, 0.1], 'middle': [0.1, 0.8, 0.1], 'top_left': [0.1, 0.1, 0.8]}
geoms = []
# 1. 绘制焊缝主体 (圆柱体)
radius = 0.5 # 适中的粗细
for name, data in seams.items():
start, end = np.asarray(data['start_3d']), np.asarray(data['end_3d'])
direction = end - start
length = np.linalg.norm(direction)
if length < 1e-6: continue
cyl = o3d.geometry.TriangleMesh.create_cylinder(radius=radius, height=length, resolution=64)
cyl.compute_vertex_normals() # 法线对于光照计算至关重要
R = rotation_matrix_from_vectors(np.array([0.0, 0.0, 1.0]), direction)
cyl.rotate(R, center=(0, 0, 0)).translate((start + end) / 2.0)
cyl.paint_uniform_color(colors[name])
geoms.append(cyl)
# 2. 移动坐标轴到不遮挡的位置
all_points = [p for data in seams.values() for p in data.values()]
bbox = o3d.geometry.AxisAlignedBoundingBox.create_from_points(o3d.utility.Vector3dVector(all_points))
axis_size = max(30.0, np.linalg.norm(bbox.get_extent()) * 0.2)
axis_origin = bbox.get_min_bound() - np.array([axis_size * 1.5, axis_size * 0.5, 0])
frame = o3d.geometry.TriangleMesh.create_coordinate_frame(size=axis_size, origin=axis_origin)
geoms.append(frame)
# 3. 可视化
vis = o3d.visualization.Visualizer()
vis.create_window(window_name="Final Target Model (High Quality)", width=1280, height=720)
for g in geoms:
vis.add_geometry(g)
# --- 渲染和视角设置 ---
opt = vis.get_render_option()
opt.background_color = np.asarray([0.1, 0.1, 0.1]) # 深灰色背景,突出主体
opt.mesh_show_back_face = False
opt.light_on = True # 确保灯光已开启
# 获取视图控制器并设置相机位置
view_ctl = vis.get_view_control()
# 这个函数会自动计算一个能看全所有物体的合适视角
vis.reset_view_point(True)
# 你可以进一步手动调整相机参数以获得特定角度
# view_ctl.set_zoom(0.8)
# view_ctl.rotate(x=100, y=100) # 旋转视角
print("Visualization ready. You can rotate the view. Press 'Q' to close.")
vis.run()
vis.destroy_window()
if __name__ == '__main__':
seams = get_final_ideal_ground_truth()
print("--- Final Ideal Seam Coordinates ---")
for n, p in seams.items():
print(f"{n}: start={np.around(p['start_3d'], 1)}, end={np.around(p['end_3d'], 1)}")
visualize_beautiful_model(seams)