链接: https://dev.opencascade.org/doc/overview/html/occt_user_guides__visualization.html


1 Introduction

OCCT 中的可视化模块建立在下面的概念分离上:

  • 一方面是: 用来存储你想要渲染以及交互的几何和拓扑数据;
  • 另一方面是:上述对象的表示对象(presentation)和选择对象(selection

表示对象由 Presentation 模块来管理,而选择对象则由 Selection 模块来管理;

Applicaiton Interactive Service (AIS) 正在提供应用 GUI 和这些组建之间的交互,使得这个过程能够更加直观和透明。AIS 模块使用 Interactive Object,即可交互对象来表示一个可显示,可选择实体。除非你需要进行深度定制,否则你一般不需要触及底层的表示与选择组件的对应对象;

如果你真的要进行深度定制, 你需要知道可表示对象和可选择对象的实现原理,具体而言,你需要知道应该实现那些虚函数。首先你需要了解一些更为基础的概念,包括 Sensitive Primitive 以及 Presentable Object。

以下这些包都参与了三维物体的渲染:

  • AIS
  • StdPrs
  • Prs3d
  • PrsMgr
  • V3d
  • Graphic3d

以上这些模块也适用于二维物体的渲染。

下面这张图显示了 Visualization 模块的一些重要的概念和组建之间的关系。“几何与拓扑”数据只是 AIS 可以处理的应用数据的一个例子,你可以根据实际应用的需要基于其他形式的数据来支持可视化。

2 基础概念

2.1 表示 · Presentation

表示模块的一个基础概念是,表示数据与他背后的几何拓扑数据是解耦的,这使得你可以在不改变一个图形的呈现形式的前提下修改图形数据。

2.1.1 表示的结构

要讲一个对象展示到屏幕上需要三类不同的对象的参与:

  • 可表示对象,一般是 AIS_InteractiveObject
  • Viewer
  • 可交互上下文,即 AIS_InteractiveContext

接下来我们一一阐述。

2.1.2 可表示对象

可表示对象的主要目标是一 Graphic3d_Structure 的形式来提供一个对象的图形化表示数据。在初次展示请求时,可表示对象会调用合适的算法来创建这些结构数据。

StdPrsPrs3d 报提供了标注的可视化算法。你也可以创建自己的算法实现,来创建对应的表示结构数据(来自 Graphic3d 包)。你也可以为单个可表示对象创建多个表示结构数据,每个对应一种显示模式。

每个需要被展示的对象都要是 presenable 的,或者是与一个可展示对象关联。

2.1.3 The Viewer

Viewer 允许以交互式的方式来操作对象。当你缩放、平移或者旋转视角时 Viewer 会操作可表示对象创建的 Graphic 结构数据,而不是直接操作应用的数据层对象。创建 Graphic3d 包中的定义的结构数据对象可以使得你能够直接应用 Viewer 提供的变换机制。

2.1.4 可交互上下文

可交互上下文为整个渲染过程提供了一些通用的高层 API。 当应用需要显示某个对象时,上下文会请求这一对象的表示数据结构,并发往 Viewer 进行渲染。

2.1.5 Presentation 相关包

Presentation 至少涉及到 AIS, PrsMgr, StdPrs 以及 V3d 等子包。如果你需要实现自己的渲染算法,你可能还需要涉及到 Prs3d 和 Graphic3d 这两个包;

  • 标准可交互对象
    • AIS 包提供了一些具体的自烈性来实现 Interactive 对象( presentable and selectable entities);
    • PrsDim 提供了绘制标注和关系的可表示对象;
    • MeshVS 包提供了表示曲面的数据;
  • 标准表示构造器(Presentation Builders)
    • Prs3d 包提供了即开即用的标准表示算法,可以用来处理一些简单的几何体,包括箭头,圆柱,球体等。它还丁你要了 Prs3d_Drawer 来来控制表示对象的属性,包括颜色,线型,厚度等;
    • StdPrs 包提供了对 B-rep 对象的即开即用的表示算法试下。这些表示算法包括 Shading、Wireframe、isolines 以及 hidden line removal 等;
    • DsgPrs 提供了用来展示标注、关系以及 XYZ 坐标盒(trihendrons)的工具;
  • 选择服务(Selection Service)
    • Select3D,SelectBasics 以及 SelectMgr 实现了选择服务;
    • StdSelect 包提供了 B-rep 形状的选择构造器;
  • Viewoer 管理由 V3d 包来负责;
  • 底层接口
    • PrsMgr 包定义了一些可展示对象的基础接口和工具,它包含了实现展示过程所需要的所有类:抽象基类 PrsMgr_PresentationPrsMgr_PresentableObject 以及 concrete 类 PrsMgr_PresentationManager
    • Graphic3d 包提供了底层的图形结构数据定义。这个包还提供了 Graphic3d_GraphicDriver,用于同底层图形 API(如 OpenGL)的沟通;

2.1.6 基本示例:如何显示一个 3D 对象

1
2
3
4
5
6
7
Handle(V3d_Viewer) theViewer;
Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (theViewer);

BRepPrimAPI_MakeWedge aWedgeMaker (theWedgeDX, theWedgeDY, theWedgeDZ, theWedgeLtx);
TopoDS_Solid aShape = aWedgeMaker.Solid();
Handle(AIS_Shape) aShapePrs = new AIS_Shape (aShape); // creation of the presentable object
aContext->Display (aShapePrs, AIS_Shaded, 0, true); // display the presentable object and redraw 3d viewer

我们通过 BRepPrimAPI_MakeWedge 工具类来创建了一个几何形状,然后调用 Display 进行展示,在 SDK 的内部,交互上下文会调用可表示对象(即 AIS_Shape) 的 Compute 方法来计算出渲染数据,并将数据转交给 Viewer。这个流程如下:

2.2 选择 · Selection

标准的 OCCT 选择算法由两个部分组成:静态和动态。动态选择会导致数据在经过对应的对象上方时被高亮,而静态的选择会让对象可以被选中,从而参与后续的过程。

选择分为三种类型:

  • 点选择 - 在鼠标的位置下进行选择;
  • 矩形选择 - 在一个起点和一个终点表示一个矩形的区域内进行选择;
  • 多段线选择 - 允许在用户定义的一段非自交的多段线区域内进行选择。

在 OCCT 的选择算法中,所有的可选择对象都由一些列的敏感区域(Sensitive Zones)表示,也被称为 Sensitive entities。当鼠标移动时,这些敏感区域会被分析用作碰撞检测。

2.2.1 术语与标记

这个部分介绍一些在后续的算法描述中涉及的基本的术语和标记。

2.2.2 Sensitive Entitiy

敏感实体与实体所有者一样,是对象与选择机制之间的链接。

实体的目的是特别定义对象的哪些部分将可被选择。因此,任何意图可被选择的对象都必须被拆分成敏感实体(一个或多个)。例如,要对一个对象应用面选择,就必须将其拆分成面,并使用这些面来创建一个敏感实体集。

根据用户的不同需要,敏感实体可以是原子化的(点或者线条),也可以是复杂的。敏感实体被用作选择算法的内部单元,并且其不包含任何拓扑信息,他们连接到上层接口来获取这些拓扑信息。

2.2.3 实体所有者

每个敏感实体 Select3D_SensitiveEntity 存储了一个指向其所有者 SelectMgr_EntityOwner 的引用,这个类将一个实体和对应的可选择对象(SelectMgr_SelectableObject)关联起来。另外,拥有者可以存储一些额外的信息。例如,敏感实体的图谱形状,高亮颜色,选中状态等。

2.2.4 选择集合

为了简化不同的选择模式的处理,敏感实体被组成集合,即 SelectMgr_Selection,每个选择集合包含了某个特定的选择模式下的敏感实体内容以及对应的设置与状态。

2.2.5 可选择对象

可选择对象(SelectMgr_SelectableObject, AIS_InteractiveObject)存储所有创建出来的选择集合和敏感实体的信息。

所有可选择对象的子类都需要实现预先定义的接口以将表示数据根据选择模式拆解成敏感实体。这些计算出来的敏感实体被组成成一个选择集合,并加入到此可选择对象的选择集合列表中。仅有可选择对象被永久销毁时,这些选择集合相关的数据才会被删除。

对于标准的 OCCT 可交互对象,选择模式 0 表示选中整个对象(这些行为可以在子类实现中被修改)。例如 AIS_Shape 对象定义下面的选择模式(见 AIS_Shape::SelectionMode()

  • 0 - 选择整个对象 (AIS_Shape)
  • 1 - 选择顶点 (TopAbs_VERTEX)
  • 2 - 选择边 (TopAbs_EDGE)
  • 3 - 选择环 (TopAbs_WIRE)
  • 4 - 选择面 (TopAbs_FACE)
  • 5 - 选择壳 (TopAbs_SHELL)
  • 6 - 选择实心体 (TopAbs_SOLID)

2.2.6 Viewer 选择器

对于每个 OCCT Viewer 都有一个 Viewer 选择器类 SelectMgr_ViewerSelector3d,它提供了整个选择算法模块的一些高阶 AI,并为每次鼠标点击封装了对象以及敏感实体的处理过程。选择器维护了选择模式的激活状态,启动算法,并且探测将要被拾取的对象,存储结果,并实现了接口来保证选择结构的及时更新。

2.2.7 选择管理器

选择管理器 SelectMgr_SelectionManager 是一个操作所有展示对象的选择集合的高阶 API 提供者。它负责处理所有 Viewer 的选择器,负责对象的选择模式的激活,负责维护每个对象的选择集合的计算。最终奥的任务是保证选择数据的及时更新。

2.2.8 算法

OCCT 的所有三种选择类型都作为一个单一概念实现,基于通过三级 BVH 树遍历搜索视锥与敏感实体之间的重叠。

2.2.9 选择视锥

选择算法每次运行的第一步都是根据当前的选择类型来构建选择视锥。

对于点选或矩形选取,视锥的底面是一个矩形,根据像素容差或用户定义区域的尺寸分别构建。对于多段线选择,由构建线条定义的多边形被三角剖分,每个三角形作为其自己的视锥的底面。因此,这种类型的选择使用一组三角形视锥来进行重叠检测。

视锥的长度由近视和远视视觉体积平面限制,并且每个平面都平行于相应的视觉体积平面建造。

2.2.10 BVH 树

为了在 Viewer 的层级维持选择机制,我们构建了一个 3 层 BVH 树。

第一级树由每个可选择对象的轴对齐边界框构成。因此,这棵树的根包含了所有可选择边界的组合,即使它们当前没有激活的选择。对象在显示AIS_InteractiveObject时被添加,并且只有当对象被销毁时才会从这棵树中移除。第 1 级 BVH 树是在选择算法首次运行时按需构建的。

第二级 BVH 树包含一个可选择对象的所有敏感实体。当默认模式被激活时,第 2 级树会自动构建,并且每当首次为新的选择模式计算时,就会重新构建。

第三级 BVH 树用于包含许多元素的复杂敏感实体,例如:三角剖分、带有许多段的线、点集等。它是按需为拥有超过 800K 子元素的敏感实体构建的(由StdSelect_BRepSelectionTool::PreBuildBVH()定义)。

2.2.11 算法的各个阶段

选择算法包含预处理阶段和三个主要阶段

2.2.11.1 预处理阶段

包含计算选择视锥及其主要特征数据;

2.2.11.2 第一阶段 - 遍历第一层 BVH 树

在成功构建选择视锥之后,算法开始遍历对象级 BVH 树。包含轴对齐边界框的节点按照分离轴定理(SAT)的条件测试与选择视锥的重叠。当遍历进行到叶节点时,意味着找到了一个可能包含重叠敏感实体的候选对象。如果没有检测到这样的对象,算法停止,假设没有对象需要被选择。否则,它进入下一个阶段处理找到的可选择对象的实体。

关于轴分离定理:

SAT 代表“分离轴定理”(Separating Axis Theorem),这是计算机图形学和物理引擎中用于检测两个凸多边形之间是否存在重叠(即碰撞检测)的一个重要方法。根据这个定理,如果能找到一个轴(分离轴),使得将两个多边形在这个轴上的投影完全分开,那么这两个多边形就不相交;反之,如果对于所有可能的分离轴,两个多边形的投影都重叠,则两个多边形相交。这个定理简化了复杂形状之间碰撞检测的计算,使得它成为实现高效碰撞检测算法的关键。

2.2.11.3 第二阶段 - 遍历第二层 BVH 树

在这个阶段,需要确定在一个对象的所有敏感实体中是否有候选者。

首先,在这个阶段,算法会检查当前对象是否应用了任何变换。如果它有自己的位置,那么相应变换后的视锥将被用于进一步的计算。在下一步,访问给定对象的第二级 BVH 树的节点,以搜索重叠的叶子。如果没有找到这样的叶子,算法返回到上一个阶段。否则,它开始通过执行以下检查来处理找到的实体:

激活检查 - 实体此刻可能是不活跃的,因为它属于被停用的选择; 容差检查 - 当前的选择视锥对于进一步的检查可能太大,因为它总是以所有激活实体中的最大容差构建的;因此,在这一步,视锥可能会被缩放。

经过这些检查后,算法进入最后阶段。

2.2.11.4 第三阶段 - 特定敏感实体的重叠和包含检测

如果实体是原子的,将执行一个简单的 SAT 测试。在复杂实体的情况下,将遍历第三级 BVH 树。分析匹配的敏感实体的定量特征(如深度、到几何中心的距离),并应用裁剪平面(如果已设置)。检测结果被存储,算法返回到第一主要阶段。

2.2.12 Packages and Classes

选择机制的实现涉及到多个包 - SelectBasics, Select3D, SelectMgr, StdSelect

2.2.12.1 SelectBasics

这个包定义了一些非常基础的类型和接口,其中值得一提的是

  • SelectBasics_PickResult:存储探测过程的量化结果,例如深度以及距离几何中心的距离;
  • SelectBasics_SelectingVolumeManager: 与当前选择视锥的接口和交互方式。

每个自定义选择实体都必须至少继承 SelectBasics_SensitiveEntity

2.2.12.2 Select3D

Select3D 包包括了一系列标准的选择实体的定义,例如

  • box
  • circle
  • curve
  • face
  • group
  • point
  • segment
  • triangle
  • triangulation
  • wire

这些基础的选择实体都继承了 Select3D_SensitiveEntity。这包还引入了两个辅助类 Select3D_SensitivePoly 以及Select3D_SensitiveSet,其中后者是需要第三级 BVH 树的复杂选择实体的基类,前者则描述了任意点集并实现了基础的选择函数(注意,Select3D_SensitivePoly 类的内部并不会进行数据检查,因此,如果你需要自行派生加入自定义实现,你需要满足 SAT 理论以便使用标准的 OCCT 重叠检测方法)。

2.2.12.3 SelectMgr

这个包含用来维护整个选择过程,基于这个目的,此包提供了以下服务:

  • 激活或者取消激活所有可选择对象的选择模式;
  • 为对象计算选择数据的接口;
  • 定义了选择过滤器的类;
  • 确保 BVH 树的数据为最新;

一下是对主要类的简要描述:

  • SelectMgr_BaseFrustum, SelectMgr_Frustum, SelectMgr_RectangularFrustum, SelectMgr_TriangularFrustum and SelectMgr_TriangularFrustumSet - 这些类和皆苦与选择视锥有关,他们定义了不同的 SAT 测试方法,同时也包含了计算定量特质数值的方法(例如计算深度和距离)
  • SelectMgr_SensitiveEntity, SelectMgr_Selection and SelectMgr_SensitiveEntitySet - 存储和处理敏感实体的数据,SelectMgr_SensitiveEntitySet 实现了第二级 BVH 树的元素集合;
  • SelectMgr_SelectableObject and SelectMgr_SelectableObjectSet - 描述了可选择对象。它们也负责存储,计算和移除选择数据。SelectMgr_SelectableObjectSet 提供了第一级 BVH 树的实现;
  • SelectMgr_SelectionManager - 管理所有可选择对虾干的激活状态,选择数据计算以及 BVH 的更新。

2.2.12.4 StdSelect

这个包包含了一些 SelectMgr 的类和工具来创建选择数据结构,例如

  • StdSelect_BRepOwner - 定义了一个敏感实体的拥有者,它连接到拓扑形状以及高亮方法;
  • StdSelect_BRepSelectionTool - 包含了一些算法实现来将标准 AIS 形状分割成敏感组元;
  • StdSelect_FaceFilter, StdSelect_EdgeFilter - 实现选择过滤器;

2.2.13 样例

第一个代码片段展示了在自定义交互对象中实现 SelectMgr_SelectableObject::ComputeSelection() 方法的例子。该方法用于计算用户定义的选择模式。假设需要使一个盒子在两种模式下可选择——整个形状(模式 0)和每个边缘(模式 1)。为了选择整个盒子,应用程序可以为交互对象的每个面创建一个敏感组元。在这种情况下,所有组元共享同一个所有者——盒子本身。为了选择盒子的边缘,应用程序必须为每个边缘创建一个敏感组元。这里所有敏感实体不能共享所有者,因为不同的几何组元必须作为选择程序的结果被高亮显示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void InteractiveBox::ComputeSelection (const Handle(SelectMgr_Selection)& theSel,
const Standard_Integer theMode)
{
switch (theMode)
{
case 0: // creation of face sensitives for selection of the whole box
{
Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this, 5);
for (Standard_Integer aFaceIter = 1; aFaceIter <= myNbFaces; ++aFaceIter)
{
Select3D_TypeOfSensitivity aSensType = myIsInterior;
theSel->Add (new Select3D_SensitiveFace (anOwner, myFaces[aFaceIter]->PointArray(), aSensType));
}
break;
}
case 1: // creation of edge sensitives for selection of box edges only
{
for (Standard_Integer anEdgeIter = 1; anEdgeIter <= 12; ++anEdgeIter)
{
// 1 owner per edge, where 6 is a priority of the sensitive
Handle(MySelection_EdgeOwner) anOwner = new MySelection_EdgeOwner (this, anEdgeIter, 6);
theSel->Add (new Select3D_SensitiveSegment (anOwner, myFirstPnt[anEdgeIter]), myLastPnt[anEdgeIter]));
}
break;
}
}
}

