OpenCasCade官方开发文档翻译(7)–occt可视化

介绍

Open CASCADE 技术中的可视化基于以下方面的分离:

  • 一方面 – 存储您要显示和选择的实体的几何形状和拓扑结构的数据,以及
  • 另一方面 – 它的呈现(当对象显示在场景中时您看到的内容)和选择(交互选择整个对象或其子部分以将应用程序定义的操作应用于选定实体的可能性)。

演示通过演示组件进行管理,并通过选择组件进行选择。

应用程序交互服务AIS ) 提供了在应用程序 GUI 查看器和用于管理选择和演示的包之间创建链接的方法,这使得 3D 中这些功能的管理更加直观,因此更加透明。

AIS使用交互式对象的概念,这是一个可显示和可选择的实体,它表示应用程序数据中的一个元素。因此,在 3D 中,您(用户)无需熟悉AIS底层的任何功能,除非您想创建自己的交互式对象或选择过滤器。

但是,如果您需要提供的交互式对象和过滤器类型以外的类型,您将需要了解可呈现和可选择对象的机制,特别是如何实现它们的虚拟功能。要做到这一点,需要熟悉诸如 Sensitive Primitive 和 Presentable Object 等基本概念。

以下包用于显示 3D 对象:

用于显示 3D 对象的包也适用于 2D 对象的可视化。

下图显示了可视化中关键概念和包之间关系的示意图。当然,“几何与拓扑”只是AIS可以处理的应用程序数据的一个示例,应用程序特定的交互对象可以处理任何类型的数据。

图片[1]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

可视化中的关键概念和包

为了满足 CASCADE 用户的不同需求,本用户指南提供以下三种阅读方式。

基础概念

介绍

在 Open CASCADE 技术中,表示服务与它们所表示的数据分离,这些数据由应用算法生成。此划分允许您修改几何或拓扑算法及其结果对象,而无需修改可视化服务。

演示文稿的结构

在屏幕上显示一个对象涉及三种实体:

可展示的对象

可呈现对象的目的是以Graphic3d_Structure的形式提供对象的图形表示。在第一次显示请求时,它通过调用适当的算法并保留此框架以供进一步显示来创建此结构。

StdPrsPrs3d包中提供了标准表示算法。但是,您可以编写自己的特定表示算法,前提是它们创建由Graphic3d包中的结构组成的表示。您还可以创建单个可呈现对象的多个演示文稿:一个用于您的应用程序支持的每种可视化模式。

每个要单独呈现的对象必须是可呈现的或与可呈现的对象相关联。

观众

查看器允许交互式地操纵对象的视图。当您缩放、平移或旋转视图时,查看器在由可呈现对象创建的图形结构上进行操作,而不是在应用程序的数据模型上进行操作。在您的演示算法中创建 Graphic3d 结构允许您使用 Open CASCADE Technology 中提供的 3D 查看器进行 3D 可视化。

互动语境

交互式上下文通过一个通用的高级 API 控制整个演示过程。当应用程序请求显示对象时,交互式上下文向可呈现对象请求图形结构并将其发送给查看器进行显示。

演示包

演示至少涉及AIS、PrsMgr、StdPrsV3d包。如果您需要实现自己的表示算法,则可以使用其他包,例如Prs3dGraphic3d 。

  • 标准交互对象
    • AIS包提供类来实现交互式对象(可呈现和可选择的实体)。
    • PrsDim包为绘制尺寸和关系提供了可呈现的对象。
    • MeshVS包提供了用于处理网格数据的可展示对象MeshVS_Mesh 。
  • 标准演示文稿构建器
    • Prs3d包为箭头、圆柱体、球体等简单几何图形提供了现成的标准表示算法。它还定义了Prs3d_Drawer类,用于控制要根据颜色、线型、粗细等创建的演示文稿的属性。
    • StdPrs包为 B-Rep 形状提供了现成的标准表示算法。它提供了通用的表示算法,例如着色、线框、等值线和隐藏线移除。
    • DsgPrs包提供了用于显示尺寸、关系和 XYZ 三面体的工具。
  • 选择服务
  • 查看器管理V3d包提供了 3D 查看器支持的服务。
  • 低级接口

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

处理( V3d_Viewer ) 查看器;
BRepPrimAPI_MakeWedge aWedgeMaker(theWedgeDX、theWedgeDY、theWedgeDZ、theWedgeLtx);
TopoDS_Solid aShape = aWedgeMaker.Solid();
处理( AIS_Shape ) aShapePrs = AIS_Shape (aShape); // 创建可展示对象
aContext->Display (aShapePrs, AIS_Shaded, 0, true ); // 显示可呈现的对象并重绘 3d 查看器

形状是使用BRepPrimAPI_MakeWedge命令创建的。然后从形状创建AIS_Shape。在调用Display命令时,交互式上下文调用可呈现对象的 Compute 方法来计算演示数据并将其传输给查看器。见下图。

图片[2]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

显示可呈现的形状所涉及的过程

选择

标准OCCT 选择算法由两部分表示:动态和静态。动态选择使对象在鼠标光标移到对象上时自动突出显示。静态选择允许选择特定对象(或多个对象)以进行进一步处理。

有 3 种不同的选择类型:

  • 点选择– 允许选择并突出显示位于鼠标光标下的单个对象(或其部分);
  • 矩形选择– 允许拾取位于由鼠标开始和结束鼠标光标位置定义的矩形下方的对象或部件;
  • 折线选择– 允许拾取位于用户定义的非自相交折线下的对象或部件。

对于 OCCT 选择算法,所有可选对象都表示为一组敏感区域,称为敏感实体。当鼠标光标在视图中移动时,会分析每个对象的敏感实体是否存在碰撞。

术语和概念

本节介绍整个算法描述中使用的基本术语和概念。

敏感实体

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

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

图片[3]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

将形状划分为敏感实体的示例

根据用户的需要,敏感实体可能是原子的(点或边)或复杂的。复杂实体包含许多可以由检测机制以类似方式处理的子元素(例如,存储为一组线段或三角剖分的折线)。

实体用作选择算法的内部单元并且不包含任何拓扑数据,因此它们具有到维护特定于拓扑的方法的上层接口的链接。

实体所有者

每个Select3D_SensitiveEntity存储对其所有者SelectMgr_EntityOwner的引用,这是一个连接实体和相应可选择对象 ( SelectMgr_SelectableObject ) 的类。此外,所有者可以存储任何附加信息,例如敏感实体的拓扑形状、突出显示颜色和方法,或者是否选择了实体。

选择

为了简化对象的不同选择模式的处理,链接到其所有者的敏感实体被组织成集合,称为选择SelectMgr_Selection )。每个选择都包含为特定模式创建的实体以及敏感度和更新状态。

可选择的对象

可选对象(SelectMgr_SelectableObject或更准确地说是 AIS_InteractiveObject)存储有关所有创建的选择模式和敏感实体的信息。

可选对象的所有后继对象必须实现根据给定模式将其表示拆分为敏感实体的方法。计算出的实体排列在一个选择中,并添加到该对象的所有选择列表中。在永久删除对象之前,不会从列表中删除任何选择。

对于所有标准 OCCT 交互对象,零模式应该选择整个对象(但可以在自定义对象中重新定义)。例如,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)。
图片[4]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

从敏感实体到可选对象的引用层次结构
图片[5]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

可选对象内的实体组织原理

查看器选择器

对于每个 OCCT 查看器,都有一个查看器选择器SelectMgr_ViewerSelector3d。它为整个选择算法提供了一个高级API,并封装了对每个鼠标选择的对象和敏感实体的处理。查看器选择器维护选择模式的激活和停用,启动算法,该算法检测要选择的候选实体,并存储其结果,并实现用于保持选择结构最新的接口。

选择经理

选择管理器SelectMgr_SelectionManager是一个高级 API,用于操作所有显示对象的选择。它处理所有查看器选择器,激活和停用所有或特定选择器中对象的选择模式,管理每个对象的选择的计算和更新。此外,考虑到应用的变化,它会不断更新选择结构。

