几何变换 (Transformation) ------ 在 OpenCascade (OCC) 里主要通过 gp_Trsf
来完成,搭配 BRepBuilderAPI_Transform
对形体应用。
基础类 gp_Trsf
gp_Trsf
表示一个仿射变换,常用方法:
- SetTranslation 平移
- SetRotation 旋转
- SetScale 缩放
- SetMirror 镜像
平移 Translation
python
from OCC.Core.gp import gp_Trsf, gp_Vec
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_Transform
trsf = gp_Trsf()
trsf.SetTranslation(gp_Vec(10, 0, 0)) # 沿 X 平移 10
moved_shape = BRepBuilderAPI_Transform(shape, trsf).Shape()
旋转 Rotation
python
from OCC.Core.gp import gp_Trsf, gp_Ax1, gp_Pnt, gp_Dir
import math
trsf = gp_Trsf()
axis = gp_Ax1(gp_Pnt(0,0,0), gp_Dir(0,0,1)) # 旋转轴:过原点,沿 Z
trsf.SetRotation(axis, math.radians(45)) # 旋转 45°
rotated_shape = BRepBuilderAPI_Transform(shape, trsf).Shape()
缩放 Scale
python
from OCC.Core.gp import gp_Trsf, gp_Pnt
trsf = gp_Trsf()
center = gp_Pnt(0,0,0) # 缩放中心
trsf.SetScale(center, 2.0) # 放大 2 倍
scaled_shape = BRepBuilderAPI_Transform(shape, trsf).Shape()
镜像 (Mirror)
镜像有三种方式:
- 关于点对称 :
SetMirror(P)
- 关于直线对称 :
SetMirror(Ax1)
- 关于平面对称 :
SetMirror(Ax2)
python
from OCC.Core.gp import gp_Ax1, gp_Ax2, gp_Pnt, gp_Dir
trsf = gp_Trsf()
# 1) 关于点对称
trsf.SetMirror(gp_Pnt(0,0,0))
# 2) 关于直线对称(X 轴)
trsf.SetMirror(gp_Ax1(gp_Pnt(0,0,0), gp_Dir(1,0,0)))
# 3) 关于平面对称(XY 平面)
trsf.SetMirror(gp_Ax2(gp_Pnt(0,0,0), gp_Dir(0,0,1)))
mirrored_shape = BRepBuilderAPI_Transform(shape, trsf).Shape()
包装
我们可以写一个transform_shape
方法,专门用于几何形状变换,传入关键参数即可:
python
from OCC.Core.gp import gp_Trsf, gp_Vec, gp_Pnt, gp_Dir, gp_Ax1, gp_Ax2
from OCC.Core.BRepBuilderAPI import BRepBuilderAPI_Transform
import math
def transform_shape(shape, mode, params):
"""
通用几何变换工具函数
:param shape: TopoDS_Shape
:param mode: 变换类型 ["translate", "rotate", "scale", "mirror"]
:param params: 参数字典
- translate: {"vec": (x,y,z)}
- rotate: {"axis_point": (x,y,z), "axis_dir": (dx,dy,dz), "angle": deg}
- scale: {"center": (x,y,z), "factor": f}
- mirror:
{"point": (x,y,z)} # 点对称
{"axis_point": (x,y,z), "axis_dir": (dx,dy,dz)} # 轴对称
{"plane_point": (x,y,z), "plane_dir": (dx,dy,dz)} # 平面对称
:return: 新的 TopoDS_Shape
"""
trsf = gp_Trsf()
if mode == "translate":
v = gp_Vec(*params["vec"])
trsf.SetTranslation(v)
elif mode == "rotate":
p = gp_Pnt(*params["axis_point"])
d = gp_Dir(*params["axis_dir"])
axis = gp_Ax1(p, d)
angle = math.radians(params["angle"])
trsf.SetRotation(axis, angle)
elif mode == "scale":
p = gp_Pnt(*params["center"])
f = params["factor"]
trsf.SetScale(p, f)
elif mode == "mirror":
if "point" in params: # 点对称
trsf.SetMirror(gp_Pnt(*params["point"]))
elif "axis_point" in params and "axis_dir" in params: # 轴对称
p = gp_Pnt(*params["axis_point"])
d = gp_Dir(*params["axis_dir"])
trsf.SetMirror(gp_Ax1(p, d))
elif "plane_point" in params and "plane_dir" in params: # 平面对称
p = gp_Pnt(*params["plane_point"])
d = gp_Dir(*params["plane_dir"])
trsf.SetMirror(gp_Ax2(p, d))
else:
raise ValueError("Invalid mirror parameters")
else:
raise ValueError("Unknown transformation mode: " + str(mode))
return BRepBuilderAPI_Transform(shape, trsf).Shape()
然后直接一行代码调用即可:
python
from OCC.Core.BRepPrimAPI import BRepPrimAPI_MakeBox
from OCC.Display.SimpleGui import init_display
import OCC.Core.Quantity as Q
from transform_shape import transform_shape
display, start_display, *_ = init_display()
box = BRepPrimAPI_MakeBox(10,20,30).Shape()
display.DisplayShape(box, color=Q.Quantity_NOC_BLUE3, transparency=0.5, update=False)
# 平移
# box_t = transform_shape(box, "translate", {"vec": (40,0,0)})
# display.DisplayShape(box_t, color=Q.Quantity_NOC_GRAY31, transparency=0.5, update=False)
# # 旋转
# box_r = transform_shape(box, "rotate",
# {"axis_point": (0,0,0), "axis_dir": (0,0,1), "angle": 45})
# display.DisplayShape(box_r, color=Q.Quantity_NOC_GRAY31, update=False)
# # 缩放
# box_s = transform_shape(box, "scale", {"center": (0,0,0), "factor": 0.5})
# display.DisplayShape(box_s, color=Q.Quantity_NOC_GRAY31, update=False)
# # 镜像(XY 平面)
box_m = transform_shape(box, "mirror", {"plane_point": (0,0,0), "plane_dir": (0,0,1)})
display.DisplayShape(box_m, color=Q.Quantity_NOC_GRAY31, update=False)
display.FitAll()
start_display()