创建选择结构的算法将敏感组元存储在SelectMgr_Selection实例中。对象的选择列表中的每个SelectMgr_Selection序列必须对应于特定的选择模式。为了描述对象分解为可选择组元的过程,Select3D包中提供了一套现成的敏感实体。可以通过从Select3D_SensitiveEntity继承来定义自定义敏感组元。为了使自定义交互对象可选择或自定义现有对象的选择模式,必须定义实体所有者。它们必须继承SelectMgr_EntityOwner接口。

任何交互对象的选择结构都在SelectMgr_SelectableObject::ComputeSelection()方法中创建。下面的示例展示了如何使用标准 OCCT 机制,实现在StdSelect_BRepSelectionTool中,来计算拓扑形状的不同选择模式。

1
2
3
4
5
6
7
8
9
10
11
12
void MyInteractiveObject::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
const Standard_Integer theMode)
{
switch (theMode)
{
case 0: StdSelect_BRepSelectionTool::Load (theSelection, this, myShape, TopAbs_SHAPE); break;
case 1: StdSelect_BRepSelectionTool::Load (theSelection, this, myShape, TopAbs_VERTEX); break;
case 2: StdSelect_BRepSelectionTool::Load (theSelection, this, myShape, TopAbs_EDGE); break;
case 3: StdSelect_BRepSelectionTool::Load (theSelection, this, myShape, TopAbs_WIRE); break;
case 4: StdSelect_BRepSelectionTool::Load (theSelection, this, myShape, TopAbs_FACE); break;
}
}