图片[6]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

查看器选择器和选择管理器之间的关系链

算法

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

选择片

每次选择算法运行的第一步是根据当前激活的选择类型构建选择平截头体。

对于点或矩形选择,平截头体的底部是一个分别按照像素容差或用户定义区域的尺寸构建的矩形。对于折线选择,由构造线定义的多边形被三角剖分,每个三角形都用作其自己的平截头体的基础。因此,这种类型的选择使用一组三角平截头体进行重叠检测。

截头体长度受近视体平面和远视体平面的限制,并且每个平面都平行于相应的视体平面构建。

图片[7]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

上图显示了矩形截头体:a) 鼠标移动或单击后,b) 应用矩形选择后。

图片[8]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

在上图中,三角截头体设置为:a) 通过用户定义的折线,b) 通过基于给定折线的多边形三角剖分,c) 通过基于其中一个三角形的三角截头体。

BVH 树

为了在查看器级别保持选择机制,使用了由 3棵BVH树组成的加速结构。

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

第二级BVH树由一个可选对象的所有敏感实体组成。激活默认模式时会自动构建第 2 级树,并在首次计算新选择模式时重新构建。

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

图片[9]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

选择 BVH 树层次结构:从最大的对象级别(第一)到最小的复杂实体级别(第三)

算法的阶段

该算法包括预处理和三个主要阶段。

预处理

意味着计算选择平截头体及其主要特征。

第一阶段——遍历第一级BVH树

在成功构建选择平截头体之后,算法开始遍历对象级BVH树。根据分离轴定理 (SAT)的条款,测试包含轴对齐边界框的节点与选择平截头体的重叠。当遍历向下到叶子节点时,意味着已经找到了具有可能重叠敏感实体的候选对象。如果没有检测到这样的对象,则算法停止并假定不需要选择对象。否则,它进入下一个阶段以处理找到的可选对象的实体。

第二阶段——遍历二级BVH树

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

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

  • 激活检查 – 实体可能目前处于非活动状态,因为它属于停用选择;
  • 容差检查 – 当前选择平截头体可能太大而无法进行进一步检查,因为它始终以所有激活实体中的最大容差构建;因此,在这一步可以缩放截锥体。

在这些检查之后,算法进入最后阶段。

第三阶段——特定敏感实体的重叠或包含测试

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

包和类

选择是作为多种算法的组合实现的,这些算法分为几个包 – SelectBasicsSelect3DSelectMgrStdSelect

选择基础

SelectBasics包包含用于选择的基本类和接口。最值得注意的是:

每个自定义敏感实体必须至少继承SelectBasics_SensitiveEntity

选择3D

Select3D包提供了标准敏感实体的定义,例如:

  • 盒子;
  • 圆圈;
  • 曲线;
  • 面;
  • 团体;
  • 观点;
  • 部分;
  • 三角形;
  • 三角测量;
  • 金属丝。

每个基本敏感实体都继承Select3D_SensitiveEntity。该包还包含两个辅助类,Select3D_SensitivePolySelect3D_SensitiveSet

Select3D_SensitiveEntity – 敏感实体的基本定义。

Select3D_SensitiveSet – 需要使用第三级BVH的所有复杂敏感实体的基类。它实现了树的遍历,并为检查子实体的方法定义了一个接口。

Select3D_SensitivePoly – 描述任意点集并实现选择的基本功能。重要的是要知道这个类不执行任何内部数据检查。因此,从Select3D_SensitivePoly继承的敏感实体的自定义实现必须满足分离轴定理的条款才能使用标准 OCCT 重叠检测方法。

选择管理器

SelectMgr包用于维护整个选择过程。为此,该软件包提供以下服务:

  • 激活和停用所有可选对象的选择模式;
  • 计算对象选择模式的接口;
  • 选择过滤器类的定义;
  • 使选择的BVH数据保持最新。

主要类的简要说明:

标准选择

StdSelect包包含一些SelectMgr类的实现和用于创建选择结构的工具。例如,

使用示例

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

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
{
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()方法中创建的。下面的示例显示了如何使用在StdSelect_BRepSelectionTool中实现的标准 OCCT 机制来完成拓扑形状的不同选择模式的计算。

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中注册准备好的选择:

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

下面的代码片段说明了上述步骤。它还包含启动检测程序和解析选择结果的代码。

// 假设有上一个示例中的 InteractiveBox 类的实例。
// 它包含用于选择的方法 InteractiveBox::ComputeSelection() 的实现
// 模式 0(必须选择整个框)和 1(必须选择框的边缘)
Handle(InteractiveBox)theBox;
Handle( AIS_InteractiveContext ) theContext;
// 防止自动激活默认选择模式
theContext->SetAutoActivateSelection ( false );
theContext->Display (theBox, false );
// 将一个框加载到选择管理器而不计算任何选择模式
theContext->Load (theBox, -1, true );
//激活边缘选择
theContext->Activate (theBox, 1);
// 在当前鼠标坐标和当前视图中运行激活实体的检测机制。
// 检测到的所有者将使用上下文突出显示颜色突出显示
theContext->MoveTo (aXMousePos, aYMousePos, myView, false );
// 选择检测到的所有者
theContext->Select();
// 遍历选定的所有者
for (theContext->InitSelected(); theContext->MoreSelected() && !aHasSelected; theContext->NextSelected())
{
Handle( AIS_InteractiveObject ) anIO = theContext->SelectedInteractive();
}
// 禁用 aBox1 的所有选择模式
theContext->Deactivate (aBox1);

同样重要的是要知道,在 OCCT 中为矩形选择实现了 2 种类型的检测:

  • 包容性检测。在这种情况下,仅当敏感图元的所有点都包含在选择矩形定义的区域内时,才认为检测到敏感图元;
  • 重叠检测。在这种情况下,当敏感图元与选择矩形部分重叠时,就认为检测到敏感图元。

标准 OCCT 选择机制默认使用包含检测。要更改这一点,请使用以下代码:

// 假设有一个创建的交互式上下文
const Handle ( AIS_InteractiveContext ) theContext;
// 获取当前查看器选择器
const Handle ( StdSelect_ViewerSelector3d )& aMainSelector = theContext->MainSelector();
// 设置标志以允许重叠检测
aMainSelector->AllowOverlapDetection ( true );

应用交互服务

介绍

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

默认情况下,交互式上下文从中性开始,将每个可选对象作为一个整体拾取,但用户可以为特定对象激活局部选择以制作对象的可选部分。本地/全局选择由为每个显示对象激活的选择模式列表管理,0(默认选择模式)通常表示全局(整个对象)选择。

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

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

图片[10]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

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

交互式对象

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

演示文稿

一个交互式对象可以有它的创建者想要给它的尽可能多的演示。3D 演示由Presentation Manager ( PrsMgr_PresentationManager ) 管理。由于这在AIS中是透明的,因此用户不必担心。

演示文稿由索引(显示模式)和对其所依赖的演示文稿管理器的引用来标识。按照惯例,交互式对象的默认表示模式具有索引 0。

图片[11]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

交互式对象的不同表示的计算由继承自 PrsMgr_PresentableObject::Compute 函数的Compute函数完成。它们由PresentationManager在可视化或更新请求时自动调用。

如果要创建自己的交互对象类型,则必须通过以下方式之一实现 Compute 函数:

对于 3D:

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

对于 3D 中的隐藏线移除 (HLR) 模式:

void PackageName_ClassName::Compute ( const Handle (Prs3d_Projector)& theProjector,
const HandlePrs3d_Presentation)& thePresentation);

隐藏线移除

视图可以有两种状态:正常模式或计算模式(隐藏线移除模式)。当后者处于活动状态时,视图会查找以正常模式显示的所有演示文稿,这些演示文稿已被通知为接受 HLR 模式。内部机制允许调用交互对象自己的Compute,即投影函数。

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

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

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

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

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

演示模式

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

  • “构造元素”或基准,
  • 关系(维度和约束)
  • 物体
  • None 类型(当对象是未知类型时)。

