为了给外部提供方便的接口, Occt 在显示模块的最上层提供了 AIS(Application interactive services) 功能。 AIS 功能封装了显示模块内部的大多数功能,提供了对几何和拓朴对象的显示和选择和管理,功能包括:
显示对象,包括对象的显示颜色、显示模式等的管理
对象的选择功能,包括:根据鼠标事件和坐标数据,实现对象的选中判断,自动高亮显示、高亮显示等。
AIS 功能,使用了三部分来实现其功能,简单的说,用一个类代表可显示的对象,用一个类实现对对象显示和选择相关内容的管理,用一个视图类使对象在一个视图中显示,并允许被以多种方式显示。具体如下:
可显示对象,是一个可以显示和选择的对象,通常包含一个几何或拓扑对象。这些几何或拓朴对象,通过 mesh 模块中的算法,生成对应的图形对象,以用于对象的绘制。
视图管理器允许交互操作显示对象的视图,例如:旋转视图、缩放视图等,方便在窗口中观察显示的对象。
显示和选择的上下文管理对象,负责显示对象的管理,提供显示对象、选择对象等功能,使对象的显示和选择编程实现很简单。
具体来看每个类。
AIS_interactiveContext 类
主要功能是对一组可显示和选择的对象的管理功能,包括:显示对象、对象选择、对象高亮显示、对象颜色等等。
其内部
该类提供了丰富的接口,功能很强大,是 AIS 中最主要的类。
AIS_interactiveObject 类:
继承关系如下:
PrsMgr_PresentableObject
―― StdSelect_Shape
―― SelectMgr_SelectableObject
―――― AIS_InteractiveObject
从 PrsMgr_PresentableObject 继承了显示功能,从 SelectMgr_SelectableObject 类继承了选择功能,因此是一个可显示和选择的对象。
PrsMgr_PresentableObject 类表示一个可显示的对象,在 Occt 中,每个对象可能有多种显示模式,例如:线框显示、着色显示、包围盒显示、纹理显示等,每种模式对应不同的可显示的数据,每种可显示数据由类 PrsMgr_Presentation 类表示。 PrsMgr_PresentableObject 类记录了一个列表,其中每项是一个模式码和其对应的显示数据。例如:对应线框模式,保存了线框模式下的图形对象,主要是边界线的离散数据。对应着色模式,保存了着色模式下的图形对象,对曲面来说,就是曲面的三角面片剖分的数据。
SelectMgr_SelectableObject 类代表一个可选择的对象,并根据选择状态,给出不同的显示,比如:高亮显、显示流线等。因此,它包含了两种状态下的显示数据:选中状态的显示数据和高亮状态下的显示数据(两个 PrsMgr_Presentation 类)。通常, OCCT 下选中对象时,显示对象的 Iso 曲线,表示对象被选中,则此时对应的显示数据就是 Iso 曲线的离散数据了。
同时,每个可选择对象有多种选择模式,例如对一个 shape 来说,可以选择其中的面、边、结点。因此会对应不同的选择数据。为此, SelectMgr_SelectableObject 类中保存了一个列表,记录一系列模式下的选择数据,以供不同模式下判断对象是否选中使用,模式和对应数据由 SelectMgr_Selection 类表示。其中记录了模型码,和模型对应的选择数据。这些选择数据通常是对象的三维曲线、曲面向内部视图平面的投影,得到的 polygon 数据,借此 polygon 数据和从视点发出的射线,就可以判断一个物体是否被选中了。
简单总结一下,每个显示对象有不同的显示模式,每种模式需要不同的显示数据。每个可选择对象有不同的选择模式,每种模式对应不同的选择数据。
AIS_interactiveObject 类继承自上述类,自然就具有了显示和选择功能。
视图管理类: viewer_viewer 类,
继承关系如下:
Viewer_Viewer
―― V3d_Viewer
―― V2d_Viewer
即可能是 2d 和 3d 下的 viewer 。我们重点关注 3d 下的 viewer 。
V3d_Viewer 类负责管理 3d 下视图相关属性,主要是管理一组 view 类, view 类的继承关系如下:
Viewer_View
―― V3d_View
―――― V3d_PerspectiveView
―――― V3d_OrthographicView
―― V2d_View
v3d_View 类是管理一个窗口的视图类。它与一个窗口关联,建立窗口和 OpenGL 的 HGLRC 间的关系,并实现窗口中的旋转、缩放等功能。该类内部封装了具体的实现类: Visual3d_View 类,这个类实现了大多数的功能,而 v3d_view 类作为 Visual3d_View 的补充,实现了部分功能。
V3d_View 类支持透视和平行投影。
为了支持旋转、缩放等操作,其内部包含了两个对象:
Visual3d_ViewMapping MyViewMapping;// NPC 坐标系 .
Visual3d_ViewOrientation MyViewOrientation;//VRC 坐标系
实现了两个坐标系的管理,类似 OpenGL 中 Projection 和 ModelView 两个变换的管理。这里采用的投影变换和模型变换采用的是 PHIGS 模式。底层的实现,也部分的使用了 OpenGL 的功能,例如:屏幕坐标和 3 维空间坐标的转换等。
通过 Context 对象、 Object 对象和 View 对象三者, OpenCascade 的显示模块使显示一个对象变的很简单了。在 doc/view 结构中,通常 doc 中声明一个 Context 对象, view 中记录一个 view 对象,该对象通常如下方式创建:
m_occView = GetDocument()->GetViewer()->CreateView();
这样,显示对象调用 Context 的 display 接口显示即可,而视图功能例如:旋转、缩放等功能,则调用 view 对象的功能可以快捷的实现,如:对象的选择功能,在鼠标消息 mousemove 的响应函数中调用 context 的 Moveto 函数,则实现了鼠标移过对象,对象是否选中的判断。如何要获取选择的对象,调用 context 的 select 函数就获得的已选择的对象。可以通过 intcurrent 和 selectedshape 等函数来获取选中的对象。
具体的实现,可以参考 OpenCascade 自带的例子。