StdSelect_BRepSelectionTool类为计算给定类型(例如,面、顶点、边、线等)的敏感实体提供了一个高级 API,使用来自给定TopoDS_Shape的拓扑数据。

Open CASCADE Technology 采用的传统方式是每个实体所有者自行高亮显示自己。这种方法有两个缺点:

  • 每个实体所有者必须维护自己的Graphic3d_Structure对象,这会导致相当大的内存开销;
  • 逐个绘制选定的所有者在视觉效果上并不高效。

因此,为了克服这些限制,OCCT 提供了一种替代方式来实现选定表示的高亮显示。采用这种方法,交互对象本身将负责高亮显示,而不是实体所有者。

基于SelectMgr_EntityOwner::IsAutoHilight()返回值,AIS_InteractiveContext对象要么使用传统的高亮显示方式(如果IsAutoHilight() 返回 TRUE),要么根据它们的可选择对象将这些所有者分组,最终调用SelectMgr_SelectableObject::HilightSelected()SelectMgr_SelectableObject::ClearSelected(),并传递所有者组作为参数。

因此,应用程序可以派生自己的交互对象并重新定义来自SelectMgr_SelectableObject的虚拟方法HilightSelected()ClearSelected()HilightOwnerWithColor()SelectMgr_SelectableObject::GetHilightPresentationSelectMgr_SelectableObject::GetSelectPresentation方法可以用来根据用户的需求优化填充选择和高亮表示。

在通过重定义SelectMgr_SelectableObject::ComputeSelection()方法计算并打包了所有必要的敏感实体以及相应的所有者到SelectMgr_Selection实例后,需要通过以下步骤在SelectMgr_SelectionManager中注册准备好的选择数据:

  • 如果没有打开AIS_InteractiveContext,创建一个交互上下文并在其中显示可选择对象;
  • 使用AIS_InteractiveContext::Load()方法将可选择对象加载到交互上下文的选择管理器中。如果传递给此方法的选择模式不等于-1,则将调用此选择模式的ComputeSelection()
  • 使用AIS_InteractiveContext::Activate()AIS_InteractiveContext::Deactivate()方法激活或停用定义的选择模式。

完成这些步骤后,创建的交互上下文的选择管理器将包含给定的对象及其选择实体,它们将参与检测程序。

下面的代码片段展示了上面的步骤,其中还包含了开启选择过程并解析选择结果的流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Suppose there is an instance of class InteractiveBox from the previous sample.
// It contains an implementation of method InteractiveBox::ComputeSelection() for selection
// modes 0 (whole box must be selected) and 1 (edge of the box must be selectable)
Handle(InteractiveBox) theBox;
Handle(AIS_InteractiveContext) theContext;
// To prevent automatic activation of the default selection mode
theContext->SetAutoActivateSelection (false);
theContext->Display (theBox, false);

// Load a box to the selection manager without computation of any selection mode
theContext->Load (theBox, -1, true);
// Activate edge selection
theContext->Activate (theBox, 1);

// Run the detection mechanism for activated entities in the current mouse coordinates and in the current view.
// Detected owners will be highlighted with context highlight color
theContext->MoveTo (aXMousePos, aYMousePos, myView, false);
// Select the detected owners
theContext->Select();
// Iterate through the selected owners
for (theContext->InitSelected(); theContext->MoreSelected() && !aHasSelected; theContext->NextSelected())
{
Handle(AIS_InteractiveObject) anIO = theContext->SelectedInteractive();
}

// deactivate all selection modes for aBox1
theContext->Deactivate (aBox1);

另外需要提及的一个重点是,OCCT 的矩形选择支持两种探测模式:

  • 包含(Inclusive):只有目标完全包含在选择视锥内部时才会被认为是被选中的;
  • 覆盖(Overlap):只要目标与选择视锥存在交集就认为选中。

默认情况下 OCCT 会使用第一种,要修改这个默认行为,可以使用下面的方法:

1
2
3
4
5
6
// Assume there is a created interactive context
const Handle(AIS_InteractiveContext) theContext;
// Retrieve the current viewer selector
const Handle(StdSelect_ViewerSelector3d)& aMainSelector = theContext->MainSelector();
// Set the flag to allow overlap detection
aMainSelector->AllowOverlapDetection (true);

3 Applicaiton Interactive Service

3.1 介绍

应用交互服务允许以简单和透明的方式管理查看器中的表示和动态选择。管理可视化和选择的核心实体是交互上下文(AIS_InteractiveContext)。它连接到主查看器(V3d_Viewer)。

交互上下文默认在中立点启动,每个可选择对象作为一个整体被选中,但用户可以为特定对象激活局部选择,以使对象的部分可选择。局部/全局选择由为每个显示对象激活的选择模式列表管理,其中 0(默认选择模式)通常意味着全局(整个对象)选择。

交互对象(AIS_InteractiveObject)是被可视化和选择的实体。你可以使用标准交互对象的类,所有必要的功能已经被编程,或者你可以通过遵循下面描述的一定数量的规则和约定,实现你自己的交互对象类。

交互对象是一个“虚拟”实体,可以被呈现和选择。交互对象可以具有一定数量的特定图形属性,如可视化模式、颜色和材料。当交互对象被可视化时,所需的图形属性从它自己的绘制器(Prs3d_Drawer)中获取,如果它具有所需的自定义属性,否则从上下文绘制器中获取。

可能需要过滤要选择的实体。因此,有过滤器实体(SelectMgr_Filter),它们允许精细化动态检测上下文。这些过滤器中的一些只能在中立点使用,其他的只能在局部选择中使用。可以编程自定义过滤器并将它们加载到交互上下文中。

3.2 可交互对象

在 AIS 查看器中被可视化和选择的实体是对象(AIS_InteractiveObject)。它们将模型的底层参考几何连接到其在 AIS 中的图形表示。你可以使用预定义的 OCCT 标准交互对象类,所有必要的功能已经被编程,或者,如果你是高级用户,你可以实现你自己的交互对象类。

3.2.1 表示 · Presentation

一个交互对象可以有任意多个表示。三维表示数据由表示管理器(PrsMgr_PresentationManager)来管理;

表示数据由一个索引(显示模式)和对表示管理器的引用来表示。默认情况下,交互对象的默认表示索引是 0.

交互对象的表示数据计算由继承自 PrsMgr_PresentableObject::Compute 函数来进行。这个函数由表示管理器在显示或者更新的时候调用。

如果你要创建自己的交互对象,你需要以下面的方式来实现 Compute 函数。

3.2.1.1 For 3D

1
2
3
void PackageName_ClassName::Compute (const Handle(PrsMgr_PresentationManager)& thePresentationManager,
const Handle(Prs3d_Presentation)& thePresentation,
const Standard_Integer theMode);

3.2.1.2 For HLR Mode in 3D

1
2
void PackageName_ClassName::Compute (const Handle(Prs3d_Projector)& theProjector,
const Handle(Prs3d_Presentation)& thePresentation);

视图可以有两种状态:正常模式或计算模式(隐藏线删除模式)。当后者被激活时,视图会查找在正常模式下显示的所有表示,这些表示已被标记为接受 HLR 模式。一个内部机制允许调用交互对象自己的 Compute,即投影器(projector)函数。

按照惯例,交互对象接受或拒绝 HLR 模式的表示。可以通过以下两种方式之一进行此声明:

  • 最初通过使用枚举PrsMgr_TypeOfPresentation3d的值之一:
    • PrsMgr_TOP_AllView
    • PrsMgr_TOP_ProjectorDependent
  • 随后通过使用函数PrsMgr_PresentableObject::SetTypeOfPresentation

AIS_Shape类是支持 HLR 表示的交互对象的一个例子。HLR 算法的类型存储在形状的Prs3d_Drawer中。它是Prs3d_TypeOfHLR枚举的一个值,可以设置为:

  • Prs3d_TOH_PolyAlgo,用于基于形状三角化的多边形算法;
  • Prs3d_TOH_Algo,用于与形状的真实几何工作的精确算法;
  • Prs3d_TOH_NotSet,如果没有为给定的交互对象实例设置算法类型。