在这些类别中,可以通过签名(索引)获得额外的特征。默认情况下,交互对象的类型为 NONE,签名为 0(相当于 NONE)。如果你想给你的交互对象一个特定的类型和签名,你必须重新定义两个虚函数:

请注意, AIS中提供的“标准”对象已经使用了一些签名(请参阅标准交互式对象类列表)。

交互式上下文可以具有用于该组交互式对象的默认表示模式。给定的对象类别可能不接受此模式。因此,要获取有关此类的信息,必须使用虚函数AIS_InteractiveObject::AcceptDisplayMode

显示模式

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

高亮模式

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

函数AIS_InteractiveObject::SetHilightModeAIS_InteractiveObject::UnsetHilightMode允许指定用于突出显示的显示模式(所谓的突出显示模式),该模式独立于对象的活动表示有效。这种选择是暂时的还是确定的,都没有区别。

请注意,相同的演示文稿(以及因此相同的突出显示模式)用于突出显示检测到的对象和突出显示选定的对象,后者使用特殊的选择颜色绘制(请参阅与交互式上下文服务相关的部分)。

例如,您想系统地突出显示形状的线框表示 – 不考虑它是在线框表示中还是带有阴影。因此,您在交互对象的构造函数中将高亮模式设置为0。不要忘记在Compute函数中实现这种表示模式。

无限状态

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

让我们以表示交互式对象的IShape类为例:

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)
{
// 计算线框表示的算法
case 0:StdPrs_WFDeflectionShape::Add (thePrs, myShape, myDrawer); return;
// 计算阴影表现的算法
case 1: StdPrs_ShadedShape::Add (thePrs, myShape, myDrawer); return;
}
}
void myPk_IShape::Compute (const Handle(Prs3d_Projector)& theProjector,
const Handle(Prs3d_Presentation)& thePrs)
{
// 隐藏线模式计算算法
StdPrs_HLRPolyShape::Add (thePrs, myShape, myDrawer, theProjector);
}

选择

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

与给定模式相对应的一组敏感基元存储在选择SelectMgr_Selection ) 中。

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

选择基元(或敏感实体)的计算在虚函数ComputeSelection中完成。应该使用函数AIS_InteractiveObject::ComputeSelection为假设具有不同选择模式的每种类型的交互式对象实现它。选择章节中已经给出了该功能的机制和实现方式的详细说明。

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

图形属性

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

最初,所有抽屉属性都用预定义的值填充,这些值将定义默认的 3D 对象外观。当一个交互式对象被可视化时,首先从它自己的抽屉中获取所需的图形属性,如果存在的话,或者如果不存在该类型对象的特定抽屉,则从上下文抽屉中获取。

请记住有关图形属性的以下几点:

  • 每个交互式对象都可以有自己的可视化属性。
  • 默认情况下,交互式对象采用可视化上下文的图形属性(可视化模式、用于计算表示的偏转值、等参数的数量、颜色、线的类型、材料等)
  • AIS_InteractiveObject抽象类中,包括颜色、线条粗细、材质和透明度在内的标准属性已获得特权。因此,存在一定数量的虚函数,它们允许对这些属性进行操作。每个新的交互对象类都可以重新定义这些功能并改变类的行为。
图片[12]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

为 AIS_Shape 和 AIS_TextLabel 的变化重新定义虚函数。

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

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

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

补充服务

当您为交互对象使用补充服务时,请特别注意以下提到的情况。

更改交互对象的位置

以下功能允许在视图中“移动”交互对象的表示和选择,而无需重新计算(以及修改原始形状)。

将交互式对象连接到应用实体

每个交互式对象都具有允许以Transient形式将其归属为GetOwner的功能。

因此,交互式对象可以与应用实体关联或不关联,而不会影响其行为。

注意:不要被其他类型的所有者混淆 – SelectMgr_EntityOwner用于识别对象或对象本身的可选部分。

解析重合拓扑

由于三维图形坐标的精度具有有限的分辨率这一事实,拓扑对象的元素可以重合,从而产生“弹出”一些元素的效果。

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

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

对象层次结构

每个PrsMgr_PresentableObject都有一个名为myChildren的对象列表。PrsMgr_PresentableObject的任何转换也适用于其子项。此层次结构不会传播到Graphic3d级别及以下。

PrsMgr_PresentableObject将其组合(根据层次结构)转换发送到Graphic3d_Structure。结构的材料不受层次结构的影响。

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

实例化

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

  • 实例由分离的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:列出程序集中的对象。

看看下面的例子:

pload 建模可视化
责备
球体 1
显示
vconnectto s2 3 0 0 s # 创建实例
vfit

看看如何使用代理OpenGl_Structure来表示实例:

图片[13]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

不必为了创建实例而显示原始对象。选择也正确处理实例的转换:

pload MODELING VISUALIZATION
vinit
psphere s 1
psphere p 0.5
vdisplay s # p is not displayed
vsetloc s -2 0 0
vconnect x 3 0 0 s p # make assembly
vfit
图片[14]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

以下是涉及子组件的更复杂层次结构的示例:

pload MODELING VISUALIZATION
vinit
box b 1 1 1
psphere s 0.5
vdisplay b s
vsetlocation s 0 2.5 0
box d 0.5 0.5 3
box d2 0.5 3 0.5
vdisplay d d2
vconnectto b1 -2 0 0 b
vconnect z 2 0 0 b s
vconnect z2 4 0 0 d d2
vconnect z3 6 0 0 z z2
vfit

交互式上下文

规则

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

有一个基本规则需要遵循:对 Context 已知的交互式对象的修改必须使用 Context 函数来完成。如果交互式对象尚未加载到交互式上下文中,则只能直接调用可用于交互式对象的函数。

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

You can also write

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

功能组

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

交互上下文的管理

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

以下可调设置允许个性化演示和选择的行为:

  • 默认抽屉,包含所有可以被交互对象使用的颜色和线条属性,它们没有自己的属性。
  • 交互式对象的默认可视化模式。 默认情况下:模式 0;
  • 突出显示鼠标移动检测到的实体的颜色。默认情况下:Quantity_NOC_CYAN1
  • 预选颜色。默认情况下:Quantity_NOC_GREEN
  • 选择颜色(当您单击检测到的对象时)。默认情况下:Quantity_NOC_GRAY80

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

让我们检查两个交互对象的情况:theObj1theObj2

theCtx->Display (theObj1, false);
theCtx->Display (theObj2, true ); // TRUE 对于查看器更新
theCtx->SetDisplayMode (theObj1, 3, false );
theCtx->SetDisplayMode (2, true );
// theObj2 在模式 2 中可视化(如果它接受此模式)
// theObj1 在其模式 3 中保持可视化

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

警告!不要在实际代码中使用整数值(如上面的示例) – 改为使用适当的枚举!每个可呈现的对象都有独立的支持显示和选择模式列表;例如,AIS_DisplayMode枚举仅适用于AIS_Shape表示。

本地选择

选择模式

本地选择由索引(选择模式)定义。由特定交互对象实现的选择模式及其含义应在此类的文档中进行检查。例如,参见MeshVS_SelectionModeFlagsMeshVS_Mesh对象。

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

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

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

过滤器

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

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

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

There are Standard filters, which have already been implemented in several packages:

There are several functions to manipulate filters:

例子

// 着色可视化模式,无特定模式,授权分解成子形状
const TopoDS_Shape theShape;
Handle(AIS_Shape) aShapePrs = new AIS_Shape (theShape);
myContext->Display (aShapePrs, AIS_Shaded, -1, true , true );
// 激活将形状分解为面
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);
// 只选择旋转面或平面
myContext->MoveTo (thePixelX, thePixelY, myView, true );

选择

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

检测到和选定实体的突出显示由交互式上下文自动管理。高光颜色是上面处理的颜色。如果您想自己管理此部分,您仍然可以断开此自动模式:

您可以通过移动鼠标来质疑交互式上下文。可以使用以下功能:

使用Select功能后,您可以浏览选择列表。可以使用以下功能:

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

例子

for (myAISCtx->InitSelected();myAISCtx->MoreSelected();myAISCtx->NextSelected())
{
Handle( SelectMgr_EntityOwner ) anOwner = myAISCtx->SelectedOwner();
Handle( AIS_InteractiveObject ) anObj =Handle( AIS_InteractiveObject )::DownCast (anOwner->Selectable());
如果(HandleStdSelect_BRepOwner)aBRepOwner =HandleStdSelect_BRepOwner)::DownCast(anOwner))
{
// 能够使用选择的形状
TopoDS_Shape aShape = aBRepOwner->Shape();
}
}

选择方案

AIS_InteractiveContext的 Select* 方法接受一些选择方案作为参数。下表描述了可用的选择方案。

类型 点击反应 类型 点击反应
AIS_SelectionScheme_Replace
图片[15]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核
AIS_SelectionScheme_XOR
图片[16]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核
AIS_SelectionScheme_Add
图片[17]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核
AIS_SelectionScheme_Clear
图片[18]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核
AIS_SelectionScheme_Remove
图片[19]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核
AIS_SelectionScheme_ReplaceExtra
图片[20]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

标准交互式对象类

交互式对象是连接图形表示和基础参考几何图形的可选择和可视对象。

它们分为四种类型:

  • 基准面——构造几何元素;
  • 关系——对交互形状和相应参考几何的约束;
  • 对象——拓扑形状或形状之间的连接;
  • – 一个令牌,它不是消除对象,而是告诉应用程序进一步查看,直到它在其生成中找到可接受的对象定义。

在这些类别中,有可能通过签名进行额外的表征。签名提供了进一步表征的索引。默认情况下,交互式对象具有None类型和签名 0(相当于None)。如果你想给你的交互对象一个特定的类型和签名,你必须重新定义两个虚方法:TypeSignature

基准

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

AIS_PointAIS_AxisAIS_LineAIS_CircleAIS_PlaneAIS_Trihedron有四种选择模式:

  • mode AIS_TrihedronSelectionMode_EntireObject : 三面体的选择;
  • mode AIS_TrihedronSelectionMode_Origin :选择三面体的原点;
  • mode AIS_TrihedronSelectionMode_Axes :选择轴;
  • mode AIS_TrihedronSelectionMode_MainPlanes :选择平面 XOY、YOZ、XOZ。

当您激活其中一种模式时,您选择AIS对象类型:

AIS_PlaneTrihedron提供三种选择模式:

  • 模式0:选择整个三面体;
  • 方式一:选择三面体的原点;
  • 模式 2:轴的选择 – 与三面体的注释相同。

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

目的

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

AIS_Shape有两种可视化模式:

  • mode AIS_WireFrame :线(默认模式)
  • mode AIS_Shaded : 阴影(取决于形状的类型)

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

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

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

AIS_ColoredShape aColoredShape = AIS_ColoredShape (theShape);
// 设置整个形状的颜色
aColoredShape-> SetColor ( Quantity_NOC_RED);
// 设置整个形状的线宽
aColoredShape-> SetWidth (1.0);
// 设置透明度值
aColoredShape-> SetTransparency (0.5);
// 自定义指定子形状的颜色
aColoredShape-> SetCustomColor (theSubShape, Quantity_NOC_BLUE1);
// 自定义指定子形状的线宽
aColoredShape-> SetCustomWidth (theSubShape, 0.25);

表示类AIS_PointCloud可用于有效绘制大量任意彩色点集。它使用Graphic3d_ArrayOfPoints将点数据传递给OpenGL图形驱动程序,以将设置点绘制为“点精灵”数组。点数据被打包到顶点缓冲区对象中以提高性能。

  • 用于绘制点的点标记的类型可以指定为表示方面。
  • 演示文稿通过可视化点集的边界框提供选择。它支持两种显示/高亮模式​​:点或边界框。
图片[21]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

随机彩色点云

例子:

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);

绘制命令vpointcloud从形状三角剖分构建点云。该命令还可以绘制一个球面或具有大量点(超过一百万)的体积。

关系

关系由一个或多个交互式形状的约束和相应的参考几何图形组成。例如,您可能希望以平行关系约束两条边。该约束本身被视为对象,并显示为敏感原语。这采用用 || 标记的垂直箭头的图形形式。符号,位于两条边之间。

PrsDim提供以下关系:

关系列表并不详尽。

方面

MeshVS_Mesh

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

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

MeshVS_Mesh的演示文稿是使用演示文稿构建器MeshVS_PrsBuilder构建的。您可以在构建器之间进行选择,以不同的方式表示对象。此外,您可以重新定义基本构建器类并提供您自己的演示构建器。

您可以使用以下方法添加/删除构建器:

MeshVS_Mesh有一组保留的显示和突出显示模式标志。模式值是允许选择附加显示参数并组合以下模式标志的位数,允许以线框、着色和收缩模式显示网格:

也可以使用以下方法以线框、着色或收缩模式显示变形网格:

以下方法代表不同类型的数据:

以下方法提供选择和突出显示:

MeshVS_DMF_User是用户定义的模式。

演示文稿生成器将使用这些值。还有一组选择模式标志,可以按位组合进行分组:

  • MeshVS_SMF_0D
  • MeshVS_SMF_Link
  • MeshVS_SMF_Face
  • MeshVS_SMF_Volume
  • MeshVS_SMF_Element – 将0D、Link、FaceVolume分组为位掩码;
  • MeshVS_SMF_Node
  • MeshVS_SMF_All – 将元素节点分组为位掩码;
  • MeshVS_SMF_Mesh
  • MeshVS_SMF_Group

例如,这样的对象可用于显示对象并以 STL 文件格式存储:

// 读取数据并创建数据源
Handle( Poly_Triangulation ) aSTLMesh = RWStl::ReadFile (aFileName);
// 创建网格
Handle( MeshVS_Mesh ) aMeshPrs = new MeshVS();
aMeshPrs->SetDataSource (aDataSource);
// 使用默认的演示生成器
Handle( MeshVS_MeshPrsBuilder ) aBuilder = new MeshVS_MeshPrsBuilder (aMeshPrs);
aMeshPrs->AddBuilder (aBuilder, true );

MeshVS_NodalColorPrsBuilder允许使用映射在其上的颜色缩放纹理来表示网格。为此,您应该为色标定义一个颜色映射,将此映射传递给演示构建器,并为每个节点定义一个 0.0 – 1.0 范围内的适当值。以下示例演示了如何执行此操作(检查视图是否已设置为显示纹理):

// 将节点构建器分配给网格
Handle( MeshVS_NodalColorPrsBuilder ) aBuilder = new MeshVS_NodalColorPrsBuilder (theMeshPrs, MeshVS_DMF_NodalColorDataPrs | MeshVS_DMF_OCCMask);
aBuilder->UseTexture ( true );
//准备颜色图
aColorMap.Append (Quantity_NOC_RED);
aColorMap.Append (Quantity_NOC_BLUE1);
// 将颜色比例图值 (0..1) 分配给节点
// 遍历节点并将节点 id 和适当的值添加到地图
aScaleMap.Bind (anId, aValue);
// 将颜色映射和颜色比例值传递给构建器
aBuilder->SetColorMap (aColorMap);
aBuilder->SetInvalidColor (Quantity_NOC_BLACK);
aBuilder->SetTextureCoords (aScaleMap);
aMesh->AddBuilder (aBuilder, true );

动态选择

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

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

3D 演示

