我们来详细解读一下 AIS_InteractiveObject
这个类。
AIS_InteractiveObject
是 Open CASCADE Technology (OCCT) 中 AIS (Application Interactive Services) 模块的核心基类。简单来说,你在 OCCT 查看器中看到的、能与之交互(如点击选择、高亮、移动)的任何三维对象,几乎都是从 AIS_InteractiveObject
派生而来的。
这个类的主要职责是为应用程序数据赋予可视化和可选择的特性。它充当了你的业务数据(例如一个几何形状、一个测量尺寸)和 OCCT 的可视化/选择引擎之间的桥梁。
核心概念和设计
-
双重继承身份:
- 它继承自
SelectMgr_SelectableObject
,这赋予了它被选择的能力。这意味着它可以构建用于拾取检测的“敏感图元”(Sensitive Primitives),例如,一个立方体的面、边、顶点都可以被独立选中。 SelectMgr_SelectableObject
本身继承自PrsMgr_PresentableObject
,这赋予了AIS_InteractiveObject
被显示的能力。这意味着它可以生成用于在三维视图中渲染的“表达”(Presentation)。
- 它继承自
-
显示模式 (Display Mode):
- 同一个
AIS_InteractiveObject
可以有多种不同的视觉表现形式。例如,一个机械零件可以以线框模式 (Wireframe)、着色模式 (Shading) 或 带边框的着色模式 (Shading with Edges) 显示。 - 这些不同的显示形式由一个整数索引,即“显示模式”来区分。派生类需要重写
Compute()
方法,根据传入的显示模式索引来生成对应的Prs3d_Presentation
。
- 同一个
-
选择模式 (Selection Mode):
- 与显示模式类似,一个对象也可以有多种被选择的方式。例如,对于一个
TopoDS_Shape
对象,你可以只想选择它的面 (Face),或者只想选择它的边 (Edge),或者顶点 (Vertex)。 - 这些不同的选择粒度由“选择模式”索引来定义。派生类需要重写
ComputeSelection()
方法,根据传入的选择模式索引来生成对应的敏感图元。
- 与显示模式类似,一个对象也可以有多种被选择的方式。例如,对于一个
-
交互式上下文 (
AIS_InteractiveContext
):AIS_InteractiveObject
对象本身并不直接管理自己的显示状态或在视图中的绘制。它必须被注册到一个AIS_InteractiveContext
实例中。AIS_InteractiveContext
是一个总管,负责管理场景中所有AIS_InteractiveObject
对象的生命周期、显示/隐藏、高亮、选择等操作。- 类成员
myCTXPtr
就是一个指向其所属上下文的指针。SetContext()
和GetContext()
方法用于管理这个关联。几乎所有对单个对象的显示操作(如Redisplay
)最终都会委托给AIS_InteractiveContext
来执行。
-
所有者 (
Owner
):myOwner
成员变量允许一个交互对象关联一个“所有者”。这个所有者通常是创建此交互对象的更高级别的业务对象。- 一个典型的例子是:你有一个
TopoDS_Shape
(一个复杂的装配体)。为了让它的某个子形状(比如一个螺栓的面)可以被单独选择,你可能会为这个面创建一个AIS_InteractiveObject
。此时,这个面的AIS_InteractiveObject
的Owner
就可以被设置为代表整个螺栓甚至整个装配体的TopoDS_Shape
。 - 这样做的好处是,当用户在视图中选中这个面时,你的应用程序可以通过
GetOwner()
追溯到它所属的更高级别的业务对象,从而执行相关的业务逻辑。
关键成员函数解析
virtual AIS_KindOfInteractive Type() const
: 返回对象的类型枚举,如AIS_KindOfInteractive_Shape
(形状)、AIS_KindOfInteractive_Datum
(基准)等。用于快速分类对象。virtual Standard_Integer Signature() const
: 类型的进一步签名。例如,同为AIS_KindOfInteractive_Datum
类型,可以用 Signature 来区分点 (1)、线 (5)、平面 (7) 等。void Redisplay(const Standard_Boolean AllModes = Standard_False)
: 请求重绘此对象。它会调用其所属AIS_InteractiveContext
的相应方法来完成。如果AllModes
为真,则对象的所有显示模式都会被重新计算。void SetContext(const Handle(AIS_InteractiveContext)& aCtx)
: 将此对象与一个交互式上下文关联起来。这是对象能够被显示和选择的前提。const Handle(Standard_Transient)& GetOwner() const
/void SetOwner(...)
: 获取和设置对象的所有者,用于建立选择时的业务逻辑追溯链。virtual Standard_Boolean ProcessDragging(...)
: 一个虚函数,用于处理拖拽操作。当用户在视图中拖动此对象时,该方法会被调用。派生类可以重写此方法以实现自定义的拖拽行为。Handle(Prs3d_Presentation) Presentation() const
: 获取对象在当前显示模式下的Prs3d_Presentation
(图形表达)对象。void DumpJson(...)
: 用于调试,将对象的状态信息输出为 JSON 格式。
使用方式总结
开发者通常不会直接实例化 AIS_InteractiveObject
,因为它的 Compute()
和 ComputeSelection()
等关键方法都需要具体实现。
正确的使用方式是:
- 继承: 从
AIS_InteractiveObject
或其更具体的派生类(如AIS_Shape
)派生出你自己的类。 - 实现: 在你的派生类中,持有你的业务数据(比如自定义的几何体、数据点等)。
- 重写:
- 重写
Compute(const Handle(PrsMgr_PresentationManager)& aPresentationManager, const Handle(Prs3d_Presentation)& aPresentation, const Standard_Integer aMode)
方法,在其中根据aMode
(显示模式)将你的业务数据转换为可视化的图元(Prs3d_Presentation
)。 - 重写
ComputeSelection(const Handle(SelectMgr_Selection)& aSelection, const Standard_Integer aMode)
方法,在其中根据aMode
(选择模式)为你的对象创建可被拾取的敏感区域。
- 重写
- 使用: 创建你的派生类的实例,然后调用
AIS_InteractiveContext::Display()
方法将其显示在视图中。
总而言之,AIS_InteractiveObject
是连接应用程序数据和 OCCT 交互式可视化框架的基石。理解它的设计思想对于在 OCCT 中进行二次开发至关重要。