<!-- /* Font Definitions */ @font-face {font-family:Wingdings; panose-1:5 0 0 0 0 0 0 0 0 0; mso-font-charset:2; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:0 268435456 0 0 -2147483648 0;} @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} a:link, span.MsoHyperlink {color:blue; text-decoration:underline; text-underline:single;} a:visited, span.MsoHyperlinkFollowed {color:purple; text-decoration:underline; text-underline:single;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:42.55pt; mso-footer-margin:49.6pt; mso-paper-source:0; layout-grid:15.6pt;} div.Section1 {page:Section1;} /* List Definitions */ @list l0 {mso-list-id:1262759992; mso-list-type:hybrid; mso-list-template-ids:233838752 67698689 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;} @list l0:level1 {mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:42.0pt; mso-level-number-position:left; margin-left:42.0pt; text-indent:-21.0pt; font-family:Wingdings;} @list l1 {mso-list-id:1317801007; mso-list-type:hybrid; mso-list-template-ids:950448730 67698701 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;} @list l1:level1 {mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:21.0pt; mso-level-number-position:left; margin-left:21.0pt; text-indent:-21.0pt; font-family:Wingdings;} @list l1:level2 {mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:42.0pt; mso-level-number-position:left; margin-left:42.0pt; text-indent:-21.0pt; font-family:Wingdings;} @list l2 {mso-list-id:1472291016; mso-list-type:hybrid; mso-list-template-ids:715554900 67698701 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;} @list l2:level1 {mso-level-number-format:bullet; mso-level-text:; mso-level-tab-stop:42.0pt; mso-level-number-position:left; margin-left:42.0pt; text-indent:-21.0pt; font-family:Wingdings;} @list l3 {mso-list-id:1565097105; mso-list-type:hybrid; mso-list-template-ids:151808690 -289405516 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;} @list l3:level1 {mso-level-number-format:alpha-lower; mso-level-text:%1、; mso-level-tab-stop:39.75pt; mso-level-number-position:left; margin-left:39.75pt; text-indent:-18.0pt;} ol {margin-bottom:0cm;} ul {margin-bottom:0cm;} -->
为了给外部提供方便的接口, Occt 在显示模块的最上层提供了 AIS(Application interactive services) 功能。 AIS 功能封装了显示模块内部的大多数功能,提供了对几何和拓朴对象的显示和选择和管理,功能包括:
显示对象,包括对象的显示颜色、显示模式等的管理
对象的选择功能,包括:根据鼠标事件和坐标数据,实现对象的选中判断,自动高亮显示、高亮显示等。
AIS 功能,使用了三部分来实现其功能,简单的说,用一个类代表可显示的对象,用一个类实现对对象显示和选择相关内容的管理,用一个视图类使对象在一个视图中显示,并允许被以多种方式显示。具体如下:
- 显示和选择的上下文管理类, AIS_interactiveContext
- 可显示的对象, AIS_interactiveObject
- 视图管理器。
可显示对象,是一个可以显示和选择的对象,通常包含一个几何或拓扑对象。这些几何或拓朴对象,通过 mesh 模块中的算法,生成对应的图形对象,以用于对象的绘制。
视图管理器允许交互操作显示对象的视图,例如:旋转视图、缩放视图等,方便在窗口中观察显示的对象。
显示和选择的上下文管理对象,负责显示对象的管理,提供显示对象、选择对象等功能,使对象的显示和选择编程实现很简单。
具体来看每个类。
AIS_interactiveContext 类
主要功能是对一组可显示和选择的对象的管理功能,包括:显示对象、对象选择、对象高亮显示、对象颜色等等。
其内部
- 包含了一个 map ,将可显示对象和其状态保存下来,并实现添加和删除对象功能。
- 包含了一个显示管理器,负责对象的显示。
- 包含了一个选择管理器,负责对象的选择功能。
- 包含了一个视图管理器,管理对象所在试图的显示功能。
该类提供了丰富的接口,功能很强大,是 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 自带的例子。