用于AIS_Shape的 HLR 算法类型可以通过调用AIS_Shape::SetTypeOfHLR()方法来更改。当前HLR算法类型可以使用AIS_Shape::TypeOfHLR()方法获得。

这些方法从AIS_Shape的绘制器中获取值。如果在Prs3d_Drawer中设置的HLR算法类型为Prs3d_TOH_NotSet,则Prs3d_Drawer会从AIS_InteractiveContext的默认绘制器中获取值。因此,可以更改所有新显示的交互对象所使用的默认HLR算法。存储在上下文绘制器中的HLR算法类型的值可以是Prs3d_TOH_AlgoPrs3d_TOH_PolyAlgo。多边形算法是默认算法。

3.2.2 表示模式

AIS 中的交互对象有四种类型:

  • the "construction element" or Datum,
  • the Relation (dimensions and constraints)
  • the Object
  • the None type (when the object is of an unknown type).

在每个类别内部还可以使用一个签名(索引形式)来提供更多的特征信息。默认情况下,交互对象具有 NONE类型,和 0 值签名,如果你需要更改这些属性,你需要重新盯一下下面两个虚函数:

  • AIS_InteractiveObject::Type
  • AIS_InteractiveObject::Signature

注意:某些签名值已经被 AIS 内部的标准交互类使用。

交互上下文可以为一组交互对象设定一个默认的表示模式。这个模式可能不被某个给定的对象类接受。因此,要获取关于这个类的信息,需要使用虚拟函数AIS_InteractiveObject::AcceptDisplayMode

3.2.3 显示模式

函数AIS_InteractiveContext::SetDisplayModeAIS_InteractiveContext::UnsetDisplayMode允许为对象设置一个自定义的显示模式,这可以与交互上下文提议的模式不同。

3.2.4 高亮模式

在动态检测中,交互上下文回显的表示默认是已经在屏幕上的表示。

函数AIS_InteractiveObject::SetHilightModeAIS_InteractiveObject::UnsetHilightMode允许指定用于高亮显示的显示模式(所谓的高亮模式),这个模式与对象的活动表示独立有效。无论这个选择是临时的还是最终的都没有关系。

注意,用于高亮检测到的对象和用于高亮选中的对象的是相同的表示(因此是相同的高亮模式),后者用特殊的选择颜色绘制(参考与交互上下文服务相关的部分)。

例如,你想要系统地高亮显示一个形状的线框表示——不管它是在线框表示中可视化还是以阴影方式。因此,你在交互对象的构造器中将高亮模式设置为 0。不要忘记在 Compute 函数中实现这种表示模式。

3.2.5 无限状态(Infinite Status)

如果你不希望一个对象受到全视图(FitAll)的影响,你必须声明它为无限的;你可以使用AIS_InteractiveObject::SetInfiniteStateAIS_InteractiveObject::IsInfinite函数取消其“无限”的状态。

以一个代表交互对象的类 IShape 为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
myPk_IShape::myPk_IShape (const TopoDS_Shape& theShape, PrsMgr_TypeOfPresentation theType)
: AIS_InteractiveObject (theType), myShape (theShape) { SetHilightMode (0); }

Standard_Boolean myPk_IShape::AcceptDisplayMode (const Standard_Integer theMode) const
{
return theMode == 0 || theMode == 1;
}

void myPk_IShape::Compute (const Handle(PrsMgr_PresentationManager)& thePrsMgr,
const Handle(Prs3d_Presentation)& thePrs,
const Standard_Integer theMode)
{
switch (theMode)
{
// algo for calculation of wireframe presentation
case 0: StdPrs_WFDeflectionShape::Add (thePrs, myShape, myDrawer); return;
// algo for calculation of shading presentation
case 1: StdPrs_ShadedShape::Add (thePrs, myShape, myDrawer); return;
}
}

void myPk_IShape::Compute (const Handle(Prs3d_Projector)& theProjector,
const Handle(Prs3d_Presentation)& thePrs)
{
// Hidden line mode calculation algorithm
StdPrs_HLRPolyShape::Add (thePrs, myShape, myDrawer, theProjector);
}

3.2.6 选择

一个交互对象可以有无限数量的选择模式,每个模式代表一种敏感原语的“分解”。每个原语都有一个所有者(SelectMgr_EntityOwner),它允许识别已检测到的确切交互对象或形状(见选择章节)。

对应于给定模式的敏感原语集合存储在一个选择(SelectMgr_Selection)中。

每种选择模式由一个索引标识。按照惯例,允许我们完整把握交互对象的默认选择模式是模式0。然而,可以在自定义交互对象中使用方法SelectMgr_SelectableObject::setGlobalSelMode()进行修改。

选择原语(或敏感实体)的计算在一个虚拟函数ComputeSelection中完成。对于假定具有不同选择模式的每种类型的交互对象,都应实现该函数AIS_InteractiveObject::ComputeSelection。在选择章节中已给出了关于此机制和实现此函数方式的详细说明。

有一些最广泛使用的交互对象在 OCCT 中的选择模式计算示例——AIS_Shape(按顶点、按边缘等选择)。要创建具有与AIS_Shape相同选择行为的新交互对象类——如顶点和边缘——你必须重新定义虚拟函数AIS_InteractiveObject::AcceptShapeDecomposition

3.2.7 图形属性

图形属性管理器,或者说 Prs3d_Drawer,存储特定交互对象的图形属性以及由交互上下文控制的交互对象的图形属性。

在初始条件下,所有 Drawer 属性都填充了预定义的值,这些值将定义默认的 3D 对象外观。当交互对象被可视化时,所需的图形属性首先从其自有的 Drawer 中取得(如果存在的话),或者如果没有该类型对象的特定 Drawer,则从上下文 Drawer 中取得。

关于图形属性,需记住以下几点:

  • 每个交互对象可以拥有自己的可视化属性。
  • 默认情况下,交互对象取其所在上下文的图形属性(可视化模式、用于计算表示的偏差值、等参数线数量、颜色、线型、材料等)。
  • AIS_InteractiveObject 抽象类中,包括颜色、线条粗细、材质和透明度在内的标准属性被特别优先考虑。因此,有一定数量的虚拟函数,允许对这些属性进行操作。每个新的交互对象类可以重新定义这些函数并改变类的行为。
Redefinition of virtual functions for changes in AIS_Shape and AIS_TextLabel.

以下虚拟函数提供了颜色、宽度、材料和透明度的设置:

  • AIS_InteractiveObject::UnsetColor
  • AIS_InteractiveObject::SetWidth
  • AIS_InteractiveObject::UnsetWidth
  • AIS_InteractiveObject::SetMaterial
  • AIS_InteractiveObject::UnsetMaterial
  • AIS_InteractiveObject::SetTransparency
  • AIS_InteractiveObject::UnsetTransparency

这些方法可以作为一种通用方式分配属性的快捷方式,但结果可能不可用。一些交互对象可能根本不实现这些方法,或者只实现它们的一个子集。直接修改由AIS_InteractiveObject::Attributes返回的Prs3d_Drawer属性,可以用于更精确和可预测的配置。

重要的是要知道哪些函数可能意味着对象的表示需要重新计算。如果要更新交互对象的表示模式,PrsMgr_PresentableObject指示这一点的一个标志。可以使用AIS_InteractiveContext中的DisplayRedisplay函数更新模式。

3.2.8 Complementary Services

注意以下问题

3.2.8.1 改变交互对象的位置

下面的这些函数允许移动一个表示对象的位置而不需要重新计算表示数据或者修原始的形状数据:

  • AIS_InteractiveContext::SetLocation
  • AIS_InteractiveContext::ResetLocation
  • AIS_InteractiveContext::HasLocation
  • AIS_InteractiveContext::Location

3.2.8.2 关联到应用对象

每个交互对象都允许通过 GetOwner 方法来获取 Transient 形式的数据;

  • AIS_InteractiveObject::SetOwner
  • AIS_InteractiveObject::HasOwner
  • AIS_InteractiveObject::GetOwner

这种数据关联不会影响交互对象本身的行为。

3.2.8.3 解决拓扑精度问题(coincident topology)

由于三维图形坐标的精确度具有有限的分辨率,拓扑对象的元素可以重合,产生“弹出”某些元素覆盖另一些元素的效果。

对于两个或多个交互对象的元素重合的问题,你可以应用多边形偏移。这是一种图形计算偏移,或深度缓冲区偏移,允许你通过修改它们的深度值来排列元素,而不改变它们的坐标。接受这种偏移的图形元素是实心多边形或作为边界线和点显示的多边形。通过设置适当的内部样式,可以将多边形显示为线条或点。

方法AIS_InteractiveObject::SetPolygonOffsetsAIS_InteractiveContext::SetPolygonOffsets允许设置多边形偏移。

3.2.8.4 对象树

每个PrsMgr_PresentableObject都有一个称为 myChildren 的对象列表。对PrsMgr_PresentableObject的任何变换也会应用到其子对象上。这种层次结构不会传播到Graphic3d级别及以下。

PrsMgr_PresentableObject将其结合的(根据层次结构)变换下传到Graphic3d_Structure。结构的材质不受层次结构的影响。

