在Python 中可以使用开源的三维库(例如 trimesh)来创建简单的管线模型,并将其导出为多种 3D 模型格式。本文为大家介绍如何使用 trimesh 创建圆直管并导出为 .obj 等通用三维格式模型。
pip安装trimesh
pip install trimesh
支持的文件格式
trimesh 支持多种文件格式的导出,包括:
• .obj(Wavefront OBJ)
• .stl(Stereolithography)
• .glb/.gltf(glTF 2.0)
• .ply(Polygon File Format)
• .off(Object File Format)
你可以使用以下代码列出所有支持的文件格式:
import trimesh
# 列出支持的文件格式
formats = trimesh.available_formats()
print("支持的导出格式:", formats)
圆直管
下面的代码示例展示了如何用 trimesh 创建一个圆柱体模型,并导出为 .obj 文件:
import trimesh
创建圆柱体模型 半径为1 高度为2
cylinder = trimesh.creation.cylinder(radius=1.0, height=2.0)
# 导出为 .obj 文件
output_path = "cylinder.obj"
cylinder.export(output_path)
print(f"模型成功导出至 {output_path}")
你可以使用 trimesh 库围绕一条指定的线(由线的两端点坐标确定)创建圆柱体。可以使用变换矩阵将基本几何体变换到你想要的位置和方向。下面是一个指定线的两个端点坐标并创建圆柱体的案例。
创建围绕指定两点坐标的圆柱体
import trimesh
import numpy as np
def create_cylinder_along_line(point1, point2, radius=1.0):
direction = np.array(point2) - np.array(point1)
height = np.linalg.norm(direction)
unit_direction = direction / height
z_axis = np.array([0, 0, 1]) # The cylinder is initially aligned with the z-axis
axis = np.cross(z_axis, unit_direction)
angle = np.arccos(np.dot(z_axis, unit_direction))
if np.linalg.norm(axis) == 0:
rotation_matrix = np.eye(3) # Identity matrix if vectors are parallel
else:
axis = axis / np.linalg.norm(axis)
K = np.array([[0, -axis[2], axis[1]],
[axis[2], 0, -axis[0]],
[-axis[1], axis[0], 0]])
rotation_matrix = np.eye(3) + np.sin(angle) * K + (1 - np.cos(angle)) * np.dot(K, K)
midpoint = (np.array(point1) + np.array(point2)) / 2
translation_matrix = np.eye(4)
translation_matrix[:3, 3] = midpoint
transform = np.eye(4)
transform[:3, :3] = rotation_matrix
transform = np.dot(translation_matrix, transform)
cylinder = trimesh.creation.cylinder(radius=radius, height=height)
cylinder.apply_transform(transform)
return cylinder
# 用法示例
point1 = [0, 0, 0] # 管线起点坐标
point2 = [1, 20, 3] # 管线终点坐标
radius = 0.5 # 管直径
cylinder = create_cylinder_along_line(point1, point2, radius)
output_path = "cylinder_along_line.obj"
cylinder.export(output_path)
print(f"模型导出至 {output_path}")
代码解释
1.方向向量计算:direction = np.array(point2) - np.array(point1),计算由两个端点坐标定义的方向向量。
2.标准化方向向量:unit_direction = direction / height,得到标准化的方向向量。
3.计算旋转矩阵:通过方向向量和单位 z 轴之间的夹角计算旋转矩阵,将圆柱体从 z 轴方向旋转到目标方向。
4.平移矩阵:平移到两个端点的中点。
5.组合变换矩阵:旋转和平移矩阵组合,应用到圆柱体上。
可以为管线添加指定的颜色.
import trimesh
# 创建圆柱体
cylinder = trimesh.creation.cylinder(radius=1.0, height=4.0)
# 为网格的每个面指定颜色
cylinder.visual.face_colors = [255, 0, 0, 255] # 红色,RGBA 格式
# 导出
cylinder.export("colored_cylinder.obj")
此外,你还可以将模型导出成其他通用的三维格式.
# 导出为 .stl 文件
cylinder.export("cylinder_along_line.stl")
# 导出为 .gltf 文件
cylinder.export("cylinder_along_line.gltf")
方管
下面的代码示例展示了如何用 trimesh根据直线的两点坐标实现方管建模,并导出为 .obj 文件:
import trimesh
import numpy as np
def create_rectangular_pipe_along_line(point1, point2, width=1.0, height=1.0):
# 计算两点间的方向向量和长度
direction = np.array(point2) - np.array(point1)
length = np.linalg.norm(direction)
# 计算单位方向向量
unit_direction = direction / length
# 创建基础方管
box = trimesh.creation.box(extents=[width, height, length])
# 计算旋转矩阵,将方管从 Z 轴方向旋转到目标方向
z_axis = np.array([0, 0, 1]) # 方管初始方向为 Z 轴
axis = np.cross(z_axis, unit_direction)
angle = np.arccos(np.dot(z_axis, unit_direction))
if np.linalg.norm(axis) == 0:
rotation_matrix = np.eye(3) # 如果方向相同或相反,则使用单位矩阵
else:
axis = axis / np.linalg.norm(axis)
K = np.array([[0, -axis[2], axis[1]],
[axis[2], 0, -axis[0]],
[-axis[1], axis[0], 0]])
rotation_matrix = np.eye(3) + np.sin(angle) * K + (1 - np.cos(angle)) * np.dot(K, K)
# 创建旋转和平移矩阵
translation_matrix = np.eye(4)
translation_matrix[:3, 3] = (np.array(point1) + np.array(point2)) / 2 # 平移到两点的中间
transform = np.eye(4)
transform[:3, :3] = rotation_matrix
transform = np.dot(translation_matrix, transform)
# 应用旋转和平移矩阵
box.apply_transform(transform)
return box
# 示例:沿着一条线创建方管
point1 = [0, 0, 0] # 线的起点
point2 = [20, 30, 1] # 线的终点
width = 0.5 # 方管的宽度
height = 0.5 # 方管的高度
rectangular_pipe = create_rectangular_pipe_along_line(point1, point2, width=width, height=height)
rectangular_pipe.export(r"E:\rectangular_pipe1.obj")
还可以添加赋色代码,为模型赋予颜色
box.visual.face_colors = (0, 255, 0, 255) # RGBA 绿色