3D 术语表

  • ——一组原语和这些原语的属性。基元和属性可以添加到组中,但不能从中删除,除非全局删除。一个组可以有一个选择标识。
  • 光源有五种光源——环境光源、前照灯、定向光源、位置光源和点光源。
  • Primitive – 一个可绘制的元素。它在 3D 空间中有一个定义。基元可以是线条、面、文本或标记。一旦显示标记和文本保持相同的大小。可以修改线条和面,例如缩放。属性在组内设置。基元必须存储在一个组中。
  • 结构——管理一组组。这些组是相互排斥的。可以对结构进行编辑、添加或删除组。一个结构可以引用其他结构来形成层次结构。它有一个默认的(恒等式)转换,并且可以对其应用其他转换(旋转、平移、缩放等)。每个结构都有一个与之关联的显示优先级,它决定了它在 3D 查看器中的重绘顺序。
  • 视图——由视图方向、视图映射和上下文视图定义。
  • 查看器——管理一组视图。
  • 视图方向– 定义观察者根据视图参考坐标查看场景的方式。
  • 视图映射——定义从视图参考坐标到标准化投影坐标的转换。这遵循 Pigs 方案。
  • Z-Buffering – 一种仅在着色模式下去除隐藏表面的形式。这对于着色模式下的视图始终处于活动状态,并且不能被抑制。

图形基元

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

图形结构可以是:

  • 显示,
  • 突出显示,
  • 抹去,
  • 变身,
  • 连接以形成由转换创建的结构树层次结构。

有以下课程:

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

结构层次

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

图形基元

  • 标记
    • 有一个或多个顶点,
    • 有类型、比例因子和颜色,
    • 具有独立于变换的大小、形状和方向。
  • 三角测量
    • 至少有三个顶点,
    • 已为着色定义了节点法线,
    • 具有内饰属性——款式、颜色、正反面材质、质感和反射率。
  • 折线线段
    • 有两个或多个顶点,
    • 具有以下属性——类型、宽度比例因子、颜色。
  • 文本
    • 具有几何和非几何属性,
    • 几何属性——字符高度、字符向上向量、文本路径、水平和垂直对齐、方向、三维位置、可缩放标志
    • 非几何属性——文本字体、字符间距、字符扩展因子、颜色。

原始数组

不同类型的原语可以用以下原语数组表示:

Graphic3d_ArrayOfPrimitives是这些原始数组的基类。方法集Graphic3d_ArrayOfPrimitives::AddVertex允许将顶点及其属性(颜色、法线、纹理坐标)添加到图元数组。您还可以修改分配给顶点的值或通过顶点索引查询这些值。

以下示例显示了如何定义点数组:

// 创建一个数组
Handle( Graphic3d_ArrayOfPoints ) anArray = new Graphic3d_ArrayOfPoints (theVerticiesMaxCount);
// 将顶点添加到数组中
anArray->AddVertex(10.0, 10.0, 10.0);
anArray->AddVertex(0.0, 10.0, 10.0);
// 将数组添加到结构中
Handle ( Graphic3d_Group ) aGroup = thePrs-> NewGroup ();
aGroup->AddPrimitiveArray(anArray);
aGroup->SetGroupPrimitivesAspect (myDrawer->PointAspect()->Aspect());

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

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

// 创建一个数组
Handle ( Graphic3d_ArrayOfTriangles ) anArray = new Graphic3d_ArrayOfTriangles (theVerticesMaxCount, theEdgesMaxCount, Graphic3d_ArrayFlags_None);
// 将顶点添加到数组中
anArray->AddVertex(-1.0, 0.0, 0.0); // 顶点
anArray->AddVertex(1.0, 0.0, 0.0); // 顶点
anArray->AddVertex(0.0, 1.0, 0.0); // 顶点
anArray->AddVertex(0.0,-1.0, 0.0); // 顶点
// 将边添加到数组中
anArray->AddEdges (1, 2, 3); // 第一个三角形
anArray->AddEdges(1, 2, 4); //第二个三角形
// 将数组添加到结构中
Handle ( Graphic3d_Group ) aGroup = thePrs-> NewGroup ();
aGroup->AddPrimitiveArray(anArray);
aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());

文本原语

TKOpenGl工具包使用纹理字体呈现文本标签。Graphic3d文本基元具有以下特点:

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

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

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

如果您不希望 Graphic3d 结构边界受到文本位置的影响,您可以将 FALSE 作为theToEvalMinMax传递。

请注意,文本方向角度可以由Graphic3d_AspectText3d属性定义。

请参阅示例:

// 获取组
Handle ( Graphic3d_Group ) aGroup = thePrs-> NewGroup ();
// 改变文本方面
Handle( Graphic3d_AspectText3d ) aTextAspect = new Graphic3d_AspectText3d ();
aTextAspect->SetTextZoomable ( true );
aTextAspect->SetTextAngle (45.0);
aGroup->SetPrimitivesAspect (aTextAspect);
// 将文本原语添加到结构中
Handle( Graphic3d_Text ) aText = new Graphic3d_Text (16.0f);
aText->SetText(“文本”);
aText->SetPosition ( gp_Pnt (1, 1, 1));
aGroup->AddText (aText);

材料

Graphic3d_MaterialAspect定义了以下通用材料属性:

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

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

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

Phong 着色模型(Graphic3d_TypeOfShadingModel_Phong、Graphic3d_TypeOfShadingModel_PhongFacet 和 Graphic3d_TypeOfShadingModel_Gouraud)中使用了常见的材料属性。在 PBR 着色模型(Graphic3d_TypeOfShadingModel_Pbr 和 Graphic3d_TypeOfShadingModel_PbrFacet)中,材质属性由以下Graphic3d_PBRMaterial属性(Graphic3d_MaterialAspect::PBRMaterial())定义:

  • 反照率(主色);
  • 金属因素;
  • 粗糙度系数;
  • 透明度;
  • 折射率。

纹理

纹理由名称定义。提供三种类型的纹理:

  • 一维;
  • 二维;
  • 环境映射。

自定义着色器

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

// 创建着色器程序
// 附加顶点着色器
aProgram->AttachShader ( Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, “<Path to VS>” ));
// 附加片段着色器
aProgram->AttachShader ( Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, “<Path to FS>” ));
// 设置自定义统一变量的值(如果有的话)
aProgram->PushVariable ( “MyColor” , Graphic3d_Vec3 (0.0f, 1.0f, 0.0f));
// 为特定的 AIS_Shape 设置 aspect 属性
aISShape->Attributes()->ShadingAspect()->Aspect()->SetShaderProgram(aProgram);

图形属性

方面包概述

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

  • 图形属性组;
  • 边缘、线条、背景;
  • 窗户;
  • 司机;
  • 上面的许多枚举。

3D观景设施

概述

V3d包提供了定义 3D 查看器和附加到该查看器的视图(正交、透视)的资源该软件包提供了用于操作在屏幕视图中可视化的任何 3D 对象的图形场景的命令。

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

V3d包基本上是一组由查看器前端命令引导的工具该工具集包含用于创建和编辑查看器类的方法,例如:

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

一个编程示例

V3d包的示例测试程序使用主要包XwGraphic3d以及辅助包Visual3d、Aspect、Quantitymath

// 创建默认显示连接
Handle( Aspect_DisplayConnection ) aDispConnection = new Aspect_DisplayConnection ();
// 创建图形驱动程序
Handle( OpenGl_GraphicDriver ) aGraphicDriver = new OpenGl_GraphicDriver (aDispConnection);
//为此驱动程序创建一个查看器
Handle( V3d_Viewer ) aViewer = new V3d_Viewer (aGraphicDriver);
aViewer->SetDefaultBackgroundColor (Quantity_NOC_DARKVIOLET);
// 在这个查看器中创建一个结构
Handle( Graphic3d_Structure ) aStruct = new Graphic3d_Structure (aViewer->StructureManager());
aStruct->SetVisual (Graphic3d_TOS_SHADING); // 结构类型
// 在这个结构中创建一组图元
Handle( Graphic3d_Group ) aPrsGroup = aStruct->NewGroup();
// 用一个大小为 100 的四边形填充这个组
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,
数量_NOC_RED,Aspect_TOL_SOLID,1.0f,
Graphic3d_NameOfMaterial_Gold, Graphic3d_NameOfMaterial_Gold);
aPrsGroup->SetGroupPrimitivesAspect (anAspects);
aPrsGroup->AddPrimitiveArray (aTriangles);
// 在此查看器中创建环境光和无限光
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();
// 创建一个具有相同 DisplayConnection 的 3D 质量 Window
Handle( Xw_Window ) aWindow = new Xw_Window (aDispConnection, “Test V3d” , 100, 100, 500, 500);
一个窗口->地图();// 将此窗口映射到此屏幕
// 在这个 Viewer 中创建一个透视图
Handle( V3d_View ) aView = new V3d_View (aViewer);
aView->Camera()->SetProjectionType ( Graphic3d_Camera::Projection_Perspective );
// 将此视图与窗口关联
aView->SetWindow (aWindow);
// 在此视图中显示演示文稿
aStruct->Display();
// 最后更新这个视图中的可视化
aView->Update();
// 使视图适合对象大小
aView->FitAll();