对象层次结构可以通过以下 API 调用来控制:

  • PrsMgr_PresentableObject::AddChild;
  • PrsMgr_PresentableObject::RemoveChild

3.2.8.5 实例化

实例化的概念按如下方式操作对象层次结构:

  • 实例由分离的AIS对象表示。
  • 实例不计算任何表示。
  • AIS_ConnectedInteractiveAIS_MultipleConnectedInteractive 用于实现这一概念。

AIS_ConnectedInteractive 是一个对象实例,它重用连接对象的几何体,但拥有自己的变换和可见性标志。这种连接传递到 OpenGl 级别,即到 OpenGl_StructureOpenGl_Structure 只能连接到单个其他结构。

AIS_ConnectedInteractive 通常可以引用任何 AIS_InteractiveObject。当它引用另一个 AIS_ConnectedInteractive 时,它只是复制引用。

AIS_MultipleConnectedInteractive 表示一个不具有自己的表示的装配体。装配体能够参与对象层次结构,并旨在处理一组分组的实例化对象。就选择而言,它表现为单一对象。因为它位于层次结构中的较高位置,它对所有子元素应用高级变换。

所有 AIS_MultipleConnectedInteractive都能拥有子装配体。如果一个装配体附加到另一个装配体上,则执行对象实例树的深度复制。

注意,AIS_ConnectedInteractive不能引用 AIS_MultipleConnectedInteractiveAIS_ConnectedInteractive复制原始对象的敏感实体以进行选择,不同于AIS_MultipleConnectedInteractive 重用原始对象的实体。

实例可以通过以下DRAW命令控制:

  • vconnect:从输入对象和位置创建并显示AIS_MultipleConnectedInteractive对象。
  • vconnectto:使用给定位置制作对象的一个实例。
  • vdisconnect:断开装配体中的所有对象的连接,或通过名称或编号断开对象的连接。
  • vaddconnected:将对象添加到装配体中。
  • vlistconnected:列出装配体中的对象。

我们来看下面的例子:

1
2
3
4
5
6
pload MODELING VISUALIZATION
vinit
psphere s 1
vdisplay s
vconnectto s2 3 0 0 s # make instance
vfit

下面是 OpenGL_Structure 表示这些数据结构的方式:

被引用的对象即便没有显示的情况下,实例对象也可以正常工作。实例对象同时还会处理好选择数据的变换。

3.3 交互上下文

3.3.1 规则

交互上下文以透明的方式管理一个或多个查看器中交互对象的图形和可选择行为。在前一章中介绍的允许修改交互对象属性的大多数功能,在这里将再次审视。

有一个基本规则需要遵循:对已经被上下文认识的交互对象的修改,必须使用上下文函数来完成。只有当交互对象尚未加载到交互上下文中时,才可以直接调用可用于交互对象的函数。

1
2
3
Handle(AIS_Shape) aShapePrs = new AIS_Shape (theShape);
myIntContext->Display (aShapePrs, AIS_Shaded, 0, false, aShapePrs->AcceptShapeDecomposition());
myIntContext->SetColor(aShapePrs, Quantity_NOC_RED)

也可以这么写

1
2
3
4
Handle(AIS_Shape) aShapePrs = new AIS_Shape (theShape);
aShapePrs->SetColor (Quantity_NOC_RED);
aShapePrs->SetDisplayMode (AIS_Shaded);
myIntContext->Display (aShapePrs);

3.3.2 函数组

中立点和局部选择构成了交互上下文的两种操作模式或状态,交互上下文是控制可视化和选择的中心实体。中立点,作为默认模式,允许轻松地可视化和选择已加载到上下文中的交互对象。为特定对象激活局部选择允许选择它们的子部分。

3.3.3 上下文的管理

交互对象可以具有一定数量的特定图形属性,如可视化模式、颜色和材料。相应地,交互上下文具有一组图形属性,即Drawer,这是默认对其控制的对象有效的。当交互对象被可视化时,所需的图形属性首先从对象自己的Drawer中获取(如果存在),否则从上下文Drawer中获取。

以下可调整设置允许个性化呈现和选择的行为:

  • 默认Drawer,包含所有可以被没有自己属性的交互对象使用的颜色和线条属性。
  • 交互对象的默认可视化模式。默认为:模式0;
  • 通过鼠标移动检测到的实体的高亮颜色。默认为:Quantity_NOC_CYAN1
  • 预选择颜色。默认为:Quantity_NOC_GREEN
  • 选择颜色(当你点击检测到的对象时)。默认为:Quantity_NOC_GRAY80

所有这些设置都可以通过AIS_InteractiveContext的适当函数修改。当你改变与上下文有关的图形属性(例如,可视化模式)时,所有没有相应适当属性的交互对象都会被更新。

看下面的例子:

1
2
3
4
5
6
theCtx->Display (theObj1, false);
theCtx->Display (theObj2, true); // TRUE for viewer update
theCtx->SetDisplayMode (theObj1, 3, false);
theCtx->SetDisplayMode (2, true);
// theObj2 is visualized in mode 2 (if it accepts this mode)
// theObj1 stays visualized in its mode 3

PrsMgr_PresentationManagerSelectMgr_ViewerSelector3d,管理当前交互对象的展示和选择,与主查看器相关联。

警告!不要在真实代码中使用整数值(如上例所示)- 而应使用相应的枚举代替!每个可展示对象都有支持的显示和选择模式的独立列表;例如,AIS_DisplayMode枚举只适用于AIS_Shape展示。

3.4 局部选择

3.4.1 选择模式

局部选择由索引(选择模式)定义。特定交互对象实现的选择模式及其含义应在该类的文档中检查。例如,参见MeshVS_SelectionModeFlags,用于MeshVS_Mesh对象。

AIS_Shape是最常用的交互对象。它提供了管理对形状构成元素的选择操作的API(选择顶点、边缘、面等)。特定形状类型(TopAbs_ShapeEnum)的选择模式由方法AIS_Shape::SelectionMode()返回。

方法AIS_InteractiveContext::Display()没有选择模式参数激活对象的默认选择模式。方法AIS_InteractiveContext::Activate()AIS_InteractiveContext::Deactivate()激活和停用特定的选择模式。

可以同时激活多个选择模式(但默认的 0 模式用于选择整个对象是排他的 - 它不能与其他模式组合)。可以使用函数AIS_InteractiveContext::ActivatedModes检索活动模式的列表。

3.4.2 过滤器

为了定义动态检测的环境,你可以使用标准过滤器类或创建你自己的过滤器类。过滤器查询敏感原语的所有者,以确定它是否具有所需的特质。如果答案是肯定的,它就被保留;如果不是,则被拒绝。

对象的根类是SelectMgr_Filter。其背后的原理很简单:过滤器测试鼠标位置由选择器检测到的所有者(SelectMgr_EntityOwner)是否回答OK。如果是,它就被保留,否则就被拒绝。你可以通过实现延迟函数SelectMgr_Filter::IsOk()来创建一个自定义的过滤器对象类。

SelectMgr中,还有组合过滤器(AND过滤器,OR过滤器),允许组合多个过滤器。在交互上下文中,你添加的所有过滤器都存储在一个OR过滤器中(如果至少有一个过滤器回答OK,则回答OK)。

有一些标准过滤器,已经在几个包中实现:

  • StdSelect_EdgeFilter – 用于边缘,如线条和圆;
  • StdSelect_FaceFilter – 用于面,如平面、圆柱和球体;
  • StdSelect_ShapeTypeFilter – 用于形状类型,如复合体、实体、壳体和线条;
  • AIS_TypeFilter – 用于交互对象的类型;
  • AIS_SignatureFilter – 用于交互对象的类型和签名;
  • AIS_AttributeFilter – 用于交互对象的属性,如颜色和宽度。

有几个函数用于操作过滤器:

  • AIS_InteractiveContext::AddFilter 添加一个作为参数传递的过滤器。
  • AIS_InteractiveContext::RemoveFilter 移除一个作为参数传递的过滤器。
  • AIS_InteractiveContext::RemoveFilters 移除所有现有的过滤器。
  • AIS_InteractiveContext::Filters 获取上下文中活动的过滤器列表。

3.4.3 例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// shading visualization mode, no specific mode, authorization for decomposition into sub-shapes
const TopoDS_Shape theShape;
Handle(AIS_Shape) aShapePrs = new AIS_Shape (theShape);
myContext->Display (aShapePrs, AIS_Shaded, -1, true, true);

// activates decomposition of shapes into faces
const int aSubShapeSelMode = AIS_Shape::SelectionMode (TopAbs_Face);
myContext->Activate (aShapePrs, aSubShapeSelMode);

Handle(StdSelect_FaceFilter) aFil1 = new StdSelect_FaceFilter (StdSelect_Revol);
Handle(StdSelect_FaceFilter) aFil2 = new StdSelect_FaceFilter (StdSelect_Plane);
myContext->AddFilter (aFil1);
myContext->AddFilter (aFil2);

// only faces of revolution or planar faces will be selected
myContext->MoveTo (thePixelX, thePixelY, myView, true);

3.4.4 选择数据

