三维模型创建¶
约 579 个字 265 行代码 18 张图片 预计阅读时间 5 分钟
本次给大家分享的是Python_occ的基础API接口OCC.Core.BRepPrimAPI
的使用。对于occ库的安装可在网上自行搜索,比较麻烦。最近在学习open cascade库,会更新比较多有关occ的内容,欢迎正在使用、准备使用Python_occ的开发者一起探讨。
本期内容主要包括:
- 长方体构建
- 球体
- 圆锥
- 圆柱
- 环形
- 旋转体
- 拉伸体
主要流程¶
- 导入
occ
库 - 创建几何对象
- 几何操作
- 后处理显示
注意⚠️:OCCT没有单位的概念;所有旋转体的角度值都是弧度值
长方体 MakeBox¶
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox
from OCC.Display.SimpleGui import init_display
# 创建尺寸为 X=10, Y=20, Z=30 的长方体
box = BRepPrimAPI_MakeBox(10, 20, 30).Shape()
if __name__ == "__main__":
# 初始可视化窗口
display, start_display, _, _ = init_display()
# 显示几何
display.DisplayShape(box, update=True)
# 窗口包围所有可见对象
display.FitAll()
# 交互渲染(阻塞直到窗口关闭)
start_display()
可以在这个基础上进行模型颜色、透明度等的操作:
原方法:
DisplayShape(_shapes_, _material=None_, _texture=None_, _color=None_, _transparency=None_, _update=False_)
关于occt内置的颜色,见下图:
共有521种颜色,数字还挺浪漫~
不同视角¶
display.View_Front()
:正视图View_Bottom()
:仰视图View_Left()
:左视图View_Right()
:右视图View_Top()
:俯视图
更多显示操作可查看:OCC.Display.OCCViewer module
球体 MakeSphere¶
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeSphere
from OCC.Core.gp import gp_Pnt
from OCC.Display.SimpleGui import init_display
center=gp_Pnt(5,5,10) # 三维点:球心
radius=19 # 半径
# 球体几何构造器:BRepPrimAPI_MakeSphere
sphere =BRepPrimAPI_MakeSphere(center ,radius).Shape()
if __name__ == "__main__":
display, start_display, _, _ = init_display()
display.DisplayShape(sphere, update=True)
display.FitAll()
start_display()
可以在这个球体几何基础上增加剖面显示:
from OCC.Core.BRepPrimAPI import (
BRepPrimAPI_MakeSphere,
BRepPrimAPI_MakeHalfSpace,
)
from OCC.Core.BRepAlgoAPI import (
BRepAlgoAPI_Common,
BRepAlgoAPI_Section,
)
from OCC.Core.BRepBuilderAPI import (
BRepBuilderAPI_MakeFace,
BRepBuilderAPI_MakeEdge,
BRepBuilderAPI_MakeWire,
)
from OCC.Core.gp import (
gp_Pnt, gp_Dir, gp_Pln, gp_Ax2, gp_Circ,
)
from OCC.Core.Geom import Geom_Plane
from OCC.Display.SimpleGui import init_display
def make_halves_by_plane(solid, plane_origin: gp_Pnt, plane_normal: gp_Dir):
"""
用平面把封闭体分成两半(上半 / 下半)。
原理:用平面构造两个相反的 half-space,然后分别与 solid 取 Common。
"""
pln = gp_Pln(plane_origin, plane_normal)
face = BRepBuilderAPI_MakeFace(pln).Face()
# 选择在平面两侧的两个点来确定 half-space 的朝向
# 点在平面法向 +/− 方向各偏移 1 个单位
p_above = gp_Pnt(
plane_origin.X() + plane_normal.X(),
plane_origin.Y() + plane_normal.Y(),
plane_origin.Z() + plane_normal.Z(),
)
p_below = gp_Pnt(
plane_origin.X() - plane_normal.X(),
plane_origin.Y() - plane_normal.Y(),
plane_origin.Z() - plane_normal.Z(),
)
hs_above = BRepPrimAPI_MakeHalfSpace(face, p_above).Solid()
hs_below = BRepPrimAPI_MakeHalfSpace(face, p_below).Solid()
# 与 half-space 求交,得到两半
upper_half = BRepAlgoAPI_Common(solid, hs_above).Shape()
lower_half = BRepAlgoAPI_Common(solid, hs_below).Shape()
return upper_half, lower_half, pln
def make_bigger_section_disk(pln: gp_Pln, center: gp_Pnt, radius: float, scale: float = 1.05):
"""
在给定平面上生成一个“比球稍大”的圆盘(用于高亮剖面区域)。
"""
ax2 = gp_Ax2(center, pln.Axis().Direction()) # 圆所在的平面坐标系
circ = gp_Circ(ax2, radius * scale) # 放大一点点
edge = BRepBuilderAPI_MakeEdge(circ).Edge()
wire = BRepBuilderAPI_MakeWire(edge).Wire()
# 用该 wire 在此平面上生成面(圆盘)
geom_plane = Geom_Plane(pln)
face = BRepBuilderAPI_MakeFace(geom_plane, wire, True).Face()
return face
if __name__ == "__main__":
# ---------- 1) 构造球体 ----------
center = gp_Pnt(5, 5, 10)
radius = 19
sphere = BRepPrimAPI_MakeSphere(center, radius).Shape()
# ---------- 2) 定义剖切平面(过球心,法向 +Z) ----------
plane_normal = gp_Dir(0, 0, 1)
# ---------- 3) 切成上下两半 ----------
upper_half, lower_half, pln = make_halves_by_plane(sphere, center, plane_normal)
# ---------- 4) 剖切曲线(红色线条) ----------
section_curve = BRepAlgoAPI_Section(sphere, pln).Shape()
# ---------- 5) 生成更大的剖面圆盘(半透明高亮) ----------
section_disk = make_bigger_section_disk(pln, center, radius, scale=1.2)
# ---------- 6) 显示 ----------
display, start_display, _, _ = init_display()
# 上半球:蓝色,半透明
display.DisplayShape(upper_half, color="BLUE1", transparency=0.35)
# 下半球:绿色,半透明
display.DisplayShape(lower_half, color="GREEN", transparency=0.35)
# 剖面圆盘:金色,更透明(更大一些便于观察边界)
display.DisplayShape(section_disk, color="RED", transparency=0.65)
# 剖切曲线:红色、加粗
display.DisplayShape(section_curve, color="RED")
display.FitAll()
start_display()
圆锥 MakeCone¶
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeCone
from OCC.Display.SimpleGui import init_display
cone = BRepPrimAPI_MakeCone(1,0,4).Shape()
if __name__ == "__main__":
display, start_display, _, _ = init_display()
display.DisplayShape(cone, update=True, color='BLUE1', transparency=0.5)
display.FitAll()
start_display()
也可以通过指定顶点和方向向量来构造圆锥:
MakeCone
:“底半径 R1、顶半径 R2、高度 H”生成实体圆锥/圆台gp_Ax2
:带原点+法向+X方向的**坐标系**(定义几何的“放置/朝向”)gp_Dir
:单位方向向量cone = BRepPrimAPI_MakeCone(1, 0, 4).Shape()
:底半径为1,顶半径为0,高度为4
指定上下半径都有值时,可构造圆台几何:
圆柱体 MakeCylinder¶
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeCylinder
from OCC.Display.SimpleGui import init_display
import OCC.Core.Quantity as Q
cylinder = BRepPrimAPI_MakeCylinder(10,30).Shape()
display, start_display, _, _ = init_display()
display.DisplayShape(cylinder, color = Q.Quantity_NOC_GRAY31, transparency=0.45)
display.FitAll()
start_display()
OCC.Core.Quantity
,导入occ内置的颜色,当然也可以使用自定义的RGB颜色BRepPrimAPI_MakeCylinder
,构造圆柱体实体几何
该方法的文档已经非常详细,传入参数还可指定轴、角度。
部分圆柱¶
指定轴¶
# 轴向沿-Z;底面过 (60, 0, 0)
ax2_down = gp_Ax2(gp_Pnt(60, 0, 0), gp_Dir(0, 0, -1))
cyl_ax = BRepPrimAPI_MakeCylinder(ax2_down, 8.0, 25.0).Shape()
带放置的部分圆柱¶
ax2_x = gp_Ax2(gp_Pnt(0, 60, 0), gp_Dir(1, 0, 0))
cyl_ax_partial = BRepPrimAPI_MakeCylinder(ax2_x, 12.0, 20.0, radians(120.0)).Shape()
厚壁圆柱(空心):外圆柱 - 内圆柱¶
outer = BRepPrimAPI_MakeCylinder(14.0, 26.0).Shape()
inner = BRepPrimAPI_MakeCylinder(10.0, 26.0).Shape()
cyl_hollow = BRepAlgoAPI_Cut(outer, inner).Shape()
在这里调用了BRepAlgoAPI_Cut
方法,后续会分享该方法的具体用法。
环形 MakeTorus¶
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeTorus
from OCC.Display.SimpleGui import init_display
import OCC.Core.Quantity as Q
from OCC.Core.gp import gp_Pnt
from OCC.Core.gp import gp_Ax2,gp_Dir
torus = BRepPrimAPI_MakeTorus(gp_Ax2 (gp_Pnt (0,0,2),gp_Dir (0,0,1)),0.55,0.1).Shape()
display, start_display, _, _ = init_display()
display.DisplayShape(torus, color = Q.Quantity_NOC_GRAY31, transparency=0.45)
display.FitAll()
start_display()
- 核心参数:
BRepPrimAPI_MakeTorus(外半径,内半径)
- 在这个基础上也可以传入
angle
、Axes
等参数
部分环面¶
旋转体 MakeRevol¶
Edge旋转¶
# 轴:过原点、沿 Z
axis = gp_Ax1(gp_Pnt(0,0,0), gp_Dir(0,0,1))
R, H = 10.0, 25.0
e1 = BRepBuilderAPI_MakeEdge(gp_Pnt(R,0,0), gp_Pnt(R,0,H)).Edge()
surf = BRepPrimAPI_MakeRevol(e1, axis, radians(270)).Shape() # 旋转 270°
display.DisplayShape(surf, color=Q.Quantity_NOC_SKYBLUE, transparency=0.35, update=False)
Face旋转¶
# 在 XZ 平面做一个矩形截面:内半径 ri,外半径 ro,高 H
ri, ro, H = 6.0, 10.0, 20.0
# 面的轮廓: (ri,0,0)->(ro,0,0)->(ro,0,H)->(ri,0,H)->回到(ri,0,0)
e21 = BRepBuilderAPI_MakeEdge(gp_Pnt(ri,0,0), gp_Pnt(ro,0,0)).Edge()
e22 = BRepBuilderAPI_MakeEdge(gp_Pnt(ro,0,0), gp_Pnt(ro,0,H)).Edge()
e23 = BRepBuilderAPI_MakeEdge(gp_Pnt(ro,0,H), gp_Pnt(ri,0,H)).Edge()
e24 = BRepBuilderAPI_MakeEdge(gp_Pnt(ri,0,H), gp_Pnt(ri,0,0)).Edge()
w2 = BRepBuilderAPI_MakeWire(e21, e22, e23, e24).Wire()
f2 = BRepBuilderAPI_MakeFace(w2).Face()
solid = BRepPrimAPI_MakeRevol(f2, axis).Shape() # 默认 2π
display.DisplayShape(solid, color=Q.Quantity_NOC_SEAGREEN, transparency=0.25, update=False)
完整代码:
from math import radians
import OCC.Core.Quantity as Q
from OCC.Display.SimpleGui import init_display
from OCC.Core.gp import gp_Pnt, gp_Ax1, gp_Dir
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeRevol
from OCC.Core.BRepBuilderAPI import (
BRepBuilderAPI_MakeEdge, BRepBuilderAPI_MakeWire, BRepBuilderAPI_MakeFace
)
display, start_display, _, _ = init_display()
# 轴:过原点、沿 Z
axis = gp_Ax1(gp_Pnt(0,0,0), gp_Dir(0,0,1))
# -----------------------------------------------------------
# 例1:把一条母线(边)绕 Z 轴旋转,得到“圆柱侧面”(曲面,没有端盖)
# 母线:XZ 平面的线段 (R,0,0) -> (R,0,H)
R, H = 10.0, 25.0
e1 = BRepBuilderAPI_MakeEdge(gp_Pnt(R,0,0), gp_Pnt(R,0,H)).Edge()
surf = BRepPrimAPI_MakeRevol(e1, axis, radians(270)).Shape() # 旋转 270°
display.DisplayShape(surf, color=Q.Quantity_NOC_SKYBLUE, transparency=0.35, update=False)
# -----------------------------------------------------------
# 例2:把闭合面绕 Z 轴旋转 2π,得到“空心圆柱实体”(有内外壁与端盖)
# 在 XZ 平面做一个矩形截面:内半径 ri,外半径 ro,高 H
ri, ro, H = 6.0, 10.0, 20.0
# 轮廓: (ri,0,0)->(ro,0,0)->(ro,0,H)->(ri,0,H)->回到(ri,0,0)
e21 = BRepBuilderAPI_MakeEdge(gp_Pnt(ri,0,0), gp_Pnt(ro,0,0)).Edge()
e22 = BRepBuilderAPI_MakeEdge(gp_Pnt(ro,0,0), gp_Pnt(ro,0,H)).Edge()
e23 = BRepBuilderAPI_MakeEdge(gp_Pnt(ro,0,H), gp_Pnt(ri,0,H)).Edge()
e24 = BRepBuilderAPI_MakeEdge(gp_Pnt(ri,0,H), gp_Pnt(ri,0,0)).Edge()
w2 = BRepBuilderAPI_MakeWire(e21, e22, e23, e24).Wire()
f2 = BRepBuilderAPI_MakeFace(w2).Face()
solid = BRepPrimAPI_MakeRevol(f2, axis).Shape() # 不给角度=默认 2π
display.DisplayShape(solid, color=Q.Quantity_NOC_SEAGREEN, transparency=0.25, update=False)
display.FitAll()
start_display()
拉伸体 MakePrism¶
BRepPrimAPI_MakePrism(S: TopoDS_Shape, V: gp_Vec)
:用于把一个二维形体(轮廓、面等)沿某个方向拉伸成棱柱体。
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakePrism
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeFace, BRepBuilderAPI_MakeWire
from OCC.Core.gp import gp_Pnt, gp_Vec
import OCC.Core.Quantity as Q
from OCC.Display.SimpleGui import init_display
# 1) 构造一个矩形 Wire
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_MakeEdge
e1 = BRepBuilderAPI_MakeEdge(gp_Pnt(0,0,0), gp_Pnt(10,0,0)).Edge()
e2 = BRepBuilderAPI_MakeEdge(gp_Pnt(10,0,0), gp_Pnt(10,5,0)).Edge()
e3 = BRepBuilderAPI_MakeEdge(gp_Pnt(10,5,0), gp_Pnt(0,5,0)).Edge()
e4 = BRepBuilderAPI_MakeEdge(gp_Pnt(0,5,0), gp_Pnt(0,0,0)).Edge()
wire = BRepBuilderAPI_MakeWire(e1, e2, e3, e4).Wire()
face = BRepBuilderAPI_MakeFace(wire).Face()
# 2) 拉伸:沿 Z 方向 20
vec = gp_Vec(0, 0, 20)
prism = BRepPrimAPI_MakePrism(face, vec).Shape()
# 3) 显示
display, start_display, _, _ = init_display()
display.DisplayShape(face, color=Q.Quantity_NOC_YELLOWGREEN, transparency=0.1, update=False)
display.DisplayShape(prism, color=Q.Quantity_NOC_TURQUOISE3, transparency=0.6, update=True)
display.FitAll()
start_display()