定义查看参数

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

  • 眼睛——定义观察者(相机)的位置。确保眼点永远不会位于前剪裁平面和后剪裁平面之间。
  • 中心– 定义视图参考坐标的原点(相机瞄准的位置)。
  • 方向– 定义相机视图的方向(从眼睛到中心)。
  • 距离——定义眼睛和中心之间的距离。
  • 平面 – 定义视图参考坐标系中前剪裁平面的位置。
  • Back Plane – 定义视图参考坐标系中后剪裁平面的位置。
  • ZNear – 定义 Eye 和 Front 平面之间的距离。
  • ZFar – 定义 Eye 和 Back plane 之间的距离。

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

// 将相机沿 X 轴旋转 30.0 度
gp_Trsf aTrsf;
aTrsf.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Dir (1.0, 0.0, 0.0)), M_PI / 4.0);
aView->Camera()->Transform (aTrsf);

正交投影

图片[22]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

透视和正交投影

以下代码配置相机进行正交渲染:

// 在这个 Viewer 中创建一个正交视图
Handle( V3d_View ) aView = new V3d_View (theViewer);
aView->Camera()->SetProjectionType ( Graphic3d_Camera::Projection_Orthographic );
aView->Update();// 更新此视图中的可视化

透视投影

视野 (FOVy) – 以 y 轴为单位定义摄像机视野(默认为 45°)。

图片[23]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

一个视角

以下代码为透视渲染配置相机:

// 在这个 Viewer 中创建一个透视视图
Handle( V3d_View ) aView = new V3d_View (theViewer);
aView->Camera()->SetProjectionType ( Graphic3d_Camera::Projection_Perspective );
aView->Update();

立体投影

IOD – 定义眼内距离(以世界空间单位表示)。

IOD 有两种类型:

视野 (FOV) – 以 y 轴为单位定义摄像机视野(默认为 45°)。

ZFocus – 定义到立体焦距点的距离。

图片[24]-OpenCasCade官方开发文档翻译(7)–occt可视化-卡核

立体投影

要为有源(快门)3D 眼镜启用立体投影,您的工作站应满足以下要求:

  • 显卡应该支持四重缓冲。
  • 您需要主动式 3D 眼镜(液晶快门眼镜)。
  • 图形驱动程序需要配置为对新创建的OpenGL上下文进行四边形缓冲;之后应该创建查看器和视图。

在立体投影模式下,相机准备两个投影矩阵来为左眼和右眼显示不同的立体图像。 在非立体相机中,这种效果是不可见的,因为双眼只使用相同的投影。

要启用四重缓冲支持,您应该为图形驱动程序 OpenGl_Caps 提供以下设置:

OpenGl_Caps& aCaps = aDriver->ChangeOptions();

以下代码配置相机以进行立体渲染:

// 在此查看器中创建立体视图
Handle(V3d_View) aView = new V3d_View (theViewer);
aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
// 更改立体声参数
aView->Camera()->SetIOD (IODType_Absolute, 5.0);
// 最后更新此视图中的可视化
aView->Update();

还支持其他 3D 显示器,包括无源眼镜和立体眼镜的隔行扫描 – 请参阅 Graphic3d_StereoMode 枚举。 激活另一个立体显示的示例:

Handle(V3d_View) theView;
theView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
theView->ChangeRenderingParams().StereoParams = Graphic3d_StereoMode_RowInterlaced ;

VR/AR头显在应用中的支持更涉及。Aspect_XRSession类定义了一个用于处理扩展现实的基本接口。

查看裁片剔除

CPU 端的截锥体剔除算法默认为 3D 查看器激活。该算法允许在渲染阶段跳过相机外部的演示,从而提供更好的性能。以下功能支持此方法:

查看背景样式

V3d_View有几种类型的背景样式可用:纯色、渐变色、图像和环境立方体贴图。

要为背景设置纯色,您可以使用以下方法:

渐变背景样式可以通过以下方法设置:

const Quantity_Color & theColor2,
const Aspect_GradientFillMethod theFillStyle,
const Standard_Boolean theToUpdate = false );

theColor1和theColor2参数定义了插值的边界颜色,theFillStyle参数定义了插值的方向。

要将图像设置为背景并更改背景图像样式,可以使用以下方法:

const Aspect_FillMethod theFillStyle,
const Standard_Boolean theToUpdate = false );

theFileName参数定义图像文件名及其路径,theFillStyle参数定义用图像填充背景的方法。方法是:

  • Aspect_FM_NONE – 在默认位置绘制图像;
  • Aspect_FM_CENTERED – 在视图中心绘制图像;
  • Aspect_FM_TILED – 将视图与图像平铺;
  • Aspect_FM_STRETCH – 在视图上拉伸图像。

将 3D 场景转储到图像文件中

视图中显示的 3D 场景可以转储到分辨率与窗口大小无关的图像文件中(使用屏幕外缓冲区)。V3d_View具有以下转储 3D 场景的方法

const Image_TypeOfImage theBufferType);

将场景转储到具有视图尺寸的图像文件中。光栅图像数据处理算法基于Image_AlienPixMap类。支持的扩展名是“.png”、“.bmp”、“.jpg”和FreeImage库支持的其他扩展名。作为BufferType参数传递的值定义输出图像的缓冲区类型(RGB、RGBA、浮点、RGBF、RGBAF)。如果场景已成功转储,则方法返回 TRUE。

将显示的 3d 场景转储到像素图中,其宽度和高度通过参数结构theParams传递。

光线追踪支持

OCCT 可视化通过实时光线追踪技术提供渲染。允许在通常的光栅化和光线追踪渲染模式之间轻松切换。OCCT 光线追踪的核心是使用 GLSL 着色器编写的。光线追踪有很多特性:

  • 硬阴影
  • 折射
  • 反射
  • 透明度
  • 纹理
  • 支持非多边形对象,如线条、文本、突出显示、选择。
  • 使用 2 级包围体层​​次结构 ( BVH ) 进行性能优化。

光线追踪算法是递归的(Whitted 算法)。它采用BVH有效的优化结构。该结构为场景几何准备优化数据,以便进一步实时显示。BVH的耗时重新计算对于视图操作、选择、动画甚至通过变换对象位置来编辑场景来说都是不必要的。仅当显示的对象列表或其几何形状发生变化时才需要。为了使BVH可重复使用,它已添加到单独的可重复使用 OCCT 包TKMath/BVH中。

用户可以打开/关闭几个光线追踪选项:

  • 最大光线追踪深度
  • 阴影渲染
  • 镜面反射
  • 自适应抗锯齿
  • 透明阴影效果

例子:

Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
// specifies rendering mode
// maximum ray-tracing depth
aParams.RaytracingDepth = 3;
// enable shadows rendering
aParams.IsShadowEnabled = true;
// enable specular reflections
aParams.IsReflectionEnabled = true;
// enable adaptive anti-aliasing
aParams.IsAntialiasingEnabled = true;
// enable light propagation through transparent media
// update the view
aView->Update();

显示优先级

结构显示优先级控制绘制结构的顺序。 当你显示一个结构时,你指定它的优先级。 值越低,显示优先级越低。 重新生成显示时,首先绘制优先级最低的结构。 具有相同显示优先级的结构按其显示顺序绘制。 OCCT 支持 [0, 10] 范围内的 11 个结构显示优先级。