动态检测和选择以一种直接的方式实施。只有一些约定和函数需要熟悉:

  • AIS_InteractiveContext::MoveTo – 将鼠标位置传递给交互上下文选择器。
  • AIS_InteractiveContext::SelectDetected – 存储在最后一次MoveTo时检测到的内容。改变之前选中的对象。根据选择方案,选择被丰富、替换或其他。
  • AIS_InteractiveContext::SelectPoint/SelectRectangle/SelectPolygon – 对点、矩形或周围区域应用选择。改变之前选中的对象。根据选择方案,选择被丰富、替换或其他。

检测到的和选中的实体的高亮显示由交互上下文自动管理。高亮颜色是上面处理过的颜色。如果你想自己管理这一部分,你可以断开这种自动模式:

1
2
AIS_InteractiveContext::SetAutomaticHilight
AIS_InteractiveContext::AutomaticHilight

你可以通过移动鼠标来查询交互上下文。以下函数可以使用:

  • AIS_InteractiveContext::HasDetected – 检查是否有检测到的实体;
  • AIS_InteractiveContext::DetectedOwner – 返回(当前高亮显示的)检测到的实体。

使用 Select 函数后,你可以探索选择列表。以下函数可以使用:

  • AIS_InteractiveContext::InitSelected – 初始化迭代器;
  • AIS_InteractiveContext::MoreSelected – 检查迭代器是否有效;
  • AIS_InteractiveContext::NextSelected – 将迭代器移动到下一个位置;
  • AIS_InteractiveContext::SelectedOwner – 返回当前迭代器位置的实体。

所有者对象SelectMgr_EntityOwner是一个关键对象,用于识别查看器中的可选择实体(由方法AIS_InteractiveContext::DetectedOwnerAIS_InteractiveContext::SelectedOwner返回)。交互对象本身可以通过方法SelectMgr_EntityOwner::Selectable检索,而识别子部分则取决于交互对象的类型。在AIS_Shape的情况下,(子)形状通过方法StdSelect_BRepOwner::Shape返回。

3.4.5 例子

1
2
3
4
5
6
7
8
9
10
for (myAISCtx->InitSelected(); myAISCtx->MoreSelected(); myAISCtx->NextSelected())
{
Handle(SelectMgr_EntityOwner) anOwner = myAISCtx->SelectedOwner();
Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
if (Handle(StdSelect_BRepOwner) aBRepOwner = Handle(StdSelect_BRepOwner)::DownCast (anOwner))
{
// to be able to use the picked shape
TopoDS_Shape aShape = aBRepOwner->Shape();
}
}

3.4.6 选择机制

AIS_InteractiveContextSelect* 方法接受一个额外参数指定选择机制,下面的表格阐述了这些机制的含义:

3.5 标准交互对象

交互对象是可选择和可视的对象,连接图形表示和底层参考几何体。

它们被分为四种类型:

  • Datum – 一个构造几何元素;
  • Relation – 对交互形状和相应参考几何体的约束;
  • Object – 一个拓扑形状或形状之间的连接;
  • None – 一个标记,它不是消除对象,而是告诉应用程序继续查找,直到它找到其生成中一个可接受的对象定义。

在这些类别内部,还可以通过签名进一步进行特征化。签名提供了进一步特征化的索引。默认情况下,交互对象具有None类型和0的签名(等同于None)。如果你想给你的交互对象指定特定的类型和签名,你必须重新定义两个虚拟方法:TypeSignature

3.5.1 Datum

基准元素将构造元素如线、圆、点、三面体、平面三面体、平面和轴线等聚集在一起。

AIS_PointAIS_AxisAIS_LineAIS_CircleAIS_PlaneAIS_Trihedron具有四种选择模式:

  • 模式AIS_TrihedronSelectionMode_EntireObject:选择一个三面体;
  • 模式AIS_TrihedronSelectionMode_Origin:选择三面体的原点;
  • 模式AIS_TrihedronSelectionMode_Axes:选择轴线;
  • 模式AIS_TrihedronSelectionMode_MainPlanes:选择XOY、YOZ、XOZ平面。

当你激活其中一种模式时,你可以选择的AIS对象类型包括:

  • AIS_Point
  • AIS_Axis(及轴线的类型信息);
  • AIS_Plane(及平面的类型信息)。

AIS_PlaneTrihedron提供三种选择模式:

  • 模式0:选择整个三面体;
  • 模式1:选择三面体的原点;
  • 模式2:选择轴线——与三面体的备注相同。

对于平面和三面体的表示,默认的长度单位是毫米,轴线表示的默认值是10。要修改这些尺寸,你必须暂时恢复对象Drawer。从中取出DatumAspect()并改变值FirstAxisLength。最后,重新计算表示。

3.5.2 Object

对象类型包括拓扑形状及形状之间的连接。

AIS_Shape有两种可视化模式:

  • 模式AIS_WireFrame:线框(默认模式)
  • 模式AIS_Shaded:着色(取决于形状的类型)

AIS_ConnectedInteractive是一个连接到另一个交互对象引用的交互对象,并且位于查看器的其他地方,使得不需要计算表示和选择,而是可以从你的对象引用中推断它们。AIS_MultipleConnectedInteractive是一个连接到一系列交互对象(也可以是连接的对象;它不需要占用大量内存的表示计算)的对象。

MeshVS_Mesh是一个表示网格的交互对象,它有一个提供几何信息(节点,元素)的数据源,并且可以使用自定义的表示构建器从源数据构建。

AIS_ColoredShape允许对TopoDS_Shape对象及其子形状使用自定义颜色和线宽。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
AIS_ColoredShape aColoredShape = new AIS_ColoredShape (theShape);

// setup color of entire shape
aColoredShape->SetColor (Quantity_NOC_RED);

// setup line width of entire shape
aColoredShape->SetWidth (1.0);

// set transparency value
aColoredShape->SetTransparency (0.5);

// customize color of specified sub-shape
aColoredShape->SetCustomColor (theSubShape, Quantity_NOC_BLUE1);

// customize line width of specified sub-shape
aColoredShape->SetCustomWidth (theSubShape, 0.25);

表示类AIS_PointCloud可用于高效绘制大量任意集合的彩色点。它使用Graphic3d_ArrayOfPoints将点数据传递到OpenGl图形驱动,以将一组点作为"点精灵"的数组绘制。点数据被打包进顶点缓冲对象以提高性能。

用于绘制点的点标记类型可以作为表示方面被指定。该表示提供了通过可视化点集的边界框进行选择的支持。它支持两种显示/高亮模式:点或边界框。

下面是一个例子:

1
2
3
4
5
6
Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (2000, Standard_True);
aPoints->AddVertex (gp_Pnt(-40.0, -40.0, -40.0), Quantity_Color (Quantity_NOC_BLUE1));
aPoints->AddVertex (gp_Pnt (40.0, 40.0, 40.0), Quantity_Color (Quantity_NOC_BLUE2));

Handle(AIS_PointCloud) aPntCloud = new AIS_PointCloud();
aPntCloud->SetPoints (aPoints);
A random colored cloud of points

3.5.3 Relations

关系由一个或多个交互形状和相应的参考几何体上的约束组成。例如,你可能想要将两条边约束在平行关系中。这个约束被视为一个独立的对象,并显示为一个敏感原语。它采取的图形形式是一个带有||符号的垂直箭头,位于两条边之间。

PrsDim提供以下关系:

  • PrsDim_ConcentricRelation
  • PrsDim_FixRelation
  • PrsDim_IdenticRelation
  • PrsDim_ParallelRelation
  • PrsDim_PerpendicularRelation
  • PrsDim_Relation
  • PrsDim_SymmetricRelation
  • PrsDim_TangentRelation

关系列表不是详尽无遗的。

PrsDim 提供了这个包,这表明 Relation 的作用主要是在标注领域。

3.5.4 Dimension

  • PrsDim_AngleDimension
  • PrsDim_Chamf3dDimension
  • PrsDim_DiameterDimension
  • PrsDim_DimensionOwner
  • PrsDim_LengthDimension
  • PrsDim_OffsetDimension
  • PrsDim_RadiusDimension

3.5.5 MeshVS_Mesh

MeshVS_Mesh是一个表示网格的交互对象。这个对象与AIS_Shape不同,因为它的几何数据由描述对象节点和元素的数据源MeshVS_DataSource支持。结果是,你可以提供你自己的数据源。

然而,DataSource不提供任何关于属性的信息,例如节点颜色,但你可以以一种特殊的方式应用它们——通过选择适当的表示构建器。

MeshVS_Mesh的表示是通过表示构建器MeshVS_PrsBuilder构建的。你可以在构建器之间选择,以不同的方式表示对象。此外,你可以重新定义基础构建器类并提供你自己的表示构建器。

你可以使用以下方法添加/移除构建器:

1
2
3
MeshVS_Mesh::AddBuilder (const Handle(MeshVS_PrsBuilder)& theBuilder, Standard_Boolean theToTreatAsHilighter);
MeshVS_Mesh::RemoveBuilder (const Standard_Integer theIndex);
MeshVS_Mesh::RemoveBuilderById (const Standard_Integer theId);

MeshVS_Mesh有一组保留的显示和高亮模式标志。模式值是一个位数,允许选择额外的显示参数并组合以下模式标志,这些模式标志允许以线框、着色和收缩模式显示网格:

