详解 OCCT Class SelectMgr_SelectableObject

我们来深入解析 SelectMgr_SelectableObject 这个类。SelectMgr_SelectableObjectAIS_InteractiveObject 的直接父类,它专门负责定义一个对象“可被选择”的特性和行为。

可以把它看作是 OCCT 选择机制中的核心数据模型。它本身不执行选择操作,而是为选择管理器 (SelectMgr_SelectionManager) 提供所有必要的信息,告诉管理器:“我这里有哪些部分可以被选择,它们在哪里,以及选中后它们代表什么”。


核心职责与设计理念

  1. 继承自 PrsMgr_PresentableObject:

    • 这一点至关重要。它意味着任何一个“可选的”对象,首先必须是一个“可显示的”对象。这在逻辑上是通顺的,因为你通常只能选择你看得见的东西。
    • 它继承了 Compute() 等与显示相关的方法,但它自身的关注点并不在此,而是将这些职责留给子类(如 AIS_InteractiveObject)或保持默认行为。
  2. 定义“可选择性”的契约 (The Contract):

    • 这个类的核心是一个纯虚函数:virtual void ComputeSelection(...) = 0;
    • 这是一个“契约”或“接口”。任何想要成为可选对象的类,都必须实现这个方法。
    • ComputeSelection 的作用是:当选择管理器需要知道这个对象如何被选择时,它会调用此方法。方法的实现者需要创建一系列的“敏感图元 (Sensitive Primitives)”并把它们填充到传入的 SelectMgr_Selection 对象中。
  3. 什么是敏感图元 (Sensitive Primitives)?

    • 敏感图元是用于拾取检测的几何实体,它们不一定被直接渲染出来。例如,对于一个三维立方体,它的敏感图元可以是:
      • 代表6个面的 SelectMgr_SensitiveFace
      • 代表12条边的 SelectMgr_SensitiveEdge
      • 代表8个顶点的 SelectMgr_SensitiveVertex
    • 当用户在视图中点击时,OCCT 的选择算法实际上是在检测鼠标射线是否与这些敏感图元相交,而不是与显示的像素相交。
  4. 选择模式 (Selection Mode):

    • ComputeSelection 方法接受一个 theMode 参数。这允许同一个 SelectMgr_SelectableObject 对象根据不同的模式提供不同的敏感图元。
    • 例如,对于一个 AIS_ShapetheMode = 0 可能代表选择整个形状,此时 ComputeSelection 只创建一个代表整个形状包围盒的敏感图元。而 theMode = 4 可能代表选择面,此时 ComputeSelection 就会遍历形状的所有面,并为每个面创建一个 SelectMgr_SensitiveFace
  5. 管理高亮和选中状态的“特殊显示”:

    • 当鼠标滑过一个对象(检测到,Hilight)或点击选中一个对象(选中,Select)时,通常需要用不同的颜色或样式来高亮它。
    • SelectMgr_SelectableObject 内部维护了两个特殊的显示对象:myHilightPrsmySelectionPrs
    • 它提供了一套方法(如 HilightSelected, HilightOwnerWithColor, GetHilightPresentation)来管理这种临时的、用于反馈的特殊高亮效果,将它们与对象本身的常规显示(由 PrsMgr_PresentableObject 管理)分离开来。myAutoHilight 标志位决定了是由框架自动处理高亮还是由子类完全接管。

关键成员函数解析

  • virtual void ComputeSelection(...) = 0: 最重要的纯虚函数。派生类必须实现它,以定义对象在特定选择模式下如何被分解为可供选择的敏感图元。
  • void AddSelection(...) / const Handle(SelectMgr_Selection)& Selection(...) const: 用于管理和查询对象在不同选择模式下已经计算好的 SelectMgr_Selection 实例。框架内部会缓存 ComputeSelection 的结果,避免重复计算。
  • void ClearSelections(...): 清除所有已缓存的选择结果,以便下次重新计算。
  • void UpdateSelection(const Standard_Integer theMode = -1): 非常重要的方法。当你的业务数据发生变化(例如,形状被移动或修改),导致其敏感图元需要更新时,你应该调用这个方法。它会安全地标记选择需要更新,以便选择管理器在适当的时候重新调用 ComputeSelection。你不应该直接调用 RecomputePrimitives,因为它可能会导致内部数据结构(如 BVH 树)不一致。
  • virtual void HilightSelected(...) / ClearSelected(): 负责绘制和清除“选中”状态下的高亮效果。
  • Handle(Prs3d_Presentation) GetHilightPresentation(...) / GetSelectPresentation(...): 获取用于“检测时高亮”和“选中时高亮”的专用 Prs3d_Presentation 对象。
  • virtual Standard_Boolean IsAutoHilight() const: 返回一个布尔值,指示高亮是由选择管理器自动处理,还是由对象自己通过重写 HilightSelected 等方法来完全控制。

与其他核心类的关系

  • PrsMgr_PresentableObject (父类): 提供了“可显示”的能力。
  • AIS_InteractiveObject (子类): 是 SelectMgr_SelectableObject 最常见的、功能完备的实现。它在 SelectMgr_SelectableObject 的基础上增加了与交互式上下文 (AIS_InteractiveContext) 的关联,以及拖拽等更高级的交互功能。
  • SelectMgr_SelectionManager (合作者): 这是选择过程的“指挥官”。它管理所有 SelectableObject,当需要进行选择时,它会调用 SelectableObjectComputeSelection 来获取敏感图元,然后执行拾取算法。
  • SelectMgr_EntityOwner (数据载体): 当一个敏感图元被选中时,如何知道选中的是“什么”?每个敏感图元内部都持有一个 SelectMgr_EntityOwner 的句柄。这个 Owner 就像一个“身份证”,它持有一个指向原始 SelectableObject 的指针,并带有一个优先级和一个可选的、指向更具体业务数据(如 TopoDS_Shape)的指针。应用程序通过分析这个 Owner 来理解用户的选择意图。

总结

SelectMgr_SelectableObject 是一个比 AIS_InteractiveObject 更基础、更抽象的类。它精确地定义了一个对象成为“可选实体”所必须遵守的规则和提供的能力。它是一个纯粹的数据提供者,为上层的选择框架服务,是连接你的业务模型和 OCCT 底层选择机制的桥梁。

你可能感兴趣的:(详解 OCCT Class SelectMgr_SelectableObject)