Z 层支持

OCCT 具有称为 z 层的深度排列功能。 可以将图形表示放入 z 层。 通常,此功能可用于在图形应用程序中实现“放在前面”功能。

Example:

// 将 z 层设置为交互式对象
Handle( AIS_InteractiveObject ) theInterObj;
Standard_Integer anId = -1;
aViewer->AddZLayer (anId);
theContext->SetZLayer (theInterObj, anId);

对于每个 z 层,允许:

  • 启用/禁用层的深度测试。
  • 启用/禁用图层的深度写入。
  • 启用/禁用深度缓冲区清除。
  • 启用/禁用多边形偏移。

您可以使用V3d_Viewer中的 getter 获取选项。它返回给定LayerId的Graphic3d_ZLayerSettings

例子:

// 更改 z 层设置
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
aSettings.SetEnableDepthTest (true);
aSettings.SetEnableDepthWrite(true);
aSettings.SetClearDepth (true);
aViewer->SetZLayerSettings (anId, aSettings);

Z-Layer 功能的另一个应用是在显示远离世界中心的对象时处理视觉精度问题。此类对象的关键问题是可视化数据是使用单精度浮点数(32 位)存储和操作的。单精度 32 位浮点数仅提供 6-9 位有效十进制数字精度,而双精度 64 位数字提供 15-17 位有效十进制数字精度,这对于大多数应用程序来说已经足够了。

将对象移离世界中心很远时,浮点数会稳定地消耗精度。相机眼睛位置将前导十进制数字添加到整体对象转换中,由于浮点数性质,它会丢弃较小的数字。例如,大小为 0.0000123 的对象移动到位置 1000 的结果转换为 1000.0000123,它会溢出单精度浮点 – 考虑最乐观的 9 位有效数字的情况(但实际上并非如此),结果数将为 1000.00001。

这种不精确会导致 3D 查看器中出现两种视觉伪影:

  • 整体逐顶点对象失真。当在世界坐标系中定义了每个顶点位置时,就会发生这种情况。
  • 物体本身没有变形,但它在世界中的位置不稳定且不精确 – 物体在相机操作期间会跳跃。当顶点在局部坐标系中定义的距离足够小以将精度保持在单精度浮点数内时,就会发生这种情况,但是应用于对象的局部变换由于单精度浮点数而损坏。

如果不将整个演示文稿切换为双精度(对于每个顶点位置),则无法处理第一个问题。但是,使用单精度浮点数而不是双精度的可视化硬件要快得多 – 因此在大多数情况下这不是一个选项。然而,第二个问题可以通过应用特殊的渲染技巧来解决。

因此,要在 OCCT 中应用此功能,应用程序:

  • 为每个对象定义局部变换,以将表示数据适合单精度浮点数而不会失真。
  • 在空间上将世界分割成更小的区域/单元,单精度浮点就足够了。这种单元的大小可能会有所不同,并且取决于应用程序所需的精度(例如,用户能够在应用程序中放大多少相机)。
  • 为包含任何对象的每个空间单元定义一个 Z 层。
  • 根据单元中心定义 Z 层的 Local Origin 属性。
Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
aSettings.SetLocalOrigin (400.0, 0.0, 0.0);
  • 将可呈现的对象分配给最近的 Z 层。

请注意,图层的局部原点仅用于渲染 – 外部的所有内容仍将在世界坐标系中定义,包括对象的局部变换和检测结果。 例如,在具有不同 Local Origins 的 Z 层之间移动表示时,对象将停留在同一位置 – 只有可视化质量会有所不同。

剪裁平面

定义自定义剪切平面的能力对于某些任务可能非常有用。 OCCT 提供了这样一个机会。

Graphic3d_ClipPlane 类提供剪裁平面的服务:它保存平面方程系数并提供其图形表示。 要设置和获取平面方程系数,您可以使用以下方法:

可以使用以下方法激活剪切平面:

剪裁平面的数量是有限的。您可以通过方法Graphic3d_GraphicDriver::InquireLimit()检查限制值;

// 获取当前视图的裁剪平面限制
Standard_Integer aMaxClipPlanes = aView->Viewer()->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxNbClipPlanes);

例如,让我们看看如何使用自定义参数创建一个新的剪裁平面并将其添加到视图或对象中:

// 创建一个新的剪裁平面
// 改变剪裁平面的方程
Standard_Real aCoeffA, aCoeffB, aCoeffC, aCoeffD = …
aClipPlane->SetEquation ( gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
//设置上限
aClipPlane->SetCapping (aCappingArg == “on” );
// 设置剪裁平面为红色的材质
Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
Quantity_Color aColor (1.0, 0.0, 0.0, Quantity_TOC_RGB);
aMat.SetAmbientColor (aColor);
aMat.SetDiffuseColor (aColor);
aClipPlane->SetCappingMaterial (aMat);
// 设置裁剪平面的纹理
Handle( Graphic3d_Texture2Dmanual ) aTexture = …
aTexture->EnableModulate();
aTexture->EnableRepeat();
aClipPlane->SetCappingTexture (aTexture);
// 将剪切平面添加到交互对象
aIObj->AddClipPlane (aClipPlane);
// 或者到整个视图
aView->AddClipPlane (aClipPlane);
// 激活剪切平面
aClipPlane->SetOn (Standard_True);
// 更新视图
aView->Update();

自动背面剔除

背面剔除减少了三角形的渲染数量(这提高了性能)并消除了形状边界处的伪影。但是,此选项只能用于实体对象,其中内部实际上从任何角度看都是不可见的。默认开启自动背面剔除机制,由V3d_View::SetBackFacingModel()控制。

在StdPrs_ToolTriangulatedShape::IsClosed()中应用了以下功能,用于在ShadingAspect中定义背面剔除:

  • 禁用对自由封闭壳(不在实体内部)的剔除,因为自由壳的反向方向是有效的情况;
  • 启用对填充到化合物中的固体的剔除;
  • 忽略不完整三角剖分的实体。

在以下情况下,背面剔除在 TKOpenGl 级别关闭:

  • 剪裁/封盖平面生效;
  • 对于半透明物体;
  • 与孵化演示文稿风格。

示例:创建 3D 场景

要创建 3D 图形对象并在屏幕中显示它们,请按照以下步骤操作:

  1. 创建属性。
  2. 创建一个 3D 查看器。
  3. 创建视图。
  4. 创建交互式上下文。
  5. 创建交互式对象。
  6. 在交互式对象中创建基元。
  7. Display the interactive object.

Create attributes

创建颜色。

Quantity_Color aBlack (Quantity_NOC_BLACK);
Quantity_Color aBlue (Quantity_NOC_MATRABLUE);
Quantity_Color aBrown (Quantity_NOC_BROWN4);
Quantity_Color aFirebrick (Quantity_NOC_FIREBRICK);
Quantity_Color aForest (Quantity_NOC_FORESTGREEN);
Quantity_Color aGray (Quantity_NOC_GRAY70);
Quantity_Color aMyColor (0.99, 0.65, 0.31, Quantity_TOC_RGB);
Quantity_Color aBeet (Quantity_NOC_BEET);
Quantity_Color aWhite (Quantity_NOC_WHITE);

创建线属性。

anAspectBrown->SetColor (aBrown);
anAspectBlue ->SetColor (aBlue);
anAspectWhite->SetColor (aWhite);

创建标记属性。

// 标记属性
aFirebrickMarker->SetColor (Firebrick);
aFirebrickMarker->SetScale (1.0f);
aFirebrickMarker->SetType (Aspect_TOM_BALL);
// 或自定义图像
aFirebrickMarker->SetMarkerImage (theImage)

创建构面属性。

Graphic3d_MaterialAspect aBrassMaterial (Graphic3d_NameOfMaterial_Brass);
Graphic3d_MaterialAspect aGoldMaterial (Graphic3d_NameOfMaterial_Gold);
aFaceAspect->SetInteriorStyle (Aspect_IS_SOLID_WREFRAME);
aFaceAspect->SetInteriorColor (aMyColor);
aFaceAspect->SetDistinguishOn ();
aFaceAspect->SetFrontMaterial (aGoldMaterial);
aFaceAspect->SetBackMaterial (aBrassMaterial);

创建文本属性。

句柄( Graphic3d_AspectText3d ) aTextAspect = new Graphic3d_AspectText3d (aForest, Font_NOF_MONOSPACE, 1.0, 0.0);

创建 3D 查看器(Windows 示例)

// 创建图形驱动程序
// 创建一个查看器
myViewer = new V3d_Viewer (aGraphicDriver);
// 为 V3d_Viewer 设置参数
// 定义默认灯 –
// 位置光 0.3 0.0 0.0
// 定向光 V3d_XnegYposZpos
// 定向光 V3d_XnegYneg
// 环境光
a3DViewer->SetDefaultLights();
// 激活此查看器中定义的所有灯光
a3DViewer->SetLightOn();
// 设置背景颜色为黑色
a3DViewer->SetDefaultBackgroundColor (Quantity_NOC_BLACK);

创建 3D 视图(Windows 示例)

假定可能已经通过GetSafeHwnd()方法访问了有效的 Windows 窗口(如 MFC 示例的情况)。

Handle(WNT_Window) aWNTWindow = new WNT_Window (GetSafeHwnd());
myView = myViewer->CreateView();
myView->SetWindow (aWNTWindow);

创建交互式上下文

myAISContext = new AIS_InteractiveContext (myViewer);

您现在可以显示交互式对象,例如AIS_Shape

TopoDS_Shape aShape = BRepAPI_MakeBox (10, 20, 30).Solid();
Handle( AIS_Shape ) anAISShape =new AIS_Shape (aShape);
myAISContext->Display (anAISShape, true );

创建您自己的交互式对象

按照以下过程计算可呈现的对象:

  1. 构建一个继承自AIS_InteractiveObject的可展示对象(请参阅可展示对象章节)。
  2. 重用作为计算方法参数提供的Graphic3d_Structure 。

请注意,有两种计算方法:一种用于标准表示,另一种用于退化表示,即在隐藏线移除和线框模式下。

让我们看一下计算方法的例子

void MyPresentableObject::Compute ( const Handle ( PrsMgr_PresentationManager )& thePrsManager,
const Handle(Graphic3d_Structure)& thePrs,
const Standard_Integer theMode)
(
//…
)
void MyPresentableObject::Compute (const Handle(Prs3d_Projector)& theProjector,
const Handle(Graphic3d_Structure)& thePrs)
(
//…
)

在交互对象中创建基元

获取 Graphic3d_Structure 中使用的组。

Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();

更新组属性。

aGroup->SetGroupPrimitivesAspect (anAspectBlue);

在一个组中创建两个三角形。

Standard_Integer aNbTria = 2;
Handle(Graphic3d_ArrayOfTriangles) aTriangles = new Graphic3d_ArrayOfTriangles (3 * aNbTria, 0, Graphic3d_ArrayFlags_VertexNormal);
for (Standard_Integer aTriIter = 1; aTriIter <= aNbTria; ++aTriIter)
{
aTriangles->AddVertex (aTriIter * 5., 0., 0., 1., 1., 1.);
aTriangles->AddVertex (aTriIter * 5 + 5, 0., 0., 1., 1., 1.);
aTriangles->AddVertex (aTriIter * 5 + 2.5, 5., 0., 1., 1., 1.);
}
aGroup->AddPrimitiveArray (aTriangles);
aGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectFillArea3d());