1
2
3
MeshVS_DMF_WireFrame
MeshVS_DMF_Shading
MeshVS_DMF_Shrink

也可以以下方式来以线框、着色和收缩模式展示拆解后的 Mesh:

1
2
3
MeshVS_DMF_DeformedPrsWireFrame
MeshVS_DMF_DeformedPrsShading
MeshVS_DMF_DeformedPrsShrink

下面这些方法代表了不同类型的数据:

1
2
3
4
5
MeshVS_DMF_VectorDataPrs
MeshVS_DMF_NodalColorDataPrs
MeshVS_DMF_ElementalColorDataPrs
MeshVS_DMF_TextDataPrs
MeshVS_DMF_EntitiesWithData

下面这些方法提供选择和高亮

1
2
MeshVS_DMF_SelectionPrs
MeshVS_DMF_HilightPr

MeshVS_DMF_User 则是用户自定义的模式;

下面这些值为表示构造器使用,它们也是选择模式的控制符:

1
2
3
4
5
6
7
8
9
MeshVS_SMF_0D
MeshVS_SMF_Link
MeshVS_SMF_Face
MeshVS_SMF_Volume
MeshVS_SMF_Element // groups 0D, Link, Face and Volume as a bit mask;
MeshVS_SMF_Node
MeshVS_SMF_All // groups Element and Node as a bit mask;
MeshVS_SMF_Mesh
MeshVS_SMF_Group

例如下面的对象,可以并用来显示 STL 文件格式的对象:

1
2
3
4
5
6
7
8
9
10
11
// read the data and create a data source
Handle(Poly_Triangulation) aSTLMesh = RWStl::ReadFile (aFileName);
Handle(XSDRAWSTLVRML_DataSource) aDataSource = new XSDRAWSTLVRML_DataSource (aSTLMesh);

// create mesh
Handle(MeshVS_Mesh) aMeshPrs = new MeshVS();
aMeshPrs->SetDataSource (aDataSource);

// use default presentation builder
Handle(MeshVS_MeshPrsBuilder) aBuilder = new MeshVS_MeshPrsBuilder (aMeshPrs);
aMeshPrs->AddBuilder (aBuilder, true);

MeshVS_NodalColorPrsBuilder允许表示一个网格,并在其上映射一个颜色缩放纹理。为此,你应该为颜色刻度定义一个颜色映射,将这个映射传递给表示构建器,并为每个节点定义一个范围在0.0到1.0之间的适当值。以下示例展示了你如何做到这一点(检查视图是否已设置为显示纹理):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// assign nodal builder to the mesh
Handle(MeshVS_NodalColorPrsBuilder) aBuilder = new MeshVS_NodalColorPrsBuilder (theMeshPrs, MeshVS_DMF_NodalColorDataPrs | MeshVS_DMF_OCCMask);
aBuilder->UseTexture (true);

// prepare color map
Aspect_SequenceOfColor aColorMap;
aColorMap.Append (Quantity_NOC_RED);
aColorMap.Append (Quantity_NOC_BLUE1);

// assign color scale map values (0..1) to nodes
TColStd_DataMapOfIntegerReal aScaleMap;
...
// iterate through the nodes and add an node id and an appropriate value to the map
aScaleMap.Bind (anId, aValue);

// pass color map and color scale values to the builder
aBuilder->SetColorMap (aColorMap);
aBuilder->SetInvalidColor (Quantity_NOC_BLACK);
aBuilder->SetTextureCoords (aScaleMap);
aMesh->AddBuilder (aBuilder, true);

3.6 动态选择

动态选择通过敏感原语的分解来表示你想要选择的拓扑形状——将被检测和高亮显示的形状的子部分。这些原语的集合由强大的三级 BVH 树选择算法处理。

有关算法的更多细节和使用示例,请参考选择章节。

4 3D 表示

4.1 三维渲染术语

  • 群组(Group) - 一组原语及其属性的集合。原语和属性可以被添加到群组中,但除非进行全局擦除,否则不能从中移除。群组可以拥有一个拾取标识。
  • 光源(Light) - 有五种类型的光源 - 环境光、头灯、定向光、位置光和聚光灯。
  • 原语(Primitve) - 一个可绘制元素。它在 3D 空间中有定义。原语可以是线条、面、文本或标记。一旦显示,标记和文本保持相同大小。线条和面可以被修改,例如缩放。属性在群组内设置。原语必须存储在一个群组中。
  • 结构(Structure) - 管理一组群组。这些群组是互斥的。结构可以被编辑,添加或移除群组。结构可以引用其他结构形成层次结构。它有一个默认(身份)变换,也可以对其应用其他变换(旋转、平移、缩放等)。每个结构都有一个与之关联的显示优先级,这决定了它在 3D 查看器中重绘的顺序。
  • 视图(View) - 由视图定向、视图映射和上下文视图定义。
  • 查看器(Viewer) - 管理一组视图。
  • 视图定向(View Orientation) - 定义观察者以视图参考坐标查看场景的方式。
  • 视图映射(View mapping) - 定义从视图参考坐标到归一化投影坐标的转换。这遵循 Phigs 方案。
  • Z缓冲(Z-Buffering) - 仅在着色模式下的一种隐藏表面去除形式。这对于着色模式下的视图总是激活的,并且不能被抑制。

PHIGS代表“程序化图形标准”(Programmer's Hierarchical Interactive Graphics System)。它是一个三维计算机图形标准,用于描述和控制三维对象和场景的构造和渲染。PHIGS被设计为支持复杂的图形应用程序,提供了一种结构化的、层次化的方法来创建和管理图形数据。

PHIGS提供了一套丰富的图形编程接口,允许开发者定义图形对象(如线、面、体)、组织这些对象成结构,并通过变换(如旋转、缩放和平移)操作这些结构。这些图形结构可以被组织成一个场景图,支持复杂的三维场景表示。

视图映射(View mapping)在PHIGS中指的是将这些三维图形数据从模型空间转换到视口(即屏幕空间或投影空间)的过程,这包括投影变换(如透视投影或正交投影)、视图变换(定义观察者的位置和方向)等步骤。

总的来说,PHIGS方案提供了一个高度结构化和层次化的方法来处理复杂的三维图形数据和场景,虽然它已经被更现代的图形API(如OpenGL和DirectX)所超越,但它在历史上对三维图形标准的发展起到了重要作用。

4.2 图形原语

Graphic3d包用于在3D查看器中创建3D图形对象。这些被称为结构的对象由原语(如线段、三角形、文本和标记)的组合以及属性(如颜色、透明度、反射、线型、线宽和文本字体)组成。群组是结构中最小的可编辑元素。可以对结构应用变换。结构可以连接起来形成由变换组成的结构树。结构由查看器全局操作。

图形结构可以被:

  • 显示,
  • 高亮,
  • 擦除,
  • 变换,
  • 连接形成由变换创建的结构的树状层次结构。

有类用于:

  • 线条、面、标记、文本、材料的视觉属性,
  • 向量和顶点,
  • 图形对象、群组和结构。

4.2.1 Structure 层级结构

根是结构层次或结构网络的顶部。父结构的属性会传递给其后代。后代结构的属性不会影响父结构。不支持递归结构网络。

4.2.2 图形原语

  • Marker
    • 包含一个或者多个顶点;
    • 具有一个类型,一个缩放系数以及一个颜色;
    • 具有尺寸、形状、以及和变换无关的朝向;
  • Triangulation
    • 至少具有三个顶点;
    • 具有法线;
    • 具有一些内部属性,例如样式,颜色,前后材料,纹理以及反射比例等;
  • Polylines or Segments
    • 具有两个或者更多的顶点
    • 具有如下属性:类型,宽度缩放系数以及颜色
  • Text
    • 具有几何和非几何属性;
    • 几何属性:字符高度、字符向上方向,文本路径,水平和垂直对齐方式,三维位置,缩放系数等;
    • 非几何属性:字体,文本间距、字符扩张系数以及颜色等;

4.2.3 原语数组

不同类型的原语可以通过以下原语数组来表示:

  • Graphic3d_ArrayOfPoints,
  • Graphic3d_ArrayOfPolylines,
  • Graphic3d_ArrayOfSegments,
  • Graphic3d_ArrayOfTriangleFans,
  • Graphic3d_ArrayOfTriangles,
  • Graphic3d_ArrayOfTriangleStrips.

Graphic3d_ArrayOfPrimitives是这些原语数组的基类。方法Graphic3d_ArrayOfPrimitives::AddVertex允许向原语数组添加带有其属性(颜色、法线、纹理坐标)的顶点。你也可以通过顶点索引修改分配给顶点的值或查询这些值。

以下示例展示了如何定义一个点的数组:

1
2
3
4
5
6
7
8
9
10
11
// create an array
Handle(Graphic3d_ArrayOfPoints) anArray = new Graphic3d_ArrayOfPoints (theVerticiesMaxCount);

// add vertices to the array
anArray->AddVertex (10.0, 10.0, 10.0);
anArray->AddVertex (0.0, 10.0, 10.0);

// add the array to the structure
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
aGroup->AddPrimitiveArray (anArray);
aGroup->SetGroupPrimitivesAspect (myDrawer->PointAspect()->Aspect());

如果原语共享相同的顶点(多边形、三角形等),那么你可以将它们定义为顶点数组的索引。方法Graphic3d_ArrayOfPrimitives::AddEdge允许通过索引定义原语。这个方法在数组的范围[1, VertexNumber()]中添加一个“边”。也可以使用方法Graphic3d_ArrayOfPrimitives::Edge查询由边定义的顶点。

以下示例展示了如何定义一个三角形数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// create an array
Handle(Graphic3d_ArrayOfTriangles) anArray = new Graphic3d_ArrayOfTriangles (theVerticesMaxCount, theEdgesMaxCount, Graphic3d_ArrayFlags_None);
// add vertices to the array
anArray->AddVertex (-1.0, 0.0, 0.0); // vertex 1
anArray->AddVertex ( 1.0, 0.0, 0.0); // vertex 2
anArray->AddVertex ( 0.0, 1.0, 0.0); // vertex 3
anArray->AddVertex ( 0.0,-1.0, 0.0); // vertex 4

// add edges to the array
anArray->AddEdges (1, 2, 3); // first triangle
anArray->AddEdges (1, 2, 4); // second triangle

// add the array to the structure
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
aGroup->AddPrimitiveArray (anArray);
aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());

