
Open CASCADE 技术中的可视化基于以下方面的分离:
演示通过演示组件进行管理,并通过选择组件进行选择。
应用程序交互服务( AIS ) 提供了在应用程序 GUI 查看器和用于管理选择和演示的包之间创建链接的方法,这使得 3D 中这些功能的管理更加直观,因此更加透明。
AIS使用交互式对象的概念,这是一个可显示和可选择的实体,它表示应用程序数据中的一个元素。因此,在 3D 中,您(用户)无需熟悉AIS底层的任何功能,除非您想创建自己的交互式对象或选择过滤器。
但是,如果您需要提供的交互式对象和过滤器类型以外的类型,您将需要了解可呈现和可选择对象的机制,特别是如何实现它们的虚拟功能。要做到这一点,需要熟悉诸如 Sensitive Primitive 和 Presentable Object 等基本概念。
以下包用于显示 3D 对象:
用于显示 3D 对象的包也适用于 2D 对象的可视化。
下图显示了可视化中关键概念和包之间关系的示意图。当然,“几何与拓扑”只是AIS可以处理的应用程序数据的一个示例,应用程序特定的交互对象可以处理任何类型的数据。
可视化中的关键概念和包为了满足 CASCADE 用户的不同需求,本用户指南提供以下三种阅读方式。
在 Open CASCADE 技术中,表示服务与它们所表示的数据分离,这些数据由应用算法生成。此划分允许您修改几何或拓扑算法及其结果对象,而无需修改可视化服务。
在屏幕上显示一个对象涉及三种实体:
可呈现对象的目的是以Graphic3d_Structure的形式提供对象的图形表示。在第一次显示请求时,它通过调用适当的算法并保留此框架以供进一步显示来创建此结构。
StdPrs和Prs3d包中提供了标准表示算法。但是,您可以编写自己的特定表示算法,前提是它们创建由Graphic3d包中的结构组成的表示。您还可以创建单个可呈现对象的多个演示文稿:一个用于您的应用程序支持的每种可视化模式。
每个要单独呈现的对象必须是可呈现的或与可呈现的对象相关联。
查看器允许交互式地操纵对象的视图。当您缩放、平移或旋转视图时,查看器在由可呈现对象创建的图形结构上进行操作,而不是在应用程序的数据模型上进行操作。在您的演示算法中创建 Graphic3d 结构允许您使用 Open CASCADE Technology 中提供的 3D 查看器进行 3D 可视化。
交互式上下文通过一个通用的高级 API 控制整个演示过程。当应用程序请求显示对象时,交互式上下文向可呈现对象请求图形结构并将其发送给查看器进行显示。
演示至少涉及AIS、PrsMgr、StdPrs和V3d包。如果您需要实现自己的表示算法,则可以使用其他包,例如Prs3d和Graphic3d 。
形状是使用BRepPrimAPI_MakeWedge命令创建的。然后从形状创建AIS_Shape。在调用Display命令时,交互式上下文调用可呈现对象的 Compute 方法来计算演示数据并将其传输给查看器。见下图。
显示可呈现的形状所涉及的过程标准OCCT 选择算法由两部分表示:动态和静态。动态选择使对象在鼠标光标移到对象上时自动突出显示。静态选择允许选择特定对象(或多个对象)以进行进一步处理。
有 3 种不同的选择类型:
对于 OCCT 选择算法,所有可选对象都表示为一组敏感区域,称为敏感实体。当鼠标光标在视图中移动时,会分析每个对象的敏感实体是否存在碰撞。
本节介绍整个算法描述中使用的基本术语和概念。
与实体所有者一样,敏感实体是对象和选择机制之间的链接。
实体的目的是定义对象的哪些部分特别是可选择的。因此,任何意味着可选择的对象都必须拆分为敏感实体(一个或多个)。例如,要将面选择应用于对象,必须将其分解为面并使用它们来创建敏感实体集。
将形状划分为敏感实体的示例根据用户的需要,敏感实体可能是原子的(点或边)或复杂的。复杂实体包含许多可以由检测机制以类似方式处理的子元素(例如,存储为一组线段或三角剖分的折线)。
实体用作选择算法的内部单元并且不包含任何拓扑数据,因此它们具有到维护特定于拓扑的方法的上层接口的链接。
每个Select3D_SensitiveEntity存储对其所有者SelectMgr_EntityOwner的引用,这是一个连接实体和相应可选择对象 ( SelectMgr_SelectableObject ) 的类。此外,所有者可以存储任何附加信息,例如敏感实体的拓扑形状、突出显示颜色和方法,或者是否选择了实体。
为了简化对象的不同选择模式的处理,链接到其所有者的敏感实体被组织成集合,称为选择( SelectMgr_Selection )。每个选择都包含为特定模式创建的实体以及敏感度和更新状态。
可选对象(SelectMgr_SelectableObject或更准确地说是 AIS_InteractiveObject)存储有关所有创建的选择模式和敏感实体的信息。
可选对象的所有后继对象必须实现根据给定模式将其表示拆分为敏感实体的方法。计算出的实体排列在一个选择中,并添加到该对象的所有选择列表中。在永久删除对象之前,不会从列表中删除任何选择。
对于所有标准 OCCT 交互对象,零模式应该选择整个对象(但可以在自定义对象中重新定义)。例如,AIS_Shape对象确定以下模式(请参阅AIS_Shape::SelectionMode()):
对于每个 OCCT 查看器,都有一个查看器选择器类SelectMgr_ViewerSelector3d。它为整个选择算法提供了一个高级API,并封装了对每个鼠标选择的对象和敏感实体的处理。查看器选择器维护选择模式的激活和停用,启动算法,该算法检测要选择的候选实体,并存储其结果,并实现用于保持选择结构最新的接口。
选择管理器SelectMgr_SelectionManager是一个高级 API,用于操作所有显示对象的选择。它处理所有查看器选择器,激活和停用所有或特定选择器中对象的选择模式,管理每个对象的选择的计算和更新。此外,考虑到应用的变化,它会不断更新选择结构。
查看器选择器和选择管理器之间的关系链基于通过 3 级BVH树遍历搜索截锥体和敏感实体之间的重叠,所有三种类型的 OCCT 选择都作为一个概念实现。
每次选择算法运行的第一步是根据当前激活的选择类型构建选择平截头体。
对于点或矩形选择,平截头体的底部是一个分别按照像素容差或用户定义区域的尺寸构建的矩形。对于折线选择,由构造线定义的多边形被三角剖分,每个三角形都用作其自己的平截头体的基础。因此,这种类型的选择使用一组三角平截头体进行重叠检测。
截头体长度受近视体平面和远视体平面的限制,并且每个平面都平行于相应的视体平面构建。
上图显示了矩形截头体:a) 鼠标移动或单击后,b) 应用矩形选择后。
在上图中,三角截头体设置为:a) 通过用户定义的折线,b) 通过基于给定折线的多边形三角剖分,c) 通过基于其中一个三角形的三角截头体。
为了在查看器级别保持选择机制,使用了由 3棵BVH树组成的加速结构。
第一级树由每个可选对象的轴对齐边界框构成。因此,这棵树的根包含所有可选边界的组合,即使它们当前没有激活的选择。对象是在显示AIS_InteractiveObject期间添加的,并且只有在对象被销毁时才会从该树中删除。第一级BVH树是在第一次运行选择算法的同时按需构建的。
第二级BVH树由一个可选对象的所有敏感实体组成。激活默认模式时会自动构建第 2 级树,并在首次计算新选择模式时重新构建。
第三级BVH树用于包含许多元素的复杂敏感实体:例如,三角剖分、具有许多线段的线、点集等。它是针对具有超过 800K 子元素(由StdSelect_BRepSelectionTool定义)的敏感实体的需求而构建的::PreBuildBVH())。
选择 BVH 树层次结构:从最大的对象级别(第一)到最小的复杂实体级别(第三)该算法包括预处理和三个主要阶段。
意味着计算选择平截头体及其主要特征。
在成功构建选择平截头体之后,算法开始遍历对象级BVH树。根据分离轴定理 (SAT)的条款,测试包含轴对齐边界框的节点与选择平截头体的重叠。当遍历向下到叶子节点时,意味着已经找到了具有可能重叠敏感实体的候选对象。如果没有检测到这样的对象,则算法停止并假定不需要选择对象。否则,它进入下一个阶段以处理找到的可选对象的实体。
在这个阶段,有必要确定一个对象的所有敏感实体中是否存在候选对象。
首先,在这个阶段,算法检查是否对当前对象应用了任何变换。如果它有自己的位置,则相应转换的截锥体将用于进一步计算。在下一步,访问给定对象的第二级BVH树的节点以搜索重叠的叶子。如果没有找到这样的叶子,则算法返回第二阶段。否则,它通过执行以下检查开始处理找到的实体:
在这些检查之后,算法进入最后阶段。
如果实体是原子的,则执行简单的 SAT 测试。在复杂实体的情况下,遍历第三级BVH树。分析匹配敏感实体的定量特征(如深度、到几何中心的距离)并应用剪切平面(如果已设置)。检测结果被存储,算法返回第二阶段。
选择是作为多种算法的组合实现的,这些算法分为几个包 – SelectBasics、Select3D、SelectMgr和StdSelect。
SelectBasics包包含用于选择的基本类和接口。最值得注意的是:
每个自定义敏感实体必须至少继承SelectBasics_SensitiveEntity。
Select3D包提供了标准敏感实体的定义,例如:
每个基本敏感实体都继承Select3D_SensitiveEntity。该包还包含两个辅助类,Select3D_SensitivePoly和Select3D_SensitiveSet。
Select3D_SensitiveEntity – 敏感实体的基本定义。
Select3D_SensitiveSet – 需要使用第三级BVH的所有复杂敏感实体的基类。它实现了树的遍历,并为检查子实体的方法定义了一个接口。
Select3D_SensitivePoly – 描述任意点集并实现选择的基本功能。重要的是要知道这个类不执行任何内部数据检查。因此,从Select3D_SensitivePoly继承的敏感实体的自定义实现必须满足分离轴定理的条款才能使用标准 OCCT 重叠检测方法。
SelectMgr包用于维护整个选择过程。为此,该软件包提供以下服务:
主要类的简要说明:
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 { 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()方法中创建的。下面的示例显示了如何使用在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 采用的突出选定实体所有者的传统方式假设每个实体所有者都自己突出显示自己。这种方法有两个缺点:
因此,为了克服这些限制,OCCT 有另一种方法来实现所选演示文稿的突出显示。使用这种方法,交互对象本身将负责突出显示,而不是实体所有者。
在SelectMgr_EntityOwner::IsAutoHilight()返回值的基础上,AIS_InteractiveContext对象要么使用传统的高亮方式(如果IsAutoHilight()返回 TRUE)或根据其可选择的对象对这些所有者进行分组,最后调用SelectMgr_SelectableObject::HilightSelected()或SelectMgr_SelectableObject::ClearSelected(),将一组所有者作为参数传递。
因此,应用程序可以派生它自己的交互式对象并从 SelectMgr_SelectableObject 重新定义虚拟方法HilightSelected ( )、ClearSelected()和HilightOwnerWithColor()。SelectMgr_SelectableObject::GetHilightPresentation和SelectMgr_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 ) 中获取,或者从上下文抽屉中获取。
可能需要过滤要选择的实体。因此有过滤器实体(SelectMgr_Filter),它允许细化动态检测上下文。其中一些过滤器只能在中性点内使用,其他过滤器只能在局部选择内使用。可以编写自定义过滤器并将它们加载到交互式上下文中。
在AIS查看器中可视化和选择的实体是对象 ( AIS_InteractiveObject )。它们将模型的基础参考几何与其在AIS中的图形表示联系起来。您可以使用标准交互对象的预定义 OCCT 类,所有必要的功能都已经编程,或者,如果您是高级用户,您可以实现自己的交互对象类。
一个交互式对象可以有它的创建者想要给它的尽可能多的演示。3D 演示由Presentation Manager ( PrsMgr_PresentationManager ) 管理。由于这在AIS中是透明的,因此用户不必担心。
演示文稿由索引(显示模式)和对其所依赖的演示文稿管理器的引用来标识。按照惯例,交互式对象的默认表示模式具有索引 0。
交互式对象的不同表示的计算由继承自 PrsMgr_PresentableObject::Compute 函数的Compute函数完成。它们由PresentationManager在可视化或更新请求时自动调用。
如果要创建自己的交互对象类型,则必须通过以下方式之一实现 Compute 函数:
视图可以有两种状态:正常模式或计算模式(隐藏线移除模式)。当后者处于活动状态时,视图会查找以正常模式显示的所有演示文稿,这些演示文稿已被通知为接受 HLR 模式。内部机制允许调用交互对象自己的Compute,即投影函数。
按照惯例,交互对象接受或拒绝 HLR 模式的表示。可以通过以下两种方式之一进行此声明:
AIS_Shape类是支持 HLR 表示的交互式对象的示例。HLR 算法的类型存储在形状的Prs3d_Drawer中。它是Prs3d_TypeOfHLR枚举的值,可以设置为:
可以通过调用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_Algo或Prs3d_TOH_PolyAlgo。多边形算法是默认算法。
AIS中有四种类型的交互式对象:
在这些类别中,可以通过签名(索引)获得额外的特征。默认情况下,交互对象的类型为 NONE,签名为 0(相当于 NONE)。如果你想给你的交互对象一个特定的类型和签名,你必须重新定义两个虚函数:
请注意, AIS中提供的“标准”对象已经使用了一些签名(请参阅标准交互式对象类列表)。
交互式上下文可以具有用于该组交互式对象的默认表示模式。给定的对象类别可能不接受此模式。因此,要获取有关此类的信息,必须使用虚函数AIS_InteractiveObject::AcceptDisplayMode。
函数AIS_InteractiveContext::SetDisplayMode和AIS_InteractiveContext::UnsetDisplayMode允许为对象设置自定义显示模式,这可能与交互式上下文所建议的不同。
在动态检测中,由交互式上下文回显的演示默认是屏幕上已经显示的演示。
函数AIS_InteractiveObject::SetHilightMode和AIS_InteractiveObject::UnsetHilightMode允许指定用于突出显示的显示模式(所谓的突出显示模式),该模式独立于对象的活动表示有效。这种选择是暂时的还是确定的,都没有区别。
请注意,相同的演示文稿(以及因此相同的突出显示模式)用于突出显示检测到的对象和突出显示选定的对象,后者使用特殊的选择颜色绘制(请参阅与交互式上下文服务相关的部分)。
例如,您想系统地突出显示形状的线框表示 – 不考虑它是在线框表示中还是带有阴影。因此,您在交互对象的构造函数中将高亮模式设置为0。不要忘记在Compute函数中实现这种表示模式。
如果您不希望对象受到FitAll视图的影响,则必须将其声明为无限;您可以使用AIS_InteractiveObject::SetInfiniteState和AIS_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::Attributes返回的Prs3d_Drawer属性可用于更精确和可预测的配置。
重要的是要知道哪些函数可能意味着重新计算对象的表示。如果要更新交互对象的呈现模式,则来自PrsMgr_PresentableObject的标志指示这一点。可以使用AIS_InteractiveContext中的函数Display和Redisplay更新模式。
当您为交互对象使用补充服务时,请特别注意以下提到的情况。
以下功能允许在视图中“移动”交互对象的表示和选择,而无需重新计算(以及修改原始形状)。
每个交互式对象都具有允许以Transient形式将其归属为GetOwner的功能。
因此,交互式对象可以与应用实体关联或不关联,而不会影响其行为。
注意:不要被其他类型的所有者混淆 – SelectMgr_EntityOwner用于识别对象或对象本身的可选部分。
由于三维图形坐标的精度具有有限的分辨率这一事实,拓扑对象的元素可以重合,从而产生“弹出”一些元素的效果。
对于两个或多个交互对象的元素重合时的问题,您可以应用多边形偏移。它是一种图形计算偏移或深度缓冲区偏移,它允许您排列元素(通过修改它们的深度值)而不改变它们的坐标。接受这种偏移的图形元素是实心多边形或显示为边界线和点。通过设置适当的内部样式,可以将多边形显示为线或点。
AIS_InteractiveObject ::SetPolygonOffsets和AIS_InteractiveContext::SetPolygonOffsets方法允许设置多边形偏移。
每个PrsMgr_PresentableObject都有一个名为myChildren的对象列表。PrsMgr_PresentableObject的任何转换也适用于其子项。此层次结构不会传播到Graphic3d级别及以下。
PrsMgr_PresentableObject将其组合(根据层次结构)转换发送到Graphic3d_Structure。结构的材料不受层次结构的影响。
对象层次结构可以通过以下 API 调用来控制:
实例化的概念操作对象层次结构如下:
类AIS_ConnectedInteractive和AIS_MultipleConnectedInteractive用于实现这个概念。
AIS_ConnectedInteractive是一个对象实例,它重用连接对象的几何形状,但有自己的变换和可见性标志。此连接向下传播到OpenGL级别,即到OpenGl_Structure。OpenGl_Structure只能连接到单个其他结构。
AIS_ConnectedInteractive通常可以引用到任何AIS_InteractiveObject。当它被引用到另一个AIS_ConnectedInteractive时,它只是复制引用。
AIS_MultipleConnectedInteractive表示一个程序集,它没有自己的表示。这些程序集能够参与对象层次结构并旨在处理一组实例化对象。就选择而言,它表现为单个对象。它将高级转换应用于所有子元素,因为它位于层次结构的上方。
所有AIS_MultipleConnectedInteractive都可以有子程序集。如果一个程序集附加到另一个程序集,则会执行对象实例树的深层复制。
请注意,AIS_ConnectedInteractive不能引用AIS_MultipleConnectedInteractive。AIS_ConnectedInteractive复制源对象的敏感实体以供选择,不像AIS_MultipleConnectedInteractive重用源对象的实体。
可以通过以下 DRAW 命令控制实例:
看看下面的例子:
pload 建模可视化 责备 球体 1 显示 vconnectto s2 3 0 0 s # 创建实例 vfit看看如何使用代理OpenGl_Structure来表示实例:
不必为了创建实例而显示原始对象。选择也正确处理实例的转换:
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以下是涉及子组件的更复杂层次结构的示例:
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);中性点和局部选择构成了交互上下文的两种操作模式或状态,交互上下文是引导可视化和选择的中心实体。 中性点是默认模式,允许轻松可视化和选择已加载到上下文中的交互式对象。 为特定对象激活本地选择允许选择它们的子部分。
一个交互对象可以具有一定数量的特定图形属性,例如可视化模式、颜色和材质。 相应地,交互式上下文具有一组图形属性,即抽屉,默认情况下对其控制的对象有效。 可视化交互式对象时,首先从对象自己的抽屉中获取所需的图形属性(如果存在),否则从上下文抽屉中获取。
以下可调设置允许个性化演示和选择的行为:
所有这些设置都可以通过适用于AIS_InteractiveContext的函数进行修改。当您更改与上下文相关的图形属性(例如可视化模式)时,所有没有相应属性的交互式对象都会更新。
让我们检查两个交互对象的情况:theObj1和theObj2:
theCtx->Display (theObj1, false); theCtx->Display (theObj2, true ); // TRUE 对于查看器更新 theCtx->SetDisplayMode (theObj1, 3, false ); theCtx->SetDisplayMode (2, true ); // theObj2 在模式 2 中可视化(如果它接受此模式) // theObj1 在其模式 3 中保持可视化管理当前交互对象的呈现和选择的PrsMgr_PresentationManager和SelectMgr_ViewerSelector3d与主查看器相关联。
警告!不要在实际代码中使用整数值(如上面的示例) – 改为使用适当的枚举!每个可呈现的对象都有独立的支持显示和选择模式列表;例如,AIS_DisplayMode枚举仅适用于AIS_Shape表示。
本地选择由索引(选择模式)定义。由特定交互对象实现的选择模式及其含义应在此类的文档中进行检查。例如,参见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检索活动模式列表。
要定义动态检测环境,您可以使用标准过滤器类或创建自己的过滤器类。过滤器询问敏感原语的所有者以确定它是否具有所需的质量。如果它的回答是肯定的,它就会被保留。如果不是,则拒绝。
对象的根类是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:
动态检测和选择以直接的方式实施。只有几个约定和函数需要熟悉:
检测到和选定实体的突出显示由交互式上下文自动管理。高光颜色是上面处理的颜色。如果您想自己管理此部分,您仍然可以断开此自动模式:
AIS_InteractiveContext::SetAutomaticHilight AIS_InteractiveContext::AutomaticHilight您可以通过移动鼠标来质疑交互式上下文。可以使用以下功能:
使用Select功能后,您可以浏览选择列表。可以使用以下功能:
所有者对象SelectMgr_EntityOwner是标识查看器中可选实体的关键对象(由AIS_InteractiveContext::DetectedOwner和AIS_InteractiveContext::SelectedOwner方法返回)。交互对象本身可以通过方法SelectMgr_EntityOwner::Selectable检索,而识别子部分取决于交互对象的类型。在AIS_Shape的情况下,(子)形状由方法StdSelect_BRepOwner::Shape返回。
AIS_InteractiveContext的 Select* 方法接受一些选择方案作为参数。下表描述了可用的选择方案。
| 类型 | 点击反应 | 类型 | 点击反应 | |
|---|---|---|---|---|
| AIS_SelectionScheme_Replace | AIS_SelectionScheme_XOR | |||
| AIS_SelectionScheme_Add | AIS_SelectionScheme_Clear | |||
| AIS_SelectionScheme_Remove | AIS_SelectionScheme_ReplaceExtra |
交互式对象是连接图形表示和基础参考几何图形的可选择和可视对象。
它们分为四种类型:
在这些类别中,有可能通过签名进行额外的表征。签名提供了进一步表征的索引。默认情况下,交互式对象具有None类型和签名 0(相当于None)。如果你想给你的交互对象一个特定的类型和签名,你必须重新定义两个虚方法:Type和Signature。
基准将线、圆、点、三面体、平面三面体、平面和轴等构造元素组合在一起。
AIS_Point、AIS_Axis、AIS_Line、AIS_Circle、AIS_Plane和AIS_Trihedron有四种选择模式:
当您激活其中一种模式时,您选择AIS对象类型:
AIS_PlaneTrihedron提供三种选择模式:
对于平面和三面体的表示,默认长度单位是毫米,轴表示的默认值是 10。要修改这些尺寸,您必须临时恢复对象Drawer。从中获取DatumAspect()并更改值FirstAxisLength。最后,重新计算演示文稿。
对象类型包括拓扑形状和形状之间的连接。
AIS_Shape有两种可视化模式:
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图形驱动程序,以将设置点绘制为“点精灵”数组。点数据被打包到顶点缓冲区对象中以提高性能。
例子:
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是一个表示网格的交互式对象。此对象与AIS_Shape不同,因为它的几何数据由描述对象节点和元素的数据源MeshVS_DataSource支持。因此,您可以提供自己的数据源。
但是,DataSource不提供任何有关属性的信息,例如节点颜色,但您可以通过选择适当的表示构建器以特殊方式应用它们。
MeshVS_Mesh的演示文稿是使用演示文稿构建器MeshVS_PrsBuilder构建的。您可以在构建器之间进行选择,以不同的方式表示对象。此外,您可以重新定义基本构建器类并提供您自己的演示构建器。
您可以使用以下方法添加/删除构建器:
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有一组保留的显示和突出显示模式标志。模式值是允许选择附加显示参数并组合以下模式标志的位数,允许以线框、着色和收缩模式显示网格:
MeshVS_DMF_WireFrame MeshVS_DMF_Shading MeshVS_DMF_Shrink也可以使用以下方法以线框、着色或收缩模式显示变形网格:
MeshVS_DMF_DeformedPrsWireFrame MeshVS_DMF_DeformedPrsShading MeshVS_DMF_DeformedPrsShrink以下方法代表不同类型的数据:
MeshVS_DMF_VectorDataPrs MeshVS_DMF_NodalColorDataPrs MeshVS_DMF_ElementalColorDataPrs MeshVS_DMF_TextDataPrs MeshVS_DMF_EntitiesWithData以下方法提供选择和突出显示:
MeshVS_DMF_SelectionPrs MeshVS_DMF_HilightPrsMeshVS_DMF_User是用户定义的模式。
演示文稿生成器将使用这些值。还有一组选择模式标志,可以按位组合进行分组:
例如,这样的对象可用于显示对象并以 STL 文件格式存储:
// 读取数据并创建数据源 Handle( Poly_Triangulation ) aSTLMesh = RWStl::ReadFile (aFileName); Handle( XSDRAWSTLVRML_DataSource ) aDataSource = new XSDRAWSTLVRML_DataSource (aSTLMesh); // 创建网格 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 ); //准备颜色图 Aspect_SequenceOfColor aColorMap; aColorMap. Append (Quantity_NOC_RED); aColorMap. Append (Quantity_NOC_BLUE1); // 将颜色比例图值 (0..1) 分配给节点 TColStd_DataMapOfIntegerReal aScaleMap; … // 遍历节点并将节点 id 和适当的值添加到地图 aScaleMap. Bind (anId, aValue); // 将颜色映射和颜色比例值传递给构建器 aBuilder->SetColorMap (aColorMap); aBuilder->SetInvalidColor (Quantity_NOC_BLACK); aBuilder->SetTextureCoords (aScaleMap); aMesh->AddBuilder (aBuilder, true );动态选择通过敏感基元的分解来表示您想要选择的拓扑形状- 将被检测和突出显示的形状的子部分。这些原语的集合由强大的三级BVH树选择算法处理。
有关算法和使用示例的更多详细信息,请参阅选择章节。
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文本基元具有以下特点:
该组的文本属性可以使用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 函数:
// 创建着色器程序 Handle( Graphic3d_ShaderProgram ) aProgram = new Graphic3d_ShaderProgram (); // 附加顶点着色器 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包为查看器中的图形元素提供类:
V3d包提供了定义 3D 查看器和附加到该查看器的视图(正交、透视)的资源。该软件包提供了用于操作在屏幕视图中可视化的任何 3D 对象的图形场景的命令。
一组高级命令允许在任何特定视图中单独操作参数和投影结果(旋转、缩放、平移等)以及可视化属性(模式、照明、剪辑等)。
V3d包基本上是一组由查看器前端命令引导的工具。该工具集包含用于创建和编辑查看器类的方法,例如:
此V3d包的示例测试程序使用主要包Xw和Graphic3d以及辅助包Visual3d、Aspect、Quantity和math。
// 创建默认显示连接 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 的四边形填充这个组 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, 数量_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 渲染。允许用户控制所有投影参数。相机由以下属性定义:
最常见的视图操作(平移、缩放、旋转)是作为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);以下代码配置相机进行正交渲染:
// 在这个 Viewer 中创建一个正交视图 Handle( V3d_View ) aView = new V3d_View (theViewer); aView->Camera()->SetProjectionType ( Graphic3d_Camera::Projection_Orthographic ); aView->Update();// 更新此视图中的可视化视野 (FOVy) – 以 y 轴为单位定义摄像机视野(默认为 45°)。
一个视角以下代码为透视渲染配置相机:
// 在这个 Viewer 中创建一个透视视图 Handle( V3d_View ) aView = new V3d_View (theViewer); aView->Camera()->SetProjectionType ( Graphic3d_Camera::Projection_Perspective ); aView->Update();IOD – 定义眼内距离(以世界空间单位表示)。
IOD 有两种类型:
视野 (FOV) – 以 y 轴为单位定义摄像机视野(默认为 45°)。
ZFocus – 定义到立体焦距点的距离。
立体投影要为有源(快门)3D 眼镜启用立体投影,您的工作站应满足以下要求:
在立体投影模式下,相机准备两个投影矩阵来为左眼和右眼显示不同的立体图像。 在非立体相机中,这种效果是不可见的,因为双眼只使用相同的投影。
要启用四重缓冲支持,您应该为图形驱动程序 OpenGl_Caps 提供以下设置:
Handle( OpenGl_GraphicDriver) aDriver = new OpenGl_GraphicDriver(); OpenGl_Caps& aCaps = aDriver->ChangeOptions(); aCaps. contextStereo = Standard_True;以下代码配置相机以进行立体渲染:
// 在此查看器中创建立体视图 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有几种类型的背景样式可用:纯色、渐变色、图像和环境立方体贴图。
要为背景设置纯色,您可以使用以下方法:
void V3d_View::SetBackgroundColor ( const Quantity_Color & theColor);渐变背景样式可以通过以下方法设置:
void V3d_View::SetBgGradientColors ( const Quantity_Color & theColor1, const Quantity_Color & theColor2, const Aspect_GradientFillMethod theFillStyle, const Standard_Boolean theToUpdate = false );theColor1和theColor2参数定义了插值的边界颜色,theFillStyle参数定义了插值的方向。
要将图像设置为背景并更改背景图像样式,可以使用以下方法:
void V3d_View::SetBackgroundImage ( const Standard_CString theFileName, const Aspect_FillMethod theFillStyle, const Standard_Boolean theToUpdate = false );theFileName参数定义图像文件名及其路径,theFillStyle参数定义用图像填充背景的方法。方法是:
视图中显示的 3D 场景可以转储到分辨率与窗口大小无关的图像文件中(使用屏幕外缓冲区)。V3d_View具有以下转储 3D 场景的方法:
Standard_Boolean V3d_View::Dump ( const Standard_CString theFile, const Image_TypeOfImage theBufferType);将场景转储到具有视图尺寸的图像文件中。光栅图像数据处理算法基于Image_AlienPixMap类。支持的扩展名是“.png”、“.bmp”、“.jpg”和FreeImage库支持的其他扩展名。作为BufferType参数传递的值定义输出图像的缓冲区类型(RGB、RGBA、浮点、RGBF、RGBAF)。如果场景已成功转储,则方法返回 TRUE。
Standard_Boolean V3d_View::ToPixMap ( Image_PixMap & theImage, const V3d_ImageDumpOptions & theParams);将显示的 3d 场景转储到像素图中,其宽度和高度通过参数结构theParams传递。
OCCT 可视化通过实时光线追踪技术提供渲染。允许在通常的光栅化和光线追踪渲染模式之间轻松切换。OCCT 光线追踪的核心是使用 GLSL 着色器编写的。光线追踪有很多特性:
光线追踪算法是递归的(Whitted 算法)。它采用BVH有效的优化结构。该结构为场景几何准备优化数据,以便进一步实时显示。BVH的耗时重新计算对于视图操作、选择、动画甚至通过变换对象位置来编辑场景来说都是不必要的。仅当显示的对象列表或其几何形状发生变化时才需要。为了使BVH可重复使用,它已添加到单独的可重复使用 OCCT 包TKMath/BVH中。
用户可以打开/关闭几个光线追踪选项:
例子:
Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams(); // specifies rendering mode aParams. Method = Graphic3d_RM_RAYTRACING; // 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 aParams. IsTransparentShadowEnabled = true; // update the view aView->Update();结构显示优先级控制绘制结构的顺序。 当你显示一个结构时,你指定它的优先级。 值越低,显示优先级越低。 重新生成显示时,首先绘制优先级最低的结构。 具有相同显示优先级的结构按其显示顺序绘制。 OCCT 支持 [0, 10] 范围内的 11 个结构显示优先级。
OCCT 具有称为 z 层的深度排列功能。 可以将图形表示放入 z 层。 通常,此功能可用于在图形应用程序中实现“放在前面”功能。
Example:
// 将 z 层设置为交互式对象 Handle( AIS_InteractiveContext) theContext; 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); aSettings. SetPolygonOffset ( Graphic3d_PolygonOffset()); aViewer->SetZLayerSettings (anId, aSettings);Z-Layer 功能的另一个应用是在显示远离世界中心的对象时处理视觉精度问题。此类对象的关键问题是可视化数据是使用单精度浮点数(32 位)存储和操作的。单精度 32 位浮点数仅提供 6-9 位有效十进制数字精度,而双精度 64 位数字提供 15-17 位有效十进制数字精度,这对于大多数应用程序来说已经足够了。
将对象移离世界中心很远时,浮点数会稳定地消耗精度。相机眼睛位置将前导十进制数字添加到整体对象转换中,由于浮点数性质,它会丢弃较小的数字。例如,大小为 0.0000123 的对象移动到位置 1000 的结果转换为 1000.0000123,它会溢出单精度浮点 – 考虑最乐观的 9 位有效数字的情况(但实际上并非如此),结果数将为 1000.00001。
这种不精确会导致 3D 查看器中出现两种视觉伪影:
如果不将整个演示文稿切换为双精度(对于每个顶点位置),则无法处理第一个问题。但是,使用单精度浮点数而不是双精度的可视化硬件要快得多 – 因此在大多数情况下这不是一个选项。然而,第二个问题可以通过应用特殊的渲染技巧来解决。
因此,要在 OCCT 中应用此功能,应用程序:
请注意,图层的局部原点仅用于渲染 – 外部的所有内容仍将在世界坐标系中定义,包括对象的局部变换和检测结果。 例如,在具有不同 Local Origins 的 Z 层之间移动表示时,对象将停留在同一位置 – 只有可视化质量会有所不同。
定义自定义剪切平面的能力对于某些任务可能非常有用。 OCCT 提供了这样一个机会。
Graphic3d_ClipPlane 类提供剪裁平面的服务:它保存平面方程系数并提供其图形表示。 要设置和获取平面方程系数,您可以使用以下方法:
Graphic3d_ClipPlane::Graphic3d_ClipPlane ( const gp_Pln& thePlane) void Graphic3d_ClipPlane::SetEquation ( const gp_Pln& thePlane) Graphic3d_ClipPlane::Graphic3d_ClipPlane ( const Equation& theEquation) void Graphic3d_ClipPlane::SetEquation ( const Equation& theEquation) gp_Pln Graphic3d_ClipPlane::ToPlane() const可以使用以下方法激活剪切平面:
void Graphic3d_ClipPlane::SetOn ( const Standard_Boolean theIsOn)剪裁平面的数量是有限的。您可以通过方法Graphic3d_GraphicDriver::InquireLimit()检查限制值;
// 获取当前视图的裁剪平面限制 Standard_Integer aMaxClipPlanes = aView->Viewer()->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxNbClipPlanes);例如,让我们看看如何使用自定义参数创建一个新的剪裁平面并将其添加到视图或对象中:
// 创建一个新的剪裁平面 句柄 ( Graphic3d_ClipPlane ) aClipPlane = new Graphic3d_ClipPlane (); // 改变剪裁平面的方程 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); // 将剪切平面添加到交互对象 句柄 ( AIS_InteractiveObject ) aIObj = … aIObj->AddClipPlane (aClipPlane); // 或者到整个视图 aView->AddClipPlane (aClipPlane); // 激活剪切平面 aClipPlane->SetOn (Standard_True); // 更新视图 aView->Update();背面剔除减少了三角形的渲染数量(这提高了性能)并消除了形状边界处的伪影。但是,此选项只能用于实体对象,其中内部实际上从任何角度看都是不可见的。默认开启自动背面剔除机制,由V3d_View::SetBackFacingModel()控制。
在StdPrs_ToolTriangulatedShape::IsClosed()中应用了以下功能,用于在ShadingAspect中定义背面剔除:
在以下情况下,背面剔除在 TKOpenGl 级别关闭:
要创建 3D 图形对象并在屏幕中显示它们,请按照以下步骤操作:
创建颜色。
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);创建线属性。
Handle( Graphic3d_AspectLine3d) anAspectBrown = new Graphic3d_AspectLine3d(); Handle( Graphic3d_AspectLine3d) anAspectBlue = new Graphic3d_AspectLine3d(); Handle( Graphic3d_AspectLine3d) anAspectWhite = new Graphic3d_AspectLine3d(); anAspectBrown->SetColor (aBrown); anAspectBlue ->SetColor (aBlue); anAspectWhite->SetColor (aWhite);创建标记属性。
Handle( Graphic3d_AspectMarker3d aFirebrickMarker = new Graphic3d_AspectMarker3d(); // 标记属性 aFirebrickMarker-> SetColor (Firebrick); aFirebrickMarker->SetScale (1.0f); aFirebrickMarker->SetType (Aspect_TOM_BALL); // 或自定义图像 aFirebrickMarker->SetMarkerImage (theImage)创建构面属性。
Handle( Graphic3d_AspectFillArea3d ) aFaceAspect = new Graphic3d_AspectFillArea3d (); 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);假定可能已经通过GetSafeHwnd()方法访问了有效的 Windows 窗口(如 MFC 示例的情况)。
Handle(WNT_Window) aWNTWindow = new WNT_Window (GetSafeHwnd()); myView = myViewer->CreateView(); myView->SetWindow (aWNTWindow);您现在可以显示交互式对象,例如AIS_Shape。
TopoDS_Shape aShape = BRepAPI_MakeBox (10, 20, 30).Solid(); Handle( AIS_Shape ) anAISShape =new AIS_Shape (aShape); myAISContext->Display (anAISShape, true );按照以下过程计算可呈现的对象:
请注意,有两种计算方法:一种用于标准表示,另一种用于退化表示,即在隐藏线移除和线框模式下。
让我们看一下计算方法的例子
void MyPresentableObject::Compute ( const Handle本文发布于:2024-03-05 00:23:09,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/1709614182120722.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
| 留言与评论(共有 0 条评论) |