使用 polyline 函数为组 aGroup 中的 thePrs 结构创建边界框。

Standard_Real Xm、Ym、Zm、XM、YM、ZM;
thePrs-> MinMaxValues (Xm, Ym, Zm, XM, YM, ZM);
Handle( Graphic3d_ArrayOfPolylines ) aPolylines = new Graphic3d_ArrayOfPolylines (16, 4);
aPolylines->AddBound (4);
aPolylines->AddVertex (Xm, Ym, Zm);
aPolylines->AddVertex (Xm, Ym, ZM);
aPolylines->AddVertex (Xm, YM, ZM);
aPolylines->AddVertex (Xm, YM, Zm);
aPolylines->AddBound (4);
aPolylines->AddVertex (Xm, Ym, Zm);
aPolylines->AddVertex (XM, Ym, Zm);
aPolylines->AddVertex (XM, Ym, ZM);
aPolylines->AddVertex (XM, YM, ZM);
aPolylines->AddBound (4);
aPolylines->AddVertex (XM, YM, Zm);
aPolylines->AddVertex (XM, Ym, Zm);
aPolylines->AddVertex (XM, YM, Zm);
aPolylines->AddVertex (Xm, YM, Zm);
aPolylines->AddBound (4);
aPolylines->AddVertex (Xm, YM, ZM);
aPolylines->AddVertex (XM, YM, ZM);
aPolylines->AddVertex (XM, Ym, ZM);
aPolylines->AddVertex (Xm, Ym, ZM);
aGroup->AddPrimitiveArray(aPolylines);
aGroup->SetGroupPrimitivesAspect ( new Graphic3d_AspectLine3d ());

在组aGroup中创建文本和标记。

static char* THE_TEXT[3] =
{
“Application title”,
“My company”,
“My company address.”
};
Handle( Graphic3d_ArrayOfPoints ) aPtsArr = new Graphic3d_ArrayOfPoints (2, 1);
aPtsArr->AddVertex (-40.0, -40.0, -40.0);
aPtsArr->AddVertex (40.0, 40.0, 40.0);
aGroup->AddPrimitiveArray (aPtsArr);
aGroup->SetGroupPrimitivesAspect ( new Graphic3d_AspectText3d ());
Graphic3d_Vertex aMarker (0.0, 0.0, 0.0);
for ( int i = 0; i <= 2; i++)
{
aMarker.SetCoord (-( Standard_Real )i * 4 + 30,
( Standard_Real )i * 4,
-( Standard_Real )i * 4);
aGroup->Text (THE_TEXT[i], Marker, 20.);
}

网格可视化服务

MeshVS(Mesh Visualization Service)组件扩展了Open CASCADE技术的3D可视化能力。它提供了灵活的方法来显示网格以及相关的预处理器和后处理器数据。

从开发人员的角度来看,很容易将MeshVS组件集成到任何与网格相关的应用程序中,遵循以下准则:

  • 从MeshVS_DataSource类派生一个数据源类。
  • 重新实现它的虚拟方法,以便让MeshVS组件访问应用程序数据模型。这是工作中最重要的部分,因为可视化性能受数据源类的数据检索方法性能的影响。
  • 创建MeshVS_Mesh类的实例。
  • 创建数据源类的实例并通过SetDataSource()方法将其传递给MeshVS_Mesh对象。
  • 创建一个或多个MeshVS_PrsBuilder派生类的对象(标准,包含在MeshVS包中,或您的自定义类)。
  • 每个PrsBuilder负责以指定为PrsBuilder构造函数参数的特定显示模式绘制MeshVS_Mesh表示。MeshVS类将显示模式视为位标志的组合(两个最低有效位用于编码标准显示模式:线框、阴影和收缩)。
  • 将这些对象传递给MeshVS_Mesh::AddBuilder()方法。MeshVS_Mesh利用改进的选择突出显示机制:它在所谓的“突出显示”对象的帮助下突出显示其选定的实体本身。您可以借助AddBuilder()方法的相应参数将其中一个PrsBuilder对象设置为荧光笔。

MeshVS_Mesh对象的视觉属性(如阴影颜色、收缩系数等)是通过MeshVS_Drawer对象控制的。它维护一个映射“属性 ID –> 属性值”,并且可以使用任意数量的自定义属性轻松扩展。

在所有其他方面,MeshVS_Mesh与从AIS_InteractiveObject派生的任何其他类非常相似,并且应该相应地使用它(请参阅文档中对AIS的描述)。

© 版权声明
THE END
喜欢就支持一下吧
点赞9019 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容