4.2.4 文本原语

TKOpenGl工具包使用纹理字体渲染文本标签。Graphic3d文本原语具有以下特性:

  • 固定大小(不可缩放)或可缩放,
  • 可以在视图平面内旋转到任意角度,
  • 支持 Unicode 字符集。

群组的文本属性可以通过Graphic3d_AspectText3d属性群组来定义。要将任何文本添加到图形结构中,你可以使用以下方法:

1
2
void Graphic3d_Group::AddText (const Handle(Graphic3d_Text)& theTextParams,
const Standard_Boolean theToEvalMinMax);

如果你不希望文本位置影响Graphic3d结构的边界,可以传递FALSE作为theToEvalMinMax参数。

注意:文本的朝向角度可以通过 Graphic3d_AspectText3d 的属性来设置;

看下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// get the group
Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();

// change the text aspect
Handle(Graphic3d_AspectText3d) aTextAspect = new Graphic3d_AspectText3d();
aTextAspect->SetTextZoomable (true);
aTextAspect->SetTextAngle (45.0);
aGroup->SetPrimitivesAspect (aTextAspect);

// add a text primitive to the structure
Handle(Graphic3d_Text) aText = new Graphic3d_Text (16.0f);
aText->SetText ("Text");
aText->SetPosition (gp_Pnt (1, 1, 1));
aGroup->AddText (aText);

4.2.5 材质

Graphic3d_MaterialAspect定义了以下常见的材料属性:

  • 透明度;
  • 漫反射——对象颜色的一个组成部分;
  • 环境反射;
  • 镜面反射——光源颜色的一个组成部分。

确定三种反射颜色需要以下项目:

  • 颜色;
  • 漫反射系数;
  • 环境反射系数;
  • 镜面反射系数。

常见材料属性在 Phong 着色模型中使用(Graphic3d_TypeOfShadingModel_PhongGraphic3d_TypeOfShadingModel_PhongFacetGraphic3d_TypeOfShadingModel_Gouraud)。在PBR 着色模型(Graphic3d_TypeOfShadingModel_PbrGraphic3d_TypeOfShadingModel_PbrFacet)中,材料属性由以下Graphic3d_PBRMaterial属性定义(Graphic3d_MaterialAspect::PBRMaterial()):

  • Albedo(主颜色);
  • 金属度因子;
  • 粗糙度因子;
  • 透明度;
  • 折射率指数。

4.2.6 纹理

纹理由一个名字来定义。以下三类纹理受到支持:

  • 1D;
  • 2D;
  • Environment Mapping;

4.2.7 自定义 Shader

OCCT可视化核心支持GLSL着色器。自定义着色器可以通过其绘制器属性(Graphic3d方面)分配给通用表示。要在你的应用程序中为特定的AIS_Shape启用自定义着色器,可以使用以下 API 函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Create shader program
Handle(Graphic3d_ShaderProgram) aProgram = new Graphic3d_ShaderProgram();

// Attach vertex shader
aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, "<Path to VS>"));

// Attach fragment shader
aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, "<Path to FS>"));

// Set values for custom uniform variables (if they are)
aProgram->PushVariable ("MyColor", Graphic3d_Vec3 (0.0f, 1.0f, 0.0f));

// Set aspect property for specific AIS_Shape
theAISShape->Attributes()->ShadingAspect()->Aspect()->SetShaderProgram (aProgram);

4.3 图形属性

4.3.1 Aspect 包预览

Aspect包提供了查看器中图形元素的类:

  • 图形属性的组;
  • 边缘、线条、背景;
  • 窗口;
  • 驱动程序;
  • 上述许多内容的枚举。

4.4 3D View 设施

4.4.1 概览

V3d包提供了定义 3D 查看器及其附属视图(正交视图、透视视图)的资源。这个包提供了操作屏幕上视图中可视化的任何3D对象的图形场景的命令。

一组高级命令允许分别操作参数和投影结果(旋转、缩放、平移等)以及任何特定视图中的可视化属性(模式、照明、裁剪等)。

V3d包基本上是一套由查看器前端指令驱动的工具集。这套工具包含了创建和编辑查看器类的方法,例如:

  • 查看器的默认参数,
  • 视图(正交视图、透视视图),
  • 照明(位置光、定向光、环境光、聚光灯、头灯),
  • 裁剪平面,
  • 实例化的视图、平面、光源、图形结构和拾取序列,
  • 各种包方法。

4.4.2 编程指南

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// create a default display connection
Handle(Aspect_DisplayConnection) aDispConnection = new Aspect_DisplayConnection();
// create a Graphic Driver
Handle(OpenGl_GraphicDriver) aGraphicDriver = new OpenGl_GraphicDriver (aDispConnection);
// create a Viewer to this Driver
Handle(V3d_Viewer) aViewer = new V3d_Viewer (aGraphicDriver);
aViewer->SetDefaultBackgroundColor (Quantity_NOC_DARKVIOLET);
// Create a structure in this Viewer
Handle(Graphic3d_Structure) aStruct = new Graphic3d_Structure (aViewer->StructureManager());
aStruct->SetVisual (Graphic3d_TOS_SHADING); // Type of structure

// Create a group of primitives in this structure
Handle(Graphic3d_Group) aPrsGroup = aStruct->NewGroup();

// Fill this group with one quad of size 100
Handle(Graphic3d_ArrayOfTriangleStrips) aTriangles = new Graphic3d_ArrayOfTriangleStrips (4);
aTriangles->AddVertex (-100./2., -100./2., 0.0);
aTriangles->AddVertex (-100./2., 100./2., 0.0);
aTriangles->AddVertex ( 100./2., -100./2., 0.0);
aTriangles->AddVertex ( 100./2., 100./2., 0.0);

Handle(Graphic3d_AspectFillArea3d) anAspects = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID, Quantity_NOC_RED,
Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0f,
Graphic3d_NameOfMaterial_Gold, Graphic3d_NameOfMaterial_Gold);
aPrsGroup->SetGroupPrimitivesAspect (anAspects);
aPrsGroup->AddPrimitiveArray (aTriangles);

// Create Ambient and Infinite Lights in this Viewer
Handle(V3d_AmbientLight) aLight1 = new V3d_AmbientLight (Quantity_NOC_GRAY50);
Handle(V3d_DirectionalLight) aLight2 = new V3d_DirectionalLight (V3d_Zneg, Quantity_NOC_WHITE, true);
aViewer->AddLight (aLight1);
aViewer->AddLight (aLight2);
aViewer->SetLightOn();

// Create a 3D quality Window with the same DisplayConnection
Handle(Xw_Window) aWindow = new Xw_Window (aDispConnection, "Test V3d", 100, 100, 500, 500);
aWindow->Map(); // Map this Window to this screen

// Create a Perspective View in this Viewer
Handle(V3d_View) aView = new V3d_View (aViewer);
aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
// Associate this View with the Window
aView->SetWindow (aWindow);
// Display presentation in this View
aStruct->Display();
// Finally update the Visualization in this View
aView->Update();
// Fit view to object size
aView->FitAll();

4.4.3 定义查看参数

OCCT的V3d_View视图投影和方向由摄像机控制。摄像机计算并提供投影和视图方向矩阵供OpenGL渲染。这允许用户控制所有的投影参数。摄像机由以下属性定义:

  • 眼睛(Eye)- 定义观察者(摄像机)位置。确保眼睛点永远不会处于前后裁剪平面之间。
  • 中心(Center)- 定义视图参考坐标的原点(摄像机指向的地方)。
  • 方向(Direction)- 定义摄像机视图的方向(从眼睛到中心)。
  • 距离(Distance)- 定义眼睛和中心之间的距离。
  • 前平面(Front Plane)- 在视图参考坐标系统中定义前裁剪平面的位置。
  • 后平面(Back Plane)- 在视图参考坐标系统中定义后裁剪平面的位置。
  • Z近(ZNear)- 定义眼睛和前平面之间的距离。
  • Z远(ZFar)- 定义眼睛和后平面之间的距离。

最常见的视图操作(平移、缩放、旋转)作为V3d_View类的便利方法或通过AIS_ViewController工具实现。然而,Graphic3d_Camera类也可以直接由应用程序开发者使用。