Open CASCADE Technology  7.0.0

Visualization

Table of Contents

Introduction

Visualization in Open CASCADE Technology is based on the separation of:

  • on the one hand – the data which stores the geometry and topology of the entities you want to display and select, and
  • on the other hand – its presentation (what you see when an object is displayed in a scene) and selection (possibility to choose the whole object or its sub-parts interactively to apply application-defined operations to the selected entities).

Presentations are managed through the Presentation component, and selection through the Selection component.

Application Interactive Services (AIS) provides the means to create links between an application GUI viewer and the packages, which are used to manage selection and presentation, which makes management of these functionalities in 3D more intuitive and consequently, more transparent.

AIS uses the notion of the interactive object, a displayable and selectable entity, which represents an element from the application data. As a result, in 3D, you, the user, have no need to be familiar with any functions underlying AIS unless you want to create your own interactive objects or selection filters.

If, however, you require types of interactive objects and filters other than those provided, you will need to know the mechanics of presentable and selectable objects, specifically how to implement their virtual functions. To do this requires familiarity with such fundamental concepts as the sensitive primitive and the presentable object.

The the following packages are used to display 3D objects:

The packages used to display 3D objects are also applicable for visualization of 2D objects.

The figure below presents a schematic overview of the relations between the key concepts and packages in visualization. Naturally, "Geometry & Topology" is just an example of application data that can be handled by AIS, and application-specific interactive objects can deal with any kind of data.

visualization_image003.png
Key concepts and packages in visualization
To answer different needs of CASCADE users, this User's Guide offers the following three paths in reading it.

For advanced information on visualization algorithms, see our E-learning & Training offerings.

Fundamental Concepts

Presentation

In Open CASCADE Technology, presentation services are separated from the data, which they represent, which is generated by applicative algorithms. This division allows you to modify a geometric or topological algorithm and its resulting objects without modifying the visualization services.

Structure of the Presentation

Displaying an object on the screen involves three kinds of entities:

The presentable object

The purpose of a presentable object is to provide the graphical representation of an object in the form of Graphic3d structure. On the first display request, it creates this structure by calling the appropriate algorithm and retaining this framework for further display.

Standard presentation algorithms are provided in the StdPrs and Prs3d packages. You can, however, write specific presentation algorithms of your own, provided that they create presentations made of structures from the Graphic3d packages. You can also create several presentations of a single presentable object: one for each visualization mode supported by your application.

Each object to be presented individually must be presentable or associated with a presentable object.

The viewer

The viewer allows interactively manipulating views of the object. When you zoom, translate or rotate a view, the viewer operates on the graphic structure created by the presentable object and not on the data model of the application. Creating Graphic3d structures in your presentation algorithms allows you to use the 3D viewers provided in Open CASCADE Technology for 3D visualisation.

The Interactive Context

The interactive context controls the entire presentation process from a common high-level API. When the application requests the display of an object, the interactive context requests the graphic structure from the presentable object and sends it to the viewer for displaying.

Presentation packages

Presentation involves at least the AIS, PrsMgr, StdPrs and V3d packages. Additional packages, such as Prs3d and Graphic3d may be used if you need to implement your own presentation algorithms.

  • AIS package provides all classes to implement interactive objects (presentable and selectable entities).
  • PrsMgr package provides low level services and is only to be used when you do not want to use the services provided by AIS. It contains all classes needed to implement the presentation process: abstract classes Presentation and PresentableObject and concrete class PresentationManager3d.
  • StdPrs package provides ready-to-use standard presentation algorithms for specific geometries: points, curves and shapes of the geometry and topology toolkits.
  • Prs3d package provides generic presentation algorithms such as wireframe, shading and hidden line removal associated with a Drawer class, which controls the attributes of the presentation to be created in terms of color, line type, thickness, etc.
  • V3d package provides the services supported by the 3D viewer.
  • Graphic3d package provides resources to create 3D graphic structures.
  • Visual3d package contains classes implementing commands for 3D viewer.
  • DsgPrs package provides tools for display of dimensions, relations and XYZ trihedrons.

A Basic Example: How to display a 3D object

1 Void Standard_Real dx = ...; //Parameters
2 Void Standard_Real dy = ...; //to build a wedge
3 Void Standard_Real dz = ...;
4 Void Standard_Real ltx = ...;
5 
6 Handle(V3d_Viewer)aViewer = ...;
7 Handle(AIS_InteractiveContext)aContext;
8 aContext = new AIS_InteractiveContext(aViewer);
9 
10 BRepPrimAPI_MakeWedge w(dx, dy, dz, ltx);
11 TopoDS_Solid & = w.Solid();
12 Handle(AIS_Shape) anAis = new AIS_Shape(S);
13 //creation of the presentable object
14 aContext -> Display(anAis);
15 //Display the presentable object in the 3d viewer.

The shape is created using the BRepPrimAPI_MakeWedge command. An AIS_Shape is then created from the shape. When calling the Display command, the interactive context calls the Compute method of the presentable object to calculate the presentation data and transfer it to the viewer. See figure below.

visualization_image004.svg
Processes involved in displaying a presentable shape

Selection

Standard OCCT selection algorithm is represented by 2 parts: dynamic and static. Dynamic selection causes objects to be automatically highlighted as the mouse cursor moves over them. Static selection allows to pick particular object (or objects) for further processing.

There are 3 different selection types:

  • Point selection – allows picking and highlighting a single object (or its part) located under the mouse cursor;
  • Rectangle selection – allows picking objects or parts located under the rectangle defined by the start and end mouse cursor positions;
  • Polyline selection – allows picking objects or parts located under a user-defined non-self-intersecting polyline.

For OCCT selection algorithm, all selectable objects are represented as a set of sensitive zones, called sensitive entities. When the mouse cursor moves in the view, the sensitive entities of each object are analyzed for collision.

Terms and notions

This section introduces basic terms and notions used throughout the algorithm description.

Sensitive entity

Sensitive entities in the same way as entity owners are links between objects and the selection mechanism.

The purpose of entities is to define what parts of the object will be selectable in particular. Thus, any object that is meant to be selectable must be split into sensitive entities (one or several). For instance, to apply face selection to an object it is necessary to explode it into faces and use them for creation of a sensitive entity set.

visualization_image005.png
Example of a shape divided into sensitive entities
Depending on the user's needs, sensitive entities may be atomic (point or edge) or complex. Complex entities contain many sub-elements that can be handled by detection mechanism in a similar way (for example, a polyline stored as a set of line segments or a triangulation).

Entities are used as internal units of the selection algorithm and do not contain any topological data, hence they have a link to an upper-level interface that maintains topology-specific methods.

Entity owner

Each sensitive entity stores a reference to its owner, which is a class connecting the entity and the corresponding selectable object. Besides, owners can store any additional information, for example, the topological shape of the sensitive entity, highlight colors and methods, or if the entity is selected or not.

Selection

To simplify the handling of different selection modes of an object, sensitive entities linked to its owners are organized into sets, called selections.

Each selection contains entities created for a certain mode along with the sensitivity and update states.

Selectable object

Selectable object stores information about all created selection modes and sensitive entities.

All successors of a selectable object must implement the method that splits its presentation into sensitive entities according to the given mode. The computed entities are arranged in one selection and added to the list of all selections of this object. No selection will be removed from the list until the object is deleted permanently.

For all standard OCCT shapes, zero mode is supposed to select the whole object (but it may be redefined easily in the custom object). For example, the standard OCCT selection mechanism and AIS_Shape determine the following modes:

  • 0 – selection of the AIS_Shape;
  • 1 – selection of the vertices;
  • 2 – selection of the edges;
  • 3 – selection of the wires;
  • 4 – selection of the faces;
  • 5 – selection of the shells;
  • 6 – selection of the constituent solids.
visualization_image006.png
Hierarchy of references from sensitive entity to selectable object
visualization_image007.png
The principle of entities organization within the selectable object

Viewer selector

For each OCCT viewer there is a Viewer selector class instance. It provides a high-level API for the whole selection algorithm and encapsulates the processing of objects and sensitive entities for each mouse pick.

The viewer selector maintains activation and deactivation of selection modes, launches the algorithm, which detects candidate entities to be picked, and stores its results, as well as implements an interface for keeping selection structures up-to-date.

Selection manager

Selection manager is a high-level API to manipulate selection of all displayed objects. It handles all viewer selectors, activates and deactivates selection modes for the objects in all or particular selectors, manages computation and update of selections for each object. Moreover, it keeps selection structures updated taking into account applied changes.

visualization_image008.png
The relations chain between viewer selector and selection manager

Algorithm

All three types of OCCT selection are implemented as a single concept, based on the search for overlap between frustum and sensitive entity through 3-level BVH tree traversal.

Selection Frustum

The first step of each run of selection algorithm is to build the selection frustum according to the currently activated selection type.

For the point or the rectangular selection the base of the frustum is a rectangle built in conformity with the pixel tolerance or the dimensions of a user-defined area, respectively. For the polyline selection, the polygon defined by the constructed line is triangulated and each triangle is used as the base for its own frustum. Thus, this type of selection uses a set of triangular frustums for overlap detection.

The frustum length is limited by near and far view volume planes and each plane is built parallel to the corresponding view volume plane.

visualization_image009.png
Rectangular frustum: a) after mouse move or click, b) after applying the rectangular selection
visualization_image010.png
Triangular frustum set: a) user-defined polyline, b) triangulation of the polygon based on the given polyline, c) triangular frustum based on one of the triangles

BVH trees

To maintain selection mechanism at the viewer level, a speedup structure composed of 3 BVH trees is used.

The first level tree is constructed of axis-aligned bounding boxes of each selectable object. Hence, the root of this tree contains the combination of all selectable boundaries even if they have no currently activated selections. Objects are added during the display of AIS_InteractiveObject and will be removed from this tree only when the object is destroyed. The 1st level BVH tree is build on demand simultaneously with the first run of the selection algorithm.

The second level BVH tree consists of all sensitive entities of one selectable object. The 2nd level trees are built automatically when the default mode is activated and rebuilt whenever a new selection mode is calculated for the first time.

The third level BVH tree is used for complex sensitive entities that contain many elements: for example, triangulations, wires with many segments, point sets, etc. It is built on demand for sensitive entities with under 800K sub-elements.

visualization_image022.png
Selection BVH tree hierarchy: from the biggest object-level (first) to the smallest complex entity level (third)

Stages of the algorithm

The algorithm includes pre-processing and three main stages.

  • Pre-processing – implies calculation of the selection frustum and its main characteristics.
  • First stage – traverse of the first level BVH tree.

After successful building of the selection frustum, the algorithm starts traversal of the object-level BVH tree. The nodes containing axis-aligned bounding boxes are tested for overlap with the selection frustum following the terms of separating axis theorem (SAT). When the traverse goes down to the leaf node, it means that a candidate object with possibly overlapping sensitive entities has been found. If no such objects have been detected, the algorithm stops and it is assumed that no object needs to be selected. Otherwise it passes to the next stage to process the entities of the found selectable.

  • Second stage – traverse of the second level BVH tree

At this stage it is necessary to determine if there are candidates among all sensitive entities of one object.

First of all, at this stage the algorithm checks if there is any transformation applied for the current object. If it has its own location, then the correspondingly transformed frustum will be used for further calculations. At the next step the nodes of the second level BVH tree of the given object are visited to search for overlapping leaves. If no such leafs have been found, the algorithm returns to the second stage. Otherwise it starts processing the found entities by performing the following checks:

  • activation check - the entity may be inactive at the moment as it belongs to deactivated selection;
  • tolerance check - current selection frustum may be too large for further checks as it is always built with the maximum tolerance among all activated entities. Thus, at this step the frustum may be scaled.

After these checks the algorithm passes to the last stage.

  • Third stage – overlap or inclusion test of a particular sensitive entity

If the entity is atomic, a simple SAT test is performed. In case of a complex entity, the third level BVH tree is traversed. The quantitative characteristics (like depth, distance to the center of geometry) of matched sensitive entities is analyzed and clipping planes are applied (if they have been set). The result of detection is stored and the algorithm returns to the second stage.

Packages and classes

Selection is implemented as a combination of various algorithms divided among several packages – SelectBasics, Select3D, SelectMgr and StdSelect.

SelectBasics

SelectBasics package contains basic classes and interfaces for selection. The most notable are:

Each custom sensitive entity must inherit at least SelectBasics_SensitiveEntity.

Select3D

Select3D package provides a definition of standard sensitive entities, such as:

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

Each basic sensitive entity inherits Select3D_SensitiveEntity, which is a child class of SelectBasics_SensitiveEntity.

The package also contains two auxiliary classes, Select3D_SensitivePoly and Select3D_SensitiveSet.

Select3D_SensitivePoly – describes an arbitrary point set and implements basic functions for selection. It is important to know that this class does not perform any internal data checks. Hence, custom implementations of sensitive entity inherited from Select3D_SensitivePoly must satisfy the terms of Separating Axis Theorem to use standard OCCT overlap detection methods.

Select3D_SensitiveSet – a base class for all complex sensitive entities that require the third level BVH usage. It implements traverse of the tree and defines an interface for the methods that check sub-entities.

SelectMgr

SelectMgr package is used to maintain the whole selection process. For this purpose, the package provides the following services:

  • activation and deactivation of selection modes for all selectable objects;
  • interfaces to compute selection mode of the object;
  • definition of selection filter classes;
  • keeping selection BVH data up-to-date.

A brief description of the main classes:

StdSelect

StdSelect package contains the implementation of some SelectMgr classes and tools for creation of selection structures. For example,

Examples of usage

The first code snippet illustrates the implementation of SelectMgr_SelectableObject::ComputeSelection() method in a custom interactive object. The method is used for computation of user-defined selection modes.

Let us assume it is required to make a box selectable in two modes – the whole shape (mode 0) and each of its edges (mode 1).

To select the whole box, the application can create a sensitive primitive for each face of the interactive object. In this case, all primitives share the same owner – the box itself.

To select box's edge, the application must create one sensitive primitive per edge. Here all sensitive entities cannot share the owner since different geometric primitives must be highlighted as the result of selection procedure.

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

The algorithms for creating selection structures store sensitive primitives in SelectMgr_Selection instance. Each SelectMgr_Selection sequence in the list of selections of the object must correspond to a particular selection mode.

To describe the decomposition of the object into selectable primitives, a set of ready-made sensitive entities is supplied in Select3D package. Custom sensitive primitives can be defined through inheritance from SelectBasics_SensitiveEntity.

To make custom interactive objects selectable or customize selection modes of existing objects, the entity owners must be defined. They must inherit SelectMgr_EntityOwner interface.

Selection structures for any interactive object are created in SelectMgr_SelectableObject::ComputeSelection() method.

The example below shows how computation of different selection modes of the topological shape can be done using standard OCCT mechanisms, implemented in StdSelect_BRepSelectionTool.

1 void MyInteractiveObject::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
2  const Standard_Integer theMode)
3 {
4  switch (theMode)
5  {
6  case 0:
7  StdSelect_BRepSelectionTool::Load (theSelection, this, myTopoDSShape, TopAbs_SHAPE);
8  break;
9  case 1:
10  StdSelect_BRepSelectionTool::Load (theSelection, this, myTopoDSShape, TopAbs_VERTEX);
11  break;
12  case 2:
13  StdSelect_BRepSelectionTool::Load (theSelection, this, myTopoDSShape, TopAbs_EDGE);
14  break;
15  case 3:
16  StdSelect_BRepSelectionTool::Load (theSelection, this, myTopoDSShape, TopAbs_WIRE);
17  break;
18  case 4:
19  StdSelect_BRepSelectionTool::Load (theSelection, this, myTopoDSShape, TopAbs_FACE);
20  break;
21  }
22 }

The StdSelect_BRepSelectionTool class provides a high level API for computing sensitive entities of the given type (for example, face, vertex, edge, wire and others) using topological data from the given TopoDS_Shape.

The traditional way of highlighting selected entity owners adopted by Open CASCADE Technology assumes that each entity owner highlights itself on its own. This approach has two drawbacks:

  • each entity owner has to maintain its own Prs3d_Presentation object, that results in a large memory overhead for thousands of owners;
  • drawing selected owners one by one is not efficient from the OpenGL usage viewpoint.

Therefore, to overcome these limitations, OCCT has an alternative way to implement the highlighting of a selected presentation. Using this approach, the interactive object itself will be responsible for the highlighting, not the entity owner.

On the basis of SelectMgr_EntityOwner::IsAutoHilight() return value, AIS_LocalContext object either uses the traditional way of highlighting (in case if IsAutoHilight() returns true) or groups such owners according to their selectable objects and finally calls SelectMgr_SelectableObject::HilightSelected() or SelectMgr_SelectableObject::ClearSelected(), passing a group of owners as an argument.

Hence, an application can derive its own interactive object and redefine virtual methods HilightSelected(), ClearSelected() and HilightOwnerWithColor() from SelectMgr_SelectableObject. SelectMgr_SelectableObject::GetHilightPresentation and SelectMgr_SelectableObject::GetSelectPresentation methods can be used to optimize filling of selection and highlight presentations according to the user's needs.

The AIS_InteractiveContext::HighlightSelected() method can be used for efficient redrawing of the selection presentation for a given interactive object from an application code.

After all the necessary sensitive entities are computed and packed in SelectMgr_Selection instance with the corresponding owners in a redefinition of SelectMgr_SelectableObject::ComputeSelection() method, it is necessary to register the prepared selection in SelectMgr_SelectionManager through the following steps:

After these steps, the selection manager of the created interactive context will contain the given object and its selection entities, and they will be involved in the detection procedure.

The code snippet below illustrates the above steps. It also contains the code to start the detection procedure and parse the results of selection.

1 // Suppose there is an instance of class InteractiveBox from the previous sample.
2 // It contains an implementation of method InteractiveBox::ComputeSelection() for selection
3 // modes 0 (whole box must be selected) and 1 (edge of the box must be selectable)
4 Handle(InteractiveBox) aBox;
5 
6 // Assume there is a created interactive context
7 const Handle(AIS_InteractiveContext)& aContext = GetContext();
8 // To prevent automatic activation of the default selection mode
9 aContext->SetAutoActivateSelection (Standard_False);
10 
11 aContext->Display (aBox);
12 
13 // Load a box to the selection manager without computation of any selection mode
14 aContext->Load (aBox, -1, Standard_True);
15 // Activate edge selection
16 aContext->Activate (aBox, 1);
17 
18 // Run the detection mechanism for activated entities in the current mouse coordinates and
19 // in the current view. Detected owners will be highlighted with context highlight color
20 aContext->MoveTo (aXMousePos, aYMousePos, myView);
21 // Select the detected owners
22 aContext->Select();
23 // Iterate through the selected owners
24 for (aContext->InitSelected(); aContext->MoreSelected() && !aHasSelected; aContext->NextSelected())
25 {
26  Handle(AIS_InteractiveObject) anIO = aContext->SelectedInteractive();
27 }
28 
29 // deactivate all selection modes for aBox1
30 aContext->Deactivate (aBox1);

It is also important to know, that there are 2 types of detection implemented for rectangular selection in OCCT:

  • inclusive detection. In this case the sensitive primitive is considered detected only when all its points are included in the area defined by the selection rectangle;
  • overlap detection. In this case the sensitive primitive is considered detected when it is partially overlapped by the selection rectangle.

The standard OCCT selection mechanism uses inclusion detection by default. To change this, use the following code:

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

Application Interactive Services

Introduction

Application Interactive Services allow managing presentations and dynamic selection in a viewer in a simple and transparent manner.

The central entity for management of visualization and selections is the Interactive Context. It is connected to the main viewer (and if need be, the trash bin viewer). It has two operating modes: the Neutral Point and the local visualization and selection context.

The neutral point, which is the default mode, allows easily visualizing and selecting interactive objects loaded into the context.

Local Contexts can be opened to prepare and use a temporary selection environment without disturbing the neutral point. It is possible to choose the interactive objects, which you want to act on, the selection modes, which you want to activate, and the temporary visualizations, which you will execute.

When the operation is finished, you close the current local context and return to the state in which you were before opening it (neutral point or previous local context).

Interactive Objects are the entities, which are visualized and selected. You can use classes of standard interactive objects for which all necessary functions have already been programmed, or you can implement your own classes of interactive objects, by respecting a certain number of rules and conventions described below.

visualization_image016.png

An Interactive Object is a "virtual" entity, which can be presented and selected. An Interactive Object can have a certain number of specific graphic attributes, such as visualization mode, color and material.

When an Interactive Object is visualized, the required graphic attributes are taken from its own Drawer if it has the required custom attributes or otherwise from the context drawer.

visualization_image017.png

It can be necessary to filter the entities to be selected. Consequently there are Filter entities, which allow refining the dynamic detection context. Some of these filters can be used at the Neutral Point, others only in an open local context. It is possible to program custom filters and load them into the interactive context.

Interactive objects

Entities which are visualized and selected in the AIS viewer are objects. They connect the underlying reference geometry of a model to its graphic representation in AIS. You can use the predefined OCCT classes of standard interactive objects, for which all necessary functions have already been programmed, or, if you are an advanced user, you can implement your own classes of interactive objects.

Presentations

An interactive object can have as many presentations as its creator wants to give it.

3D presentations are managed by PresentationManager3D. As this is transparent in AIS, the user does not have to worry about it.

A presentation is identified by an index and by the reference to the Presentation Manager which it depends on.

By convention, the default mode of representation for the Interactive Object has index 0.

visualization_image018.png

Calculation of different presentations of an interactive object is done by the Compute functions inheriting from PrsMgr_ PresentableObject::Compute functions. They are automatically called by PresentationManager at a visualization or an update request.

If you are creating your own type of interactive object, you must implement the Compute function in one of the following ways:

For 3D:

1 void PackageName_ClassName::Compute
2  (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
3  const Handle(Prs3d_Presentation)& aPresentation,
4  const Standard_Integer aMode = 0);

#### For hidden line removal (HLR) mode in 3D:

1 void PackageName_ClassName::Compute
2  (const Handle(Prs3d_Projector)& aProjector,
3  const Handle(Prs3d_Presentation)& aPresentation);

Hidden Line Removal

The view can have two states: the normal mode or the computed mode (Hidden Line Removal mode). When the latter is active, the view looks for all presentations displayed in the normal mode, which have been signalled as accepting HLR mode. An internal mechanism allows calling the interactive object's own Compute, that is projector function.

By convention, the Interactive Object accepts or rejects the representation of HLR mode. It is possible to make this declaration in one of two ways:

AIS_Shape class is an example of an interactive object that supports HLR representation. It supports two types of the HLR algorithm:

  • the polygonal algorithm based on the shape's triangulation;
  • the exact algorithm that works with the shape's real geometry.

The type of the HLR algorithm is stored in AIS_Drawer of the shape. It is a value of the Prs3d_TypeOfHLR enumeration and can be set to:

  • Prs3d_TOH_PolyAlgo for a polygonal algorithm;
  • Prs3d_TOH_Algo for an exact algorithm;
  • Prs3d_TOH_NotSet if the type of algorithm is not set for the given interactive object instance.

The type of the HLR algorithm used for AIS_Shape can be changed by calling the AIS_Shape::SetTypeOfHLR() method.

The current HLR algorithm type can be obtained using AIS_Shape::TypeOfHLR() method is to be used.

These methods get the value from the drawer of AIS_Shape. If the HLR algorithm type in the AIS_Drawer is set to Prs3d_TOH_NotSet, the AIS_Drawer gets the value from the default drawer of AIS_InteractiveContext.

So it is possible to change the default HLR algorithm used by all newly displayed interactive objects. The value of the HLR algorithm type stored in the context drawer can be Prs3d_TOH_Algo or Prs3d_TOH_PolyAlgo. The polygonal algorithm is the default one.

Presentation modes

There are four types of interactive objects in AIS:

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

Inside these categories, additional characterization is available by means of a signature (an index.) By default, the interactive object has a NONE type and a signature of 0 (equivalent to NONE.) If you want to give a particular type and signature to your interactive object, you must redefine two virtual functions:

Note that some signatures are already used by "standard" objects provided in AIS (see the List of Standard Interactive Object Classes.

The interactive context can have a default mode of representation for the set of interactive objects. This mode may not be accepted by a given class of objects.

Consequently, to get information about this class it is necessary to use virtual function AIS_InteractiveObject::AcceptDisplayMode.

Display Mode

The functions AIS_InteractiveContext::SetDisplayMode and AIS_InteractiveContext::UnsetDisplayMode allow setting a custom display mode for an objects, which can be different from that proposed by the interactive context.

Highlight Mode

At dynamic detection, the presentation echoed by the Interactive Context, is by default the presentation already on the screen.

The functions AIS_InteractiveObject::SetHilightMode and AIS_InteractiveObject::UnSetHilightMode allow specifying the display mode used for highlighting (so called highlight mode), which is valid independently from the active representation of the object. It makes no difference whether this choice is temporary or definitive.

Note that the same presentation (and consequently the same highlight mode) is used for highlighting detected objects and for highlighting selected objects, the latter being drawn with a special selection color (refer to the section related to Interactive Context services).

For example, you want to systematically highlight the wireframe presentation of a shape - non regarding if it is visualized in wireframe presentation or with shading. Thus, you set the highlight mode to 0 in the constructor of the interactive object. Do not forget to implement this representation mode in the Compute functions.

Infinite Status

If you do not want an object to be affected by a FitAll view, you must declare it infinite; you can cancel its "infinite" status using AIS_InteractiveObject::SetInfiniteState and AIS_InteractiveObject::IsInfinite functions.

Let us take for example the class called IShape representing an interactive object :

1 myPk_IShape::myPK_IShape
2  (const TopoDS_Shape& SH, PrsMgr_TypeOfPresentation aType):
3  AIS_InteractiveObject(aType), myShape(SH), myDrwr(new AIS_Drawer()) {SetHilightMode(0);}
4 void myPk_IShape::Compute
5  (const Handle(PrsMgr_PresentationManager3d) & PM,
6  const Handle(Prs3d_Presentation)& P,
7  const Standard_Integer TheMode)
8 {
9  switch (TheMode){
10  case 0:
11  StdPrs_WFDeflectionShape::Add (P,myShape,myDrwr); //algo for calculation of wireframe presentation break;
12  case 1:
13  StdPrs_ShadedShape::Add (P,myShape,myDrwr); //algo for calculation of shading presentation.
14  break;
15  }
16 }
17 void myPk_IsShape::Compute
18  (const Handle(Prs3d_Projector)& Prj,
19  const Handle(Prs3d_Presentation) P)
20 {
21  StdPrs_HLRPolyShape::Add(P,myShape,myDrwr);
22  //Hidden line mode calculation algorithm
23 }

Selection

An interactive object can have an indefinite number of selection modes, each representing a "decomposition" into sensitive primitives. Each primitive has an owner (SelectMgr_EntityOwner) which allows identifying the exact interactive object or shape which has been detected (see Selection chapter).

The set of sensitive primitives, which correspond to a given mode, is stocked in a selection (SelectMgr_Selection).

Each selection mode is identified by an index. By convention, the default selection mode that allows us to grasp the interactive object in its entirety is mode 0. However, it can be modified in the custom interactive objects using method SelectMgr_SelectableObject::setGlobalSelMode().

The calculation of selection primitives (or sensitive entities) is done by the intermediary of a virtual function, ComputeSelection. It should be implemented for each type of interactive object that is assumed to have different selection modes using the function AIS_ConnectedInteractive::ComputeSelection.

A detailed explanation of the mechanism and the manner of implementing this function has been given in Selection chapter.

There are some examples of selection mode calculation for the most widely used interactive object in OCCT – AIS_Shape (selection by vertex, by edges, etc). To create new classes of interactive objects with the same selection behavior as AIS_Shape – such as vertices and edges – you must redefine the virtual function AIS_InteractiveObject::AcceptShapeDecomposition.

You can change the default selection mode index of a custom interactive object using the following functions:

You also can temporarily change the priority of some interactive objects for selection of the global mode to facilitate their graphic detection using the following functions:

Graphic attributes

Graphic attributes manager, or AIS Drawer, stores graphic attributes for specific interactive objects and for interactive objects controlled by interactive context.

Initially, all drawer attributes are filled out with the predefined values which will define the default 3D object appearance.

When an interactive object is visualized, the required graphic attributes are first taken from its own drawer if one exists, or from the context drawer if no specific drawer for that type of object exists.

Keep in mind the following points concerning graphic attributes:

  • Each interactive object can have its own visualization attributes.
  • The set of graphic attributes of an interactive object is stocked in an AIS_Drawer, which is only a Prs3d_Drawer with the possibility of a link to another drawer
  • By default, the interactive object takes the graphic attributes of the context in which it is visualized (visualization mode, deflection values for the calculation of presentations, number of isoparameters, color, type of line, material, etc.)
  • In the AIS_InteractiveObject abstract class, standard attributes including color, line thickness, material, and transparency have been privileged. Consequently, there is a certain number of virtual functions, which allow acting on these attributes. Each new class of interactive object can redefine these functions and change the behavior of the class.
visualization_image019.png
Figure 13. Redefinition of virtual functions for changes in AIS_Point
visualization_image020.png
Figure 14. Redefinition of virtual functions for changes in AIS_Shape.
The following virtual functions provide settings for color, width, material and transparency:

For other types of attribute, it is appropriate to change the Drawer of the object directly using:

It is important to know which functions may imply the recalculation of presentations of the object.

If the presentation mode of an interactive object is to be updated, a flag from PrsMgr_PresentableObject indicates this.

The mode can be updated using the functions Display and Redisplay in AIS_InteractiveContext.

Complementary Services

When you use complementary services for interactive objects, pay special attention to the cases mentioned below.

Change the location of an interactive object

The following functions allow temporarily "moving" the representation and selection of Interactive Objects in a view without recalculation.

Connect an interactive object to an applicative entity

Each Interactive Object has functions that allow attributing it an Owner in form of a Transient.

An interactive object can therefore be associated or not with an applicative entity, without affecting its behavior.

Resolving coincident topology

Due to the fact that the accuracy of three-dimensional graphics coordinates has a finite resolution the elements of topological objects can coincide producing the effect of "popping" some elements one over another.

To the problem when the elements of two or more Interactive Objects are coincident you can apply the polygon offset. It is a sort of graphics computational offset, or depth buffer offset, that allows you to arrange elements (by modifying their depth value) without changing their coordinates. The graphical elements that accept this kind of offsets are solid polygons or displayed as boundary lines and points. The polygons could be displayed as lines or points by setting the appropriate interior style.

The method AIS_InteractiveObject::SetPolygonOffsets (const Standard_Integer aMode, const Standard_Real aFactor, const Standard_Real aUnits) allows setting up the polygon offsets.

The parameter aMode can contain various combinations of Aspect_PolygonOffsetMode enumeration elements:

  • Aspect_POM_None
  • Aspect_POM_Off
  • Aspect_POM_Fill
  • Aspect_POM_Line
  • Aspect_POM_Point
  • Aspect_POM_All

The combination of these elements defines the polygon display modes that will use the given offsets. You can switch off the polygon offsets by passing Aspect_POM_Off. Passing Aspect_POM_None allows changing the aFactor and aUnits values without changing the mode. If aMode is different from Aspect_POM_Off, the aFactor and aUnits arguments are used by the graphics renderer to calculate the depth offset value:

1 offset = aFactor * m + aUnits * r

where m is the maximum depth slope for the currently displayed polygons, r is the minimum depth resolution (implementation-specific).

Negative offset values move polygons closer to the viewer while positive values shift polygons away.

Warning

This method has a side effect – it creates its own shading aspect if not yet created, so it is better to set up the object shading aspect first.

You can use the following functions to obtain the current settings for polygon offsets:

1 void AIS_InteractiveObject::PolygonOffsets
2  (Standard_Integer &aMode,
3  Standard_Real &aFactor,
4  Standard_Real &aUnits)
5 Standard_Boolean AIS_InteractiveObject::HasPolygonOffsets()

The same operation could be performed for the interactive object known by the AIS_InteractiveContext with the following methods:

1 void AIS_InteractiveContext::SetPolygonOffsets
2  (const Handle(AIS_InteractiveObject) &anObj,
3  const Standard_Integer aMode,
4  const Standard_Real aFactor,
5  const Standard_Real aUnits)
6 void AIS_InteractiveContext::PolygonOffsets
7  (const Handle(AIS_InteractiveObject) &anObj,
8  Standard_Integer &aMode,
9  Standard_Real &aFactor,
10  Standard_Real &aUnits)
11 Standard_Boolean AIS_InteractiveContext::HasPolygonOffsets
12  (const Handle(AIS_InteractiveObject) &anObj)

Interactive Context

Rules

The Interactive Context allows managing in a transparent way the graphic and selectable behavior of interactive objects in one or more viewers. Most functions which allow modifying the attributes of interactive objects, and which were presented in the preceding chapter, will be looked at again here.

There is one essential rule to follow: the modification of an interactive object, which is already known by the Context, must be done using Context functions. You can only directly call the functions available for an interactive object if it has not been loaded into an Interactive Context.

1 Handle (AIS_Shape) TheAISShape = new AIS_Shape (ashape);
2  myIntContext->Display(TheAISShape);
3  myIntContext->SetDisplayMode(TheAISShape ,1);
4  myIntContext->SetColor(TheAISShape,Quantity_NOC_RED);

You can also write

1 Handle (AIS_Shape) TheAISShape = new AIS_Shape (ashape);
2  TheAISShape->SetColor(Quantity_NOC_RED);
3  TheAISShape->SetDisplayMode(1);
4  myIntContext->Display(TheAISShape);

Groups of functions

Neutral Point and Local Context constitute the two operating modes or states of the Interactive Context, which is the central entity which pilots visualizations and selections.

The Neutral Point, which is the default mode, allows easily visualizing and selecting interactive objects, which have been loaded into the context. Opening Local contexts allows preparing and using a temporary selection environment without disturbing the neutral point.

A set of functions allows choosing the interactive objects which you want to act on, the selection modes which you want to activate, and the temporary visualizations which you will execute. When the operation is finished, you close the current local context and return to the state in which you were before opening it (neutral point or previous local context).

The Interactive Context is composed of many functions, which can be conveniently grouped according to the theme:

  • management proper to the context;
  • management in the local context;
  • presentations and selection in open/closed context;
  • selection strictly speaking.

Some functions can only be used in open Local Context; others in closed local context; others do not have the same behavior in one state as in the other.

Management of the Interactive Context

The Interactive Context is made up of a Principal Viewer and, optionally, a trash bin or Collector Viewer.

An interactive object can have a certain number of specific graphic attributes, such as visualization mode, color, and material. Correspondingly, the interactive context has a set of graphic attributes, the Drawer, which is valid by default for the objects it controls.

When an interactive object is visualized, the required graphic attributes are first taken from the object's own Drawer if one exists, or from the context drawer for the others.

The following adjustable settings allow personalizing the behavior of presentations and selections:

  • Default Drawer, containing all the color and line attributes which can be used by interactive objects, which do not have their own attributes.
  • Default Visualization Mode for interactive objects. By default: mode 0 ;
  • Highlight color of entities detected by mouse movement. By default: Quantity_NOC_CYAN1;
  • Pre-selection color. By default: Quantity_NOC_GREEN;
  • Selection color (when you click on a detected object). By default: Quantity_NOC_GRAY80;
  • Sub-Intensity color. By default: Quantity_NOC_GRAY40.

All of these settings can be modified by functions proper to the Context.

When you change a graphic attribute pertaining to the Context (visualization mode, for example), all interactive objects, which do not have the corresponding appropriate attribute, are updated.

Let us examine the case of two interactive objects: obj1 and obj2:

1 TheCtx->Display(obj1,Standard_False); // False = no viewer update
2 TheCtx->Display(obj2,Standard_True); // True = viewer update
3 TheCtx->SetDisplayMode(obj1,3,Standard_False);
4 TheCtx->SetDisplayMode(2);
5 // obj2 is visualised in mode 2 (if it accepts this mode)
6 // obj1 stays visualised in its mode 3.

PresentationManager3D and Selector3D, which manage the presentation and selection of present interactive objects, are associated to the main Viewer. The same is true of the optional Collector.

Local Context

Rules and Conventions

  • Opening a local context allows preparing an environment for temporary presentations and selections, which will disappear once the local context is closed.
  • It is possible to open several local contexts, but only the last one will be active.
  • When you close a local context, the previous one, which is still on the stack, is activated again. If none is left, you return to Neutral Point.
  • Each local context has an index created when the context opens. You should close the local context, which you have opened.

The interactive object, which is used the most by applications, is AIS_Shape. Consequently, standard functions are available which allow you to easily prepare selection operations on the constituent elements of shapes (selection of vertices, edges, faces etc) in an open local context. The selection modes specific to "Shape" type objects are called Standard Activation Mode. These modes are only taken into account in open local context and only act on interactive objects which have redefined the virtual function AcceptShapeDecomposition() so that it returns TRUE.

  • Objects, which are temporarily in a local context, are not recognized by other local contexts a priori. Only objects visualized in Neutral Point are recognized by all local contexts.
  • The state of a temporary interactive object in a local context can only be modified while another local context is open.

Warning

The specific modes of selection only concern the interactive objects, which are present in the Main Viewer. In the Collector, you can only locate interactive objects, which answer positively to the positioned filters when a local context is open, however, they are never decomposed in standard mode.

Management of Local Context

The local context can be opened using method AIS_InteractiveContext::OpenLocalContext. The following options are available:

  • UseDisplayedObjects: allows loading the interactive objects visualized at Neutral Point in the opened local context. If FALSE, the local context is empty after being opened. If TRUE, the objects at Neutral Point are modified by their default selection mode.
  • AllowShapeDecomposition: AIS_Shape allows or prevents decomposition in standard shape location mode of objects at Neutral Point, which are type-privileged (see Selection chapter). This Flag is only taken into account when UseDisplayedObjects is TRUE.
  • AcceptEraseOfObjects: authorizes other local contexts to erase the interactive objects present in this context. This option is rarely used. The last option has no current use.

This function returns the index of the created local context. It should be kept and used when the context is closed.

To load objects visualized at Neutral Point into a local context or remove them from it use methods

1 AIS_InteractiveContext::UseDisplayedObjects
2 AIS_InteractiveContext::NotUseDisplayedObjects

Closing Local Contexts is done by:

1 AIS_InteractiveContext::CloseLocalContext
2 AIS_InteractiveContext::CloseAllContexts

Warning When the index is not specified in the first function, the current Context is closed. This option can be dangerous, as other Interactive Functions can open local contexts without necessarily warning the user. For greater security, you have to close the context with the index given on opening.

To get the index of the current context, use function AIS_InteractiveContext::IndexOfCurrentLocal. It allows closing all open local contexts at one go. In this case, you find yourself directly at Neutral Point.

When you close a local context, all temporary interactive objects are deleted, all selection modes concerning the context are canceled, and all content filters are emptied.

Presentation in a Neutral Point

You must distinguish between the Neutral Point and the Open Local Context states. Although the majority of visualization functions can be used in both situations, their behavior is different.

Neutral Point should be used to visualize the interactive objects, which represent and select an applicative entity. Visualization and Erasing orders are straightforward:

1 AIS_InteractiveContext::Display
2  (const Handle(AIS_InteractiveObject)& anIobj,
3  const Standard_Boolean updateviewer=Standard_True);
4 
5 AIS_InteractiveContext::Display
6  (const Handle(AIS_InteractiveObject)& anIobj,
7  const Standard_Integer amode,
8  const Standard_Integer aSelectionMode,
9  const Standard_Boolean updateviewer = Standard_True,
10  const Standard_Boolean allowdecomposition = Standard_True);
11 
12  AIS_InteractiveContext::Erase
13  AIS_InteractiveContext::EraseMode
14  AIS_InteractiveContext::ClearPrs
15  AIS_InteractiveContext::Redisplay
16  AIS_InteractiveContext::Remove
17  AIS_InteractiveContext::EraseAll
18  AIS_InteractiveContext::Hilight
19  AIS_InteractiveContext::HilightWithColor

Bear in mind the following points:

  • It is recommended to display and erase interactive objects when no local context is opened, and open a local context for local selection only.
  • The first Display function among the two ones available in InteractiveContext visualizes the object in its default mode (set with help of SetDisplayMode() method of InteractiveObject prior to Display() call), or in the default context mode, if applicable. If it has neither, the function displays it in 0 presentation mode. The object's default selection mode is automatically activated (0 mode by convention).
  • Activating the displayed object by default can be turned off with help of SetAutoActivateSelection() method. This might be efficient if you are not interested in selection immediately after displaying an object.
  • The second Display function should only be used in Neutral Point to visualize a supplementary mode for the object, which you can erase by EraseMode (...). You activate the selection mode. This is passed as an argument. By convention, if you do not want to activate a selection mode, you must set the SelectionMode argument to -1. This function is especially interesting in open local context, as we will see below.
  • In Neutral Point, it is not advisable to activate other selection modes than the default selection one. It is preferable to open a local context in order to activate particular selection modes.
  • When you call Erase(Interactive object) function, the PutIncollector argument, which is FALSE by default, allows you to visualize the object directly in the Collector and makes it selectable (by activation of 0 mode). You can nonetheless block its passage through the Collector by changing the value of this option. In this case, the object is present in the Interactive Context, but is not seen anywhere.
  • Erase() with putInCollector = Standard_True might be slow as it recomputes the object presentation in the Collector. Set putInCollector to Standard_False if you simply want to hide the object's presentation temporarily.
  • Visualization attributes and graphic behavior can be modified through a set of functions similar to those for the interactive object (color, thickness of line, material, transparency, locations, etc.) The context then manages immediate and deferred updates.
  • Call Remove() method of InteractiveContext as soon as the interactive object is no longer needed and you want to destroy it.. Otherwise, references to InteractiveObject are kept by InteractiveContext, and the Object is not destroyed, which results in memory leaks. In general, if the presentation of an interactive object can be computed quickly, it is recommended to Remove() it instead of using Erase() method.

Presentation in the Local Context

In open local context, the Display functions presented above can be as well.

WARNING

The function AIS_InteractiveObject::Display automatically activates the object's default selection mode. When you only want to visualize an Interactive Object in open Context, you must call the function AIS_InteractiveContext::Display.

You can activate or deactivate specific selection modes in the local open context in several different ways: Use the Display functions with the appropriate modes.

1 AIS_InteractiveContext::ActivateStandardMode
2 //can be used only if a Local Context is opened.
3 AIS_InteractiveContext::DeactivateStandardMode
4 AIS_InteractiveContext::ActivatedStandardModes
5 AIS_InteractiveContext::SetShapeDecomposition

This activates the corresponding selection mode for all objects in Local Context, which accept decomposition into sub-shapes. Every new Object which has been loaded into the interactive context and which meets the decomposition criteria is automatically activated according to these modes.

WARNING

If you have opened a local context by loading an object with the default options (AllowShapeDecomposition = Standard_True), all objects of the "Shape" type are also activated with the same modes. You can change the state of these "Standard" objects by using SetShapeDecomposition(Status).

Load an interactive object by the function AIS_InteractiveContext::Load.

This function allows loading an Interactive Object whether it is visualized or not with a given selection mode, and/or with the necessary decomposition option. If AllowDecomp=TRUE and obviously, if the interactive object is of the "Shape" type, these "standard" selection modes will be automatically activated as a function of the modes present in the Local Context.

Use AIS_InteractiveContext::Activate and AIS_InteractiveContext::Deactivate to directly activate/deactivate selection modes on an object.

Filters

To define an environment of dynamic detection, you can use standard filter classes or create your own. A filter questions the owner of the sensitive primitive in local context to determine if it has the desired qualities. If it answers positively, it is kept. If not, it is rejected.

The root class of objects is SelectMgr_Filter. The principle behind it is straightforward: a filter tests to see whether the owners (SelectMgr_EntityOwner) detected in mouse position by the Local context selector answer OK. If so, it is kept, otherwise it is rejected.

You can create a custom class of filter objects by implementing the deferred function IsOk():

1 class MyFilter : public SelectMgr_Filter { };
2 virtual Standard_Boolean MyFilter::IsOk
3  (const Handle(SelectMgr_EntityOwner)& anObj) const = 0;

In SelectMgr, there are also Composition filters (AND Filters, OR Filters), which allow combining several filters. In InteractiveContext , all filters that you add are stocked in an OR filter (which answers OK if at least one filter answers OK).

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

As there are specific behaviors on shapes, each new Filter class must, if necessary, redefine AIS_LocalContext::ActsOn function, which informs the Local Context if it acts on specific types of sub-shapes. By default, this function answers FALSE.

WARNING

Only type filters are activated in Neutral Point to make it possible to identify a specific type of visualized object. For filters to come into play, one or more object selection modes must be activated.

There are several functions to manipulate filters:

Example

1 myContext->OpenLocalContext(Standard_False);
2 // no object in neutral point is loaded
3 
4 myContext->ActivateStandardMode(TopAbs_Face);
5 //activates decomposition of shapes into faces.
6 Handle (AIS_Shape) myAIShape = new AIS_Shape ( ATopoShape);
7 
8 myContext->Display(myAIShape,1,-1,Standard_True,Standard_True);
9 
10 //shading visualization mode, no specific mode, authorization for decomposition into sub-shapes. At this Stage, myAIShape is decomposed into faces...
11 
12 Handle(StdSelect_FaceFilter) Fil1= new
13  StdSelect_FaceFilter(StdSelect_Revol);
14 Handle(StdSelect_FaceFilter) Fil2= new
15  StdSelect_FaceFilter(StdSelect_Plane);
16 
17 myContext->AddFilter(Fil1);
18 myContext->AddFilter(Fil2);
19 
20 //only faces of revolution or planar faces will be selected
21 
22 myContext->MoveTo( xpix,ypix,Vue);
23 // detects the mouse position

Selection in the Local Context

Dynamic detection and selection are put into effect in a straightforward way. There are only a few conventions and functions to be familiar with. The functions are the same in neutral point and in open local context:

Highlighting of detected and selected entities is automatically managed by the Interactive Context, whether you are in neutral point or Local Context. The Highlight colors are those dealt with above. You can nonetheless disconnect this automatic mode if you want to manage this part yourself :

1 AIS_InteractiveContext::SetAutomaticHilight
2 AIS_InteractiveContext::AutomaticHilight

If there is no open local context, the objects selected are called current objects. If there is a local context, they are called selected objects. Iterators allow entities to be recovered in either case. A set of functions allows manipulating the objects, which have been placed in these different lists.

WARNING

When a Local Context is open, you can select entities other than interactive objects (vertices, edges etc.) from decompositions in standard modes, or from activation in specific modes on specific interactive objects. Only interactive objects are stocked in the list of selected objects.

You can question the Interactive context by moving the mouse. The following functions can be used:

After using the Select and ShiftSelect functions in Neutral Point, you can explore the list of selections, referred to as current objects in this context. The following functions can be used:

In the Local Context, you can explore the list of selected objects available. The following functions can be used:

Example

1 myAISCtx->InitSelected();
2 while (myAISCtx->MoreSelected())
3  {
4  if (myAISCtx->HasSelectedShape)
5  {
6  TopoDS_Shape ashape = myAISCtx->SelectedShape();
7  // to be able to use the picked shape
8  }
9  else
10  {
11  Handle_AIS_InteractiveObject anyobj = myAISCtx->Interactive();
12  // to be able to use the picked interactive object
13  }
14 myAISCtx->NextSelected();
15 }

You have to ask whether you have selected a shape or an interactive object before you can recover the entity in the Local Context or in the iteration loop. If you have selected a Shape from TopoDS on decomposition in standard mode, the Interactive() function returns the interactive object, which provided the selected shape. Other functions allow you to manipulate the content of Selected or Current Objects:

You can highlight and remove highlighting from a current object, and empty the list of current objects using the following functions:

1 AIS_InteractiveContext::HilightCurrents
2 AIS_InteractiveContext::UnhilightCurrents
3 AIS_InteractiveContext::ClearCurrents

When you are in an open Local Context, you may need to keep "temporary" interactive objects. This is possible using the following functions:

  • AIS_InteractiveContext::KeepTemporary transfers the characteristics of the interactive object seen in its local context (visualization mode, etc.) to the neutral point. When the local context is closed, the object does not disappear.
  • AIS_InteractiveContext::SetSelectedCurrent allows the selected object to become the current object when you close the local context.

You can also want to use function AIS_InteractiveContext::ClearLocalContext to modify in a general way the state of the local context before continuing a selection (emptying objects, removing filters, standard activation modes).

Recommendations

The possibilities of use for local contexts are numerous depending on the type of operation that you want to perform:

  • working on all visualized interactive objects,
  • working on only a few objects,
  • working on a single object.

When you want to work on one type of entity, you should open a local context with the option UseDisplayedObjects set to FALSE. Some functions which allow you to recover the visualized interactive objects, which have a given Type, and Signature from the "Neutral Point" are:

1 AIS_InteractiveContext::DisplayedObjects (AIS_ListOfInteractive& aListOfIO) const;
2 AIS_InteractiveContext::DisplayedObjects (const AIS_KindOfInteractive WhichKind, const Standard_Integer WhichSignature;
3 AIS_ListOfInteractive& aListOfIO) const;

At this stage, you only have to load the functions Load, Activate, and so on.

When you open a Local Context with default options, you must keep the following points in mind:

  • The Interactive Objects visualized at Neutral Point are activated with their default selection mode. You must deactivate those, which you do not want to use.
  • The Shape Type Interactive Objects are automatically decomposed into sub-shapes when standard activation modes are launched.
  • The "temporary" Interactive Objects present in the Local Contexts are not automatically taken into account. You have to load them manually if you want to use them.

The stages could be the following:

  1. Open a Local Context with the right options;
  2. Load/Visualize the required complementary objects with the desired activation modes.
  3. Activate Standard modes if necessary
  4. Create its filters and add them to the Local Context
  5. Detect/Select/recover the desired entities
  6. Close the Local Context with the adequate index.

It is useful to create an interactive editor, to which you pass the Interactive Context. This allow setting up different contexts of selection/presentation according to the operation, which you want to perform.

Let us assume that you have visualized several types of interactive objects: AIS_Points, AIS_Axes, AIS_Trihedrons, and AIS_Shapes.

For your applicative function, you need an axis to create a revolved object. You could obtain this axis by identifying:

  • an axis which is already visualized,
  • 2 points,
  • a rectilinear edge on the shapes which are present,
  • a cylindrical face on the shapes (You will take the axis of this face)
1 myIHMEditor::myIHMEditor
2  (const Handle(AIS_InteractiveContext)& Ctx,
3  ....) :
4  myCtx(Ctx),
5  ...
6 {
7 }
8 
9 myIHMEditor::PrepareContext()
10 {
11 myIndex =myCtx->OpenLocalContext();
12 
13 //the filters
14 
15 Handle(AIS_SignatureFilter) F1 = new AIS_SignatureFilter(AIS_KOI_Datum,AIS_SD_Point);
16 //filter on the points
17 
18 Handle(AIS_SignatureFilter) F2 = new AIS_SignatureFilter(AIS_KOI_Datum,AIS_SD_Axis);
19 //filters on the axes.
20 
21 Handle(StdSelect_FaceFilter) F3 = new StdSelect_FaceFilter(AIS_Cylinder);
22 //cylindrical face filters
23 //...
24 // activation of standard modes on the shapes..
25 myCtx->ActivateStandardMode(TopAbs_FACE);
26 myCtx->ActivateStandardMode(TopAbs_VERTEX);
27 myCTX->Add(F1);
28 myCTX->Add(F2);
29 myCTX->Add(F3);
30 
31 // at this point, you can call the selection/detection function
32 }
33 
34 void myIHMEditor::MoveTo(xpix,ypix,Vue)
35 
36 { myCTX->MoveTo(xpix,ypix,vue);
37 // the highlight of what is detected is automatic.
38 }
39 Standard_Boolean myIHMEditor::Select()
40 {
41 // returns true if you should continue the selection
42  myCTX->Select();
43  myCTX->InitSelected();
44  if(myCTX->MoreSelected())
45  {
46  if(myCTX->HasSelectedShape())
47  { const TopoDS_Shape& sh = myCTX->SelectedShape();
48  if( vertex){
49  if(myFirstV...)
50  {
51  //if it is the first vertex, you stock it, then you deactivate the faces and only keep the filter on the points:
52  mypoint1 = ....;
53  myCtx->RemoveFilters();
54  myCTX->DeactivateStandardMode(TopAbs_FACE);
55  myCtx->Add(F1);
56  // the filter on the AIS_Points
57  myFirstV = Standard_False;
58  return Standard_True;
59  }
60  else
61  {
62  mypoint2 =...;
63  // construction of the axis return Standard_False;
64  }
65  }
66  else
67  {
68  //it is a cylindrical face : you recover the axis; visualize it; and stock it.
69  return Standard_False;
70  }
71  }
72  // it is not a shape but is no doubt a point.
73  else
74  {
75  Handle(AIS_InteractiveObject)
76  SelObj = myCTX->SelectedInteractive();
77  if(SelObj->Type()==AIS_KOI_Datum)
78  {
79  if(SelObj->Signature()==1)
80  {
81  if (firstPoint)
82  {
83  mypoint1 =...
84  return Standard_True;
85  }
86  else
87  {
88  mypoint2 = ...;
89  //construction of the axis, visualization, stocking
90  return Standard_False;
91  }
92  }
93 
94  else
95  {
96  // you have selected an axis; stock the axis
97  return Standard_False;
98  }
99  }
100  }
101  }
102  }
103 void myIHMEditor::Terminate()
104 {
105 myCtx->CloseLocalContext(myIndex);
106 ...
107 }

Standard Interactive Object Classes

Interactive Objects are selectable and viewable objects connecting graphic representation and the underlying reference geometry.

They are divided into four types:

  • the Datum – a construction geometric element;
  • the Relation – a constraint on the interactive shape and the corresponding reference geometry;
  • the Object – a topological shape or connection between shapes;
  • None – a token, that instead of eliminating the object, tells the application to look further until it finds an acceptable object definition in its generation.

Inside these categories, there is a possibility of additional characterization by means of a signature. The signature provides an index to the further characterization. By default, the Interactive Object has a None type and a signature of 0 (equivalent to None). If you want to give a particular type and signature to your interactive object, you must redefine the two virtual methods: Type and Signature.

Datum

The Datum groups together the construction elements such as lines, circles, points, trihedrons, plane trihedrons, planes and axes.

AIS_Point, AIS_Axis, AIS_Line, AIS_Circle, AIS_Plane and AIS_Trihedron have four selection modes:

  • mode 0 : selection of a trihedron;
  • mode 1 : selection of the origin of the trihedron;
  • mode 2 : selection of the axes;
  • mode 3 : selection of the planes XOY, YOZ, XOZ.

when you activate one of modes: 1 2 3 4, you pick AIS objects of type:

AIS_PlaneTrihedron offers three selection modes:

  • mode 0 : selection of the whole trihedron;
  • mode 1 : selection of the origin of the trihedron;
  • mode 2 : selection of the axes – same remarks as for the Trihedron.

For the presentation of planes and trihedra, the default unit of length is millimeter, and the default value for the representation of axes is 100. If you modify these dimensions, you must temporarily recover the object Drawer. From it, take the Aspects in which the values for length are stored (PlaneAspect for the plane, FirstAxisAspect for trihedra), and change these values inside these Aspects. Finally, recalculate the presentation.

Object

The Object type includes topological shapes, and connections between shapes.

AIS_Shape has three visualization modes :

  • mode 0 : Line (default mode)
  • mode 1 : Shading (depending on the type of shape)
  • mode 2 : Bounding Box

And at maximum seven selection modes, depending on the shape complexity:

  • mode 0 : selection of the AIS_Shape;
  • mode 1 : selection of the vertices;
  • mode 2 : selection of the edges;
  • mode 3 : selection of the wires;
  • mode 4 : selection of the faces;
  • mode 5 : selection of the shells;
  • mode 6 : selection of the constituent solids.
  • AIS_Triangulation is a simple interactive object for displaying triangular mesh contained in Poly_Triangulation container.
  • AIS_ConnectedInteractive is an Interactive Object connecting to another interactive object reference, and located elsewhere in the viewer makes it possible not to calculate presentation and selection, but to deduce them from your object reference.
  • AIS_ConnectedShape is an object connected to interactive objects having a shape; this class has the same decompositions as AIS_Shape. Furthermore, it allows a presentation of hidden parts, which are calculated automatically from the shape of its reference.
  • AIS_MultipleConnectedInteractive is an object connected to a list of interactive objects (which can also be Connected objects. It does not require memory hungry calculations of presentation)
  • AIS_MultipleConnectedShape is an interactive Object connected to a list of interactive objects having a Shape (AIS_Shape, AIS_ConnectedShape, AIS_MultipleConnectedShape). The presentation of hidden parts is calculated automatically.
  • AIS_TexturedShape is an Interactive Object that supports texture mapping. It is constructed as a usual AIS_Shape, but has additional methods that allow to map a texture on it.
  • MeshVS_Mesh is an Interactive Object that represents meshes, it has a data source that provides geometrical information (nodes, elements) and can be built up from the source data with a custom presentation builder.

The class AIS_ColoredShape allows using custom colors and line widths for TopoDS_Shape objects and their sub-shapes.

1 AIS_ColoredShape aColoredShape = new AIS_ColoredShape (theShape);
2 
3 // setup color of entire shape
4 aColoredShape->SetColor (Quantity_Color (Quantity_NOC_RED));
5 
6 // setup line width of entire shape
7 aColoredShape->SetWidth (1.0);
8 
9 // set transparency value
10 aColoredShape->SetTransparency (0.5);
11 
12 // customize color of specified sub-shape
13 aColoredShape->SetCustomColor (theSubShape, Quantity_Color (Quantity_NOC_BLUE1));
14 
15 // customize line width of specified sub-shape
16 aColoredShape->SetCustomWidth (theSubShape, 0.25);

The presentation class AIS_PointCloud can be used for efficient drawing of large arbitrary sets of colored points. It uses Graphic3d_ArrayOfPoints to pass point data into OpenGl graphic driver to draw a set points as an array of "point sprites". The point data is packed into vertex buffer object for performance.

  • The type of point marker used to draw points can be specified as a presentation aspect.
  • The presentation provides selection by a bounding box of the visualized set of points. It supports two display / highlighting modes: points or bounding box.
point_cloud.png
A random colored cloud of points

Example:

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

The draw command vpointcloud builds a cloud of points from shape triangulation. This command can also draw a sphere surface or a volume with a large amount of points (more than one million).

Relations

The Relation is made up of constraints on one or more interactive shapes and the corresponding reference geometry. For example, you might want to constrain two edges in a parallel relation. This constraint is considered as an object in its own right, and is shown as a sensitive primitive. This takes the graphic form of a perpendicular arrow marked with the || symbol and lying between the two edges.

The following relations are provided by AIS:

The list of relations is not exhaustive.

Dimensions

MeshVS_Mesh

MeshVS_Mesh is an Interactive Object that represents meshes. This object differs from the AIS_Shape as its geometrical data is supported by the data source MeshVS_DataSource that describes nodes and elements of the object. As a result, you can provide your own data source.

However, the DataSource does not provide any information on attributes, for example nodal colors, but you can apply them in a special way – by choosing the appropriate presentation builder.

The presentations of MeshVS_Mesh are built with the presentation builders MeshVS_PrsBuilder. You can choose between the builders to represent the object in a different way. Moreover, you can redefine the base builder class and provide your own presentation builder.

You can add/remove builders using the following methods:

1 MeshVS_Mesh::AddBuilder (const Handle (MeshVS_PrsBuilder) &Builder, Standard_Boolean TreatAsHilighter)
2 MeshVS_Mesh::RemoveBuilder (const Standard_Integer Index)
3 MeshVS_Mesh::RemoveBuilderById (const Standard_Integer Id)

There is a set of reserved display and highlighting mode flags for MeshVS_Mesh. Mode value is a number of bits that allows selecting additional display parameters and combining the following mode flags, which allow displaying mesh in wireframe, shading and shrink modes:

1 MeshVS_DMF_WireFrame
2 MeshVS_DMF_Shading
3 MeshVS_DMF_Shrink

It is also possible to display deformed mesh in wireframe, shading or shrink modes usung :

1 MeshVS_DMF_DeformedPrsWireFrame
2 MeshVS_DMF_DeformedPrsShading
3 MeshVS_DMF_DeformedPrsShrink

The following methods represent different kinds of data :

1 MeshVS_DMF_VectorDataPrs
2 MeshVS_DMF_NodalColorDataPrs
3 MeshVS_DMF_ElementalColorDataPrs
4 MeshVS_DMF_TextDataPrs
5 MeshVS_DMF_EntitiesWithData

The following methods provide selection and highlighting :

1 MeshVS_DMF_SelectionPrs
2 MeshVS_DMF_HilightPrs

MeshVS_DMF_User is a user-defined mode.

These values will be used by the presentation builder. There is also a set of selection modes flags that can be grouped in a combination of bits:

  • 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

Such an object, for example, can be used for displaying the object and stored in the STL file format:

1 // read the data and create a data source
2 Handle (StlMesh_Mesh) aSTLMesh = RWStl::ReadFile (aFileName);
3 Handle (XSDRAWSTLVRML_DataSource) aDataSource = new XSDRAWSTLVRML_DataSource (aSTLMesh);
4 
5 // create mesh
6 Handle (MeshVS_Mesh) aMesh = new MeshVS();
7 aMesh->SetDataSource (aDataSource);
8 
9 // use default presentation builder
10 Handle (MeshVS_MeshPrsBuilder) aBuilder = new MeshVS_MeshPrsBuilder (aMesh);
11 aMesh->AddBuilder (aBuilder, Standard_True);

MeshVS_NodalColorPrsBuilder allows representing a mesh with a color scaled texture mapped on it. To do this you should define a color map for the color scale, pass this map to the presentation builder, and define an appropriate value in the range of 0.0 - 1.0 for every node.

The following example demonstrates how you can do this (check if the view has been set up to display textures):

1 // assign nodal builder to the mesh
2 Handle (MeshVS_NodalColorPrsBuilder) aBuilder = new MeshVS_NodalColorPrsBuilder
3  (aMesh,MeshVS_DMF_NodalColorDataPrs | MeshVS_DMF_OCCMask);
4 aBuilder->UseTexture (Standard_True);
5 
6 // prepare color map
7 Aspect_SequenceOfColor aColorMap;
8 aColorMap.Append ((Quantity_NameOfColor) Quantity_NOC_RED);
9 aColorMap.Append ((Quantity_NameOfColor) Quantity_NOC_BLUE1);
10 
11 // assign color scale map values (0..1) to nodes
12 TColStd_DataMapOfIntegerReal aScaleMap;
13 ...
14 // iterate through the nodes and add an node id and an appropriate value to the map
15 aScaleMap.Bind (anId, aValue);
16 
17 // pass color map and color scale values to the builder
18 aBuilder->SetColorMap (aColorMap);
19 aBuilder->SetInvalidColor (Quantity_NOC_BLACK);
20 aBuilder->SetTextureCoords (aScaleMap);
21 aMesh->AddBuilder (aBuilder, Standard_True);

Dynamic Selection

The dynamic selection represents the topological shape, which you want to select, by decomposition of sensitive primitives – the sub-parts of the shape that will be detected and highlighted. The sets of these primitives are handled by the powerful three-level BVH tree selection algorithm.

For more details on the algorithm and examples of usage, please, refer to Selection chapter.

3D Presentations

Glossary of 3D terms

  • Anti-aliasing This mode attempts to improve the screen resolution by drawing lines and curves in a mixture of colors so that to the human eye the line or curve is smooth. The quality of the result is linked to the quality of the algorithm used by the workstation hardware.
  • Depth-cueing Reduces the color intensity for the portion of an object further away from the eye to give the impression of depth. This is used for wireframe objects. Shaded objects do not require this.
  • Group – a set of primitives and attributes on those primitives. Primitives and attributes may be added to a group but cannot be removed from it, unless erased globally. A group can have a pick identity.
  • Light There are five kinds of light source – ambient, headlight, directional, positional and spot. The light is only activated in a shading context in a view.
  • Primitive – a drawable element. It has a definition in 3D space. Primitives can either be lines, faces, text, or markers. Once displayed markers and text remain the same size. Lines and faces can be modified e.g. zoomed. Primitives must be stored in a group.
  • Structure – manages a set of groups. The groups are mutually exclusive. A structure can be edited, adding or removing groups. A structure can reference other structures to form a hierarchy. It has a default (identity) transformation and other transformations may be applied to it (rotation, translation, scale, etc). It has no default attributes for the primitive lines, faces, markers, and text. Attributes may be set in a structure but they are overridden by the attributes in each group. Each structure has a display priority associated with it, which rules the order in which it is redrawn in a 3D viewer. If the visualization mode is incompatible with the view it is not displayed in that view, e.g. a shading-only object is not visualized in a wireframe view.
  • View – is defined by a view orientation, a view mapping, and a context view.
  • Viewer – manages a set of views.
  • View orientation – defines the manner in which the observer looks at the scene in terms of View Reference Coordinates.
  • View mapping – defines the transformation from View Reference Coordinates to the Normalized Projection Coordinates. This follows the Phigs scheme.
  • Z-Buffering – a form of hidden surface removal in shading mode only. This is always active for a view in the shading mode. It cannot be suppressed.

Graphic primitives

The Graphic3d package is used to create 3D graphic objects in a 3D viewer. These objects called structures are made up of groups of primitives and attributes, such as polylines, planar polygons with or without holes, text and markers, and attributes, such as color, transparency, reflection, line type, line width, and text font. A group is the smallest editable element of a structure. A transformation can be applied to a structure. Structures can be connected to form a tree of structures, composed by transformations. Structures are globally manipulated by the viewer.

Graphic structures can be:

  • Displayed,
  • Highlighted,
  • Erased,
  • Transformed,
  • Connected to form a tree hierarchy of structures, created by transformations.

There are classes for:

  • Visual attributes for lines, faces, markers, text, materials,
  • Vectors and vertices,
  • Graphic objects, groups, and structures.

Structure hierarchies

The root is the top of a structure hierarchy or structure network. The attributes of a parent structure are passed to its descendants. The attributes of the descendant structures do not affect the parent. Recursive structure networks are not supported.

Graphic primitives

  • Markers
    • Have one or more vertices,
    • Have a type, a scale factor, and a color,
    • Have a size, shape, and orientation independent of transformations.
  • Polygons
    • Have one closed boundary,
    • Have at least three vertices,
    • Are planar and have a normal,
    • Have interior attributes – style, color, front and back material, texture and reflection ratio,
    • Have a boundary with the following attributes – type, width scale factor, color. The boundary is only drawn when the interior style is hollow.
  • Polygons with holes
    • Have multiple closed boundaries, each one with at least three vertices,
    • Are planar and have a normal,
    • Have interior attributes – style, color, front and back material,
    • Have a boundary with the following attributes – type, width scale factor, color. The boundary is only drawn when the interior style is hollow.
  • Polylines
    • Have two or more vertices,
    • Have the following attributes – type, width scale factor, color.
  • Text
    • Has geometric and non-geometric attributes,
    • Geometric attributes – character height, character up vector, text path, horizontal and vertical alignment, orientation, three-dimensional position, zoomable flag
    • Non-geometric attributes – text font, character spacing, character expansion factor, color.

Primitive arrays

Primitive arrays are a more efficient approach to describe and display the primitives from the aspects of memory usage and graphical performance. The key feature of the primitive arrays is that the primitive data is not duplicated. For example, two polygons could share the same vertices, so it is more efficient to keep the vertices in a single array and specify the polygon vertices with indices of this array. In addition to such kind of memory savings, the OpenGl graphics driver provides the Vertex Buffer Objects (VBO). VBO is a sort of video memory storage that can be allocated to hold the primitive arrays, thus making the display operations more efficient and releasing the RAM memory.

The Vertex Buffer Objects are enabled by default, but VBOs availability depends on the implementation of OpenGl. If the VBOs are unavailable or there is not enough video memory to store the primitive arrays, the RAM memory will be used to store the arrays.

The Vertex Buffer Objects can be disabled at the application level. You can use the method Graphic3d_GraphicDriver::EnableVBO (const Standard_Boolean status) to enable/disable VBOs:

The following example shows how to disable the VBO support:

1 // get the graphic driver
2 Handle (Graphic3d_GraphicDriver) aDriver =
3  myAISContext->CurrentViewer()->Driver();
4 
5 // disable VBO support
6 aDriver->EnableVBO (Standard_False);

Note that the use of Vertex Buffer Objects requires the application level primitive data provided by the Graphic3d_ArrayOfPrimitives to be transferred to the video memory. TKOpenGl transfers the data and releases the Graphic3d_ArrayOfPrimitives internal pointers to the primitive data. Thus it might be necessary to pay attention to such kind of behaviour, as the pointers could be modified (nullified) by the TKOpenGl.

The different types of primitives could be presented with the following primitive arrays:

The Graphic3d_ArrayOfPrimitives is a base class for these primitive arrays.

Method Graphic3d_ArrayOfPrimitives::AddVertex allows adding There is a set of similar methods to add vertices to the primitive array.

These methods take vertex coordinates as an argument and allow you to define the color, the normal and the texture coordinates assigned to the vertex. The return value is the actual number of vertices in the array.

You can also modify the values assigned to the vertex or query these values by the vertex index:

The following example shows how to define an array of points:

1 // create an array
2 Handle (Graphic3d_ArrayOfPoints) anArray = new Graphic3d_ArrayOfPoints (aVerticiesMaxCount);
3 
4 // add vertices to the array
5 anArray->AddVertex (10.0, 10.0, 10.0);
6 anArray->AddVertex (0.0, 10.0, 10.0);
7 
8 // add the array to the structure
9 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (aPrs);
10 aGroup->BeginPrimitives ();
11 aGroup->AddPrimitiveArray (anArray);
12 aGroup->EndPrimitives ();

If the primitives share the same vertices (polygons, triangles, etc.) then you can define them as indices of the vertices array.

The method Graphic3d_ArrayOfPrimitives::AddEdge allows defining the primitives by indices. This method adds an "edge" in the range [1, VertexNumber() ] in the array.

It is also possible to query the vertex defined by an edge using method Graphic3d_ArrayOfPrimitives::Edge

The following example shows how to define an array of triangles:

1 // create an array
2 Standard_Boolean IsNormals = Standard_False;
3 Standard_Boolean IsColors = Standard_False;
4 Standard_Boolean IsTextureCrds = Standard_False;
5 Handle (Graphic3d_ArrayOfTriangles) anArray =
6  new Graphic3d_ArrayOfTriangles (aVerticesMaxCount,
7  aEdgesMaxCount,
8  IsNormals,
9  IsColors,
10  IsTextureCrds);
11 // add vertices to the array
12 anArray->AddVertex (-1.0, 0.0, 0.0); // vertex 1
13 anArray->AddVertex ( 1.0, 0.0, 0.0); // vertex 2
14 anArray->AddVertex ( 0.0, 1.0, 0.0); // vertex 3
15 anArray->AddVertex ( 0.0,-1.0, 0.0); // vertex 4
16 
17 // add edges to the array
18 anArray->AddEdge (1); // first triangle
19 anArray->AddEdge (2);
20 anArray->AddEdge (3);
21 anArray->AddEdge (1); // second triangle
22 anArray->AddEdge (2);
23 anArray->AddEdge (4);
24 
25 // add the array to the structure
26 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (aPrs);
27 aGroup->BeginPrimitives ();
28 aGroup->AddPrimitiveArray (anArray);
29 aGroup->EndPrimitives ();

If the primitive array presents primitives built from sequential sets of vertices, for example polygons, then you can specify the bounds, or the number of vertices for each primitive. You can use the method Graphic3d_ArrayOfPrimitives::AddBound to define the bounds and the color for each bound. This method returns the actual number of bounds.

It is also possible to set the color and query the number of edges in the bound and bound color.

1 Standard_Integer Graphic3d_ArrayOfPrimitives::Bound
2 Quantity_Color Graphic3d_ArrayOfPrimitives::BoundColor
3 void Graphic3d_ArrayOfPrimitives::BoundColor

The following example shows how to define an array of polygons:

1 // create an array
2 Standard_Boolean IsNormals = Standard_False;
3 Standard_Boolean IsVertexColors = Standard_False;
4 Standard_Boolean IsFaceColors = Standard_False;
5 Standard_Boolean IsTextureCrds = Standard_False;
6 Handle (Graphic3d_ArrayOfPolygons) anArray =
7  new Graphic3d_ArrayOfPolygons (aVerticesMaxCount,
8  aBoundsMaxCount,
9  aEdgesMaxCount,
10  IsNormals,
11  IsVertexColors,
12  IsFaceColors,
13  IsTextureCrds);
14 
15 // add bounds to the array, first polygon
16 anArray->AddBound (3);
17 anArray->AddVertex (-1.0, 0.0, 0.0);
18 anArray->AddVertex ( 1.0, 0.0, 0.0);
19 anArray->AddVertex ( 0.0, 1.0, 0.0);
20 
21 // add bounds to the array, second polygon
22 anArray->AddBound (4);
23 anArray->AddVertex (-1.0, 0.0, 0.0);
24 anArray->AddVertex ( 1.0, 0.0, 0.0);
25 anArray->AddVertex ( 1.0,-1.0, 0.0);
26 anArray->AddVertex (-1.0,-1.0, 0.0);
27 
28 // add the array to the structure
29 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (aPrs);
30 aGroup->BeginPrimitives ();
31 aGroup->AddPrimitiveArray (anArray);
32 aGroup->EndPrimitives ();

There are also several helper methods. You can get the type of the primitive array:

1 Graphic3d_TypeOfPrimitiveArray
2 Graphic3d_ArrayOfPrimitives::Type
3 Standard_CString Graphic3d_ArrayOfPrimitives::StringType

and check if the primitive array provides normals, vertex colors and vertex texels (texture coordinates):

1 Standard_Boolean Graphic3d_ArrayOfPrimitives::HasVertexNormals
2 Standard_Boolean Graphic3d_ArrayOfPrimitives::HasVertexColors
3 Standard_Boolean Graphic3d_ArrayOfPrimitives::HasVertexTexels

or get the number of vertices, edges and bounds:

1 Standard_Integer Graphic3d_ArrayOfPrimitives::VertexNumber
2 Standard_Integer Graphic3d_ArrayOfPrimitives::EdgeNumber
3 Standard_Integer Graphic3d_ArrayOfPrimitives::BoundNumber

Text primitive

The OpenGl graphics driver uses advanced text rendering powered by FTGL library. This library provides vector text rendering, as a result the text can be rotated and zoomed without quality loss. Graphic3d text primitives have the following features:

  • fixed size (non-zoomable) or zoomable,
  • can be rotated to any angle in the view plane,
  • support unicode charset.

The text attributes for the group could be defined with the Graphic3d_AspectText3d attributes group. To add any text to the graphic structure you can use the following methods:

1 void Graphic3d_Group::Text
2  (const Standard_CString AText,
3  const Graphic3d_Vertex& APoint,
4  const Standard_Real AHeight,
5  const Quantity_PlaneAngle AAngle,
6  const Graphic3d_TextPath ATp,
7  const Graphic3d_HorizontalTextAlignment AHta,
8  const Graphic3d_VerticalTextAlignment AVta,
9  const Standard_Boolean EvalMinMax),

AText parameter is the text string, APoint is the three-dimensional position of the text, AHeight is the text height, AAngle is the orientation of the text (at the moment, this parameter has no effect, but you can specify the text orientation through the Graphic3d_AspectText3d attributes).

ATp parameter defines the text path, AHta is the horizontal alignment of the text, AVta is the vertical alignment of the text.

You can pass Standard_False as EvalMinMax if you do not want the graphic3d structure boundaries to be affected by the text position.

Note that the text orientation angle can be defined by Graphic3d_AspectText3d attributes.

1 void Graphic3d_Group::Text
2  (const Standard_CString AText,
3  const Graphic3d_Vertex& APoint,
4  const Standard_Real AHeight,
5  const Standard_Boolean EvalMinMax)
6 void Graphic3d_Group::Text
7  (const TCcollection_ExtendedString &AText,
8  const Graphic3d_Vertex& APoint,
9  const Standard_Real AHeight,
10  const Quantity_PlaneAngle AAngle,
11  const Graphic3d_TextPath ATp,
12  const Graphic3d_HorizontalTextAlignment AHta,
13  const Graphic3d_VerticalTextAlignment AVta,
14  const Standard_Boolean EvalMinMax)
15 void Graphic3d_Group::Text
16  (const TCcollection_ExtendedString &AText,
17  const Graphic3d_Vertex& APoint,
18  const Standard_Real AHeight,
19  const Standard_Boolean EvalMinMax)

See the example:

1 // get the group
2 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (aPrs);
3 
4 // change the text aspect
5 Handle(Graphic3d_AspectText3d) aTextAspect = new Graphic3d_AspectText3d ();
6 aTextAspect->SetTextZoomable (Standard_True);
7 aTextAspect->SetTextAngle (45.0);
8 aGroup->SetPrimitivesAspect (aTextAspect);
9 
10 // add a text primitive to the structure
11 Graphic3d_Vertex aPoint (1, 1, 1);
12 aGroup->Text (Standard_CString ("Text"), aPoint, 16.0);

Materials

A Graphic3d_MaterialAspect is defined by:

  • Transparency;
  • Diffuse reflection – a component of the object color;
  • Ambient reflection;
  • Specular reflection – a component of the color of the light source;
  • Refraction index.

The following items are required to determine the three colors of reflection:

  • Color;
  • Coefficient of diffuse reflection;
  • Coefficient of ambient reflection;
  • Coefficient of specular reflection.

Textures

A texture is defined by a name. Three types of texture are available:

  • 1D;
  • 2D;
  • Environment mapping.

Shaders

OCCT visualization core supports GLSL shaders. Currently OCCT supports only vertex and fragment GLSL shader. Shaders can be assigned to a generic presentation by its drawer attributes (Graphic3d aspects). To enable custom shader for a specific AISShape in your application, the following API functions are used:

1 // Create shader program
2 Handle(Graphic3d_ShaderProgram) aProgram = new Graphic3d_ShaderProgram();
3 
4 // Attach vertex shader
5 aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile(
6  Graphic3d_TOS_VERTEX, "<Path to VS>"));
7 
8 // Attach fragment shader
9 aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile(
10  Graphic3d_TOS_FRAGMENT, "<Path to FS>"));
11 
12 // Set values for custom uniform variables (if they are)
13 aProgram->PushVariable ("MyColor", Graphic3d_Vec3(0.0f, 1.0f, 0.0f));
14 
15 // Set aspect property for specific AISShape
16 theAISShape->Attributes()->ShadingAspect()->Aspect()->SetShaderProgram (aProgram);

Graphic attributes

Aspect package overview

The Aspect package provides classes for the graphic elements in the viewer:

  • Groups of graphic attributes;
  • Edges, lines, background;
  • Window;
  • Driver;
  • Enumerations for many of the above.

3D view facilities

Overview

The V3d package provides the resources to define a 3D viewer and the views attached to this viewer (orthographic, perspective). This package provides the commands to manipulate the graphic scene of any 3D object visualized in a view on screen.

A set of high-level commands allows the separate manipulation of parameters and the result of a projection (Rotations, Zoom, Panning, etc.) as well as the visualization attributes (Mode, Lighting, Clipping, Depth-cueing, etc.) in any particular view.

The V3d package is basically a set of tools directed by commands from the viewer front-end. This tool set contains methods for creating and editing classes of the viewer such as:

  • Default parameters of the viewer,
  • Views (orthographic, perspective),
  • Lighting (positional, directional, ambient, spot, headlight),
  • Clipping planes (note that only Z-clipping planes can work with the Phigs interface),
  • Instantiated sequences of views, planes, light sources, graphic structures, and picks,
  • Various package methods.

A programming example

This sample TEST program for the V3d Package uses primary packages Xw and Graphic3d and secondary packages Visual3d, Aspect, Quantity, Phigs and math.

1 //Create a default display connection
2 Handle(Aspect_DisplayConnection) aDisplayConnection = new Aspect_DisplayConnection();
3 
4 //Create a Graphic Driver from the default Aspect_DisplayConnection
5 Handle(OpenGl_GraphicDriver) GD = new OpenGl_GraphicDriver (aDisplayConnection);
6 
7 //Create a Viewer to this Driver
8 Handle(V3d_Viewer) VM = new V3d_Viewer(GD, 400.,
9  // Space size
10  V3d_Xpos,
11  // Default projection
12  Quantity_NOC_DARKVIOLET,
13  // Default background
14  V3d_ZBUFFER,
15  // Type of visualization
16  V3d_GOURAUD,
17  // Shading model
18  V3d_WAIT);
19  // Update mode
20 // Create a structure in this Viewer
21 Handle(Graphic3d_Structure) S = new Graphic3d_Structure(VM->Viewer()) ;
22 
23 // Type of structure
24 S->SetVisual (Graphic3d_TOS_SHADING);
25 
26 // Create a group of primitives in this structure
27 Handle(Graphic3d_Group) G = new Graphic3d_Group(S) ;
28 
29 // Fill this group with one polygon of size 100
30 Graphic3d_Array1OfVertex Points(0,3) ;
31 Points(0).SetCoord(-100./2.,-100./2.,-100./2.) ;
32 Points(1).SetCoord(-100./2., 100./2.,-100./2.) ;
33 Points(2).SetCoord( 100./2., 100./2.,-100./2.) ;
34 Points(3).SetCoord( 100./2.,-100./2.,-100./2.) ;
35 Normal.SetCoord(0.,0.,1.) ;
36 G->Polygon(Points,Normal) ;
37 
38 // Create Ambient and Infinite Lights in this Viewer
39 Handle(V3d_AmbientLight) L1 = new V3d_AmbientLight
40  (VM,Quantity_NOC_GRAY50) ;
41 Handle(V3d_DirectionalLight) L2 = new V3d_DirectionalLight
42  (VM,V3d_XnegYnegZneg,Quantity_NOC_WHITE) ;
43 
44 // Create a 3D quality Window with the same DisplayConnection
45 Handle(Xw_Window) W = new Xw_Window(aDisplayConnection,"Test V3d",0.5,0.5,0.5,0.5) ;
46 
47 // Map this Window to this screen
48 W->Map() ;
49 
50 // Create a Perspective View in this Viewer
51 Handle(V3d_View) aView = new V3d_View(VM);
52 aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
53 // Associate this View with the Window
54 aView ->SetWindow(W);
55 // Display ALL structures in this View
56 VM->Viewer()->Display();
57 // Finally update the Visualization in this View
58 aView->Update();

As an alternative to manual setting of perspective parameters the V3d_View::ZfitAll() and V3d_View::FitAll() functions can be used:

1 // Display shape in Viewer VM
2 Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (VM);
3 aContext->Display(shape);
4 // Create a Perspective View in Viewer VM
5 Handle(V3d_View) V = new V3d_View (VM);
6 aview->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
7 // Change Z-min and Z-max planes of projection volume to match the displayed objects
8 V->ZFitAll();
9 // Fit view to object size
10 V->FitAll();

Define viewing parameters

View projection and orientation in OCCT v3d view are driven by camera. The camera calculates and supplies projection and view orientation matrices for rendering by OpenGL. The allows to the user to control all projection parameters. The camera is defined by the following properties:

  • Eye – defines the observer (camera) position. Make sure the Eye point never gets between the Front and Back clipping planes.
  • Center – defines the origin of View Reference Coordinates (where camera is aimed at).
  • Direction – defines the direction of camera view (from the Eye to the Center).
  • Distance – defines the distance between the Eye and the Center.
  • Front Plane – defines the position of the front clipping plane in View Reference Coordinates system.
  • Back Plane – defines the position of the back clipping plane in View Reference Coordinates system.
  • ZNear – defines the distance between the Eye and the Front plane.
  • ZFar – defines the distance between the Eye and the Back plane.

Most common view manipulations (panning, zooming, rotation) are implemented as convenience methods of V3d_View class, however Graphic3d_Camera class can also be used directly by application developers:

Example:

1 // rotate camera by X axis on 30.0 degrees
2 gp_Trsf aTrsf;
3 aTrsf.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Dir (1.0, 0.0, 0.0)), 30.0);
4 aView->Camera()->Transform (aTrsf);

Orthographic Projection

view_frustum.png
Perspective and orthographic projection

The following code configures the camera for orthographic rendering:

1 // Create an orthographic View in this Viewer
2 Handle(V3d_View) aView = new V3d_View (VM);
3 aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
4 // update the Visualization in this View
5 aView->Update();

Perspective Projection

Field of view (FOVy) – defines the field of camera view by y axis in degrees (45° is default).

camera_perspective.png
Perspective frustum

The following code configures the camera for perspective rendering:

1 // Create a perspective View in this Viewer
2 Handle(V3d_View) aView = new V3d_View(VM);
3 aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
4 aView->Update();

Stereographic Projection

IOD – defines the intraocular distance (in world space units).

There are two types of IOD:

  • IODType_Absolute : Intraocular distance is defined as an absolute value.
  • IODType_Relative : Intraocular distance is defined relative to the camera focal length (as its coefficient).

Field of view (FOV) – defines the field of camera view by y axis in degrees (45° is default).

ZFocus – defines the distance to the point of stereographic focus.

stereo.png
Stereographic projection

To enable stereo projection, your workstation should meet the following requirements:

  • The graphic card should support quad buffering.
  • You need active 3D glasses (LCD shutter glasses).
  • The graphic driver needs to be configured to impose quad buffering for newly created OpenGl contexts; the viewer and the view should be created after that.

In stereographic projection mode the camera prepares two projection matrices to display different stereo-pictures for the left and for the right eye. In a non-stereo camera this effect is not visible because only the same projection is used for both eyes.

To enable quad buffering support you should provide the following settings to the graphic driver opengl_caps:

1 Handle(OpenGl_GraphicDriver) aDriver = new OpenGl_GraphicDriver();
2 OpenGl_Caps& aCaps = aDriver->ChangeOptions();
3 aCaps.contextStereo = Standard_True;

The following code configures the camera for stereographic rendering:

1 // Create a Stereographic View in this Viewer
2 Handle(V3d_View) aView = new V3d_View(VM);
3 aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
4 // Change stereo parameters
5 aView->Camera()->SetIOD (IODType_Absolute, 5.0);
6 // Finally update the Visualization in this View
7 aView->Update();

View frustum culling

The algorithm of frustum culling on CPU-side is activated by default for 3D viewer. This algorithm allows skipping the presentation outside camera at the rendering stage, providing better performance. The following features support this method:

Underlay and overlay layers management

In addition to interactive 3d graphics displayed in the view you can display underlying and overlying graphics: text, color scales and drawings.

All V3d view graphical objects in the overlay are managed by the default layer manager (V3d_LayerMgr). The V3d view has a basic layer manager capable of displaying the color scale, but you can redefine this class to provide your own overlay and underlay graphics.

The method V3d_View::SetLayerMgr(const Handle (V3d_LayerMgr)& aMgr) allows assigning a custom layer manager to the V3d view.

There are three virtual methods to prepare graphics in the manager for further drawing: setting up layer dimensions and drawing static graphics. These methods can be redefined:

1 void V3d_LayerMgr::Begin ()
2 void V3d_LayerMgr::Redraw ()
3 void V3d_LayerMgr::End ()

The layer manager controls layers (Visual3d_Layer) and layer items (Visual3d_LayerItem). Both the overlay and underlay layers can be created by the layer manager.

The layer entity is presented by the Visual3d_Layer class. This entity provides drawing services in the layer, for example:

1 void Visual3d_Layer::DrawText
2 void Visual3d_Layer::DrawRectangle
3 void Visual3d_Layer::SetColor
4 void Visual3d_Layer::SetViewport

The following example demonstrates how to draw overlay graphics by the V3d_LayerMgr:

1 // redefined method of V3d_LayerMgr
2 void MyLayerMgr::Redraw ()
3 {
4  Quantity_Color aRed (Quantity_NOC_RED);
5  myOverlayLayer->SetColor (aRed);
6  myOverlayLayer->DrawRectangle (0, 0, 100, 100);
7 }

The layer contains layer items that will be displayed on view redraw. Such items are Visual3d_LayerItem entities. To manipulate Visual3d_LayerItem entities assigned to the layer's internal list you can use the following methods:

1 void Visual3d_Layer::AddLayerItem (const Handle (Visual3d_LayerItem)& Item)
2 void Visual3d_Layer::RemoveLayerItem (const Handle (Visual3d_LayerItem)& Item)
3 void Visual3d_Layer::RemoveAllLayerItems ()
4 const Visual3d_NListOfLayerItem& Visual3d_Layer::GetLayerItemList ()

The layer's items are rendered when the method void Visual3d_Layer::RenderLayerItems() is called by the graphical driver.

The Visual3d_LayerItem has virtual methods that are used to render the item:

1 void Visual3d_LayerItem::RedrawLayerPrs ()
2 void Visual3d_LayerItem::ComputeLayerPrs ()

The item presentation can be computed before drawing by the ComputeLayerPrs method to save time on redraw. It also has an additional flag that is used to tell that the presentation should be recomputed:

1 void Visual3d_LayerItem::SetNeedToRecompute (const Standard_Boolean NeedToRecompute)
2 Standard_Boolean Visual3d_LayerItem::IsNeedToRecompute

An example of Visual3d_LayerItem is V3d_ColorScaleLayerItem that represents the color scale entity as the layer's item. The V3d_ColorScaleLayerItem sends render requests to the color scale entity represented by it. As this entity (V3d_ColorScale) is assigned to the V3d_LayerMgr it uses its overlay layer's services for drawing:

Example

1 // tell V3d_ColorScale to draw itself
2 void V3d_ColorScaleLayerItem::RedrawLayerPrs ()
3 {
4  Visual3d_LayerItem::RedrawLayerPrs ()
5  if (!MyColorScale.IsNull ())
6  MyColorScale->DrawScale ();
7 }
8 
9 // V3d_ColorScale has a reference to a LayerMgr
10 void V3d_ColorScale::DrawScale ()
11 {
12  // calls V3d_ColorScale::PaintRect, V3d_ColorScale::PaintText, etc.
13 }
14 
15 // PaintRect method uses overlay layer of LayerMgr to draw a rectangle
16 void V3d_ColorScale::PaintRect
17  (const Standard_Integer X, const Standard_Integer Y,
18  const Standard_Integer W, const Standard_Integer H,
19  const Quantity_Color aColor,
20  const Standard_Boolean aFilled)
21 {
22  const Handle (Visual3d_Layer)& theLayer = myLayerMgr->Overlay ();
23  ...
24  theLayer->SetColor (aColor);
25  theLayer->DrawRectangle (X, Y, W, H);
26  ...
27 }

View background styles

There are three types of background styles available for V3d_view: solid color, gradient color and image.

To set solid color for the background you can use the following methods:

1 void V3d_View::SetBackgroundColor
2  (const Quantity_TypeOfColor Type,
3  const Quantity_Parameter V1,
4  const Quantity_Parameter V2,
5  const Quantity_Parameter V3)

This method allows you to specify the background color in RGB (red, green, blue) or HLS (hue, lightness, saturation) color spaces, so the appropriate values of the Type parameter are Quantity_TOC_RGB and Quantity_TOC_HLS.

Note that the color value parameters V1,V2,V3 should be in the range between 0.0-1.0.

1 void V3d_View::SetBackgroundColor(const Quantity_Color &Color)
2 void V3d_View::SetBackgroundColor(const Quantity_NameOfColor Name)

The gradient background style could be set up with the following methods:

1 void V3d_View::SetBgGradientColors
2  (const Quantity_Color& Color1,
3  const Quantity_Color& Color2,
4  const Aspect_GradientFillMethod FillStyle,
5  const Standard_Boolean update)
6 
7  void V3d_View::SetBgGradientColors
8  (const Quantity_NameOfColor Color1,
9  const Quantity_NameOfColor Color2,
10  const Aspect_GradientFillMethod FillStyle,
11  const Standard_Boolean update)

The Color1 and Color2 parameters define the boundary colors of interpolation, the FillStyle parameter defines the direction of interpolation. You can pass Standard_True as the last parameter to update the view.

The fill style can be also set with the method void V3d_View::SetBgGradientStyle(const Aspect_GradientFillMethod AMethod, const Standard_Boolean update).

To get the current background color you can use the following methods:

1 void V3d_View::BackgroundColor
2  (const Quantity_TypeOfColor Type,
3  Quantity_Parameter &V1,
4  Quantity_Parameter &V2,
5  Quantity_Parameter &V3)
6 Quantity_Color V3d_View::BackgroundColor()
7 void V3d_View::GradientBackgroundColors(Quantity_Color& Color1, Quantity_Color& Color2)
8 Aspect_GradientBackground GradientBackground()

To set the image as a background and change the background image style you can use the following methods:

1 void V3d_View::SetBackgroundImage
2  (const Standard_CString FileName,
3  const Aspect_FillMethod FillStyle,
4  const Standard_Boolean update)
5 void V3d_View::SetBgImageStyle
6  (const Aspect_FillMethod FillStyle,
7  const Standard_Boolean update)

The FileName parameter defines the image file name and the path to it, the FillStyle parameter defines the method of filling the background with the image. The methods are:

  • Aspect_FM_NONE – draws the image in the default position;
  • Aspect_FM_CENTERED – draws the image at the center of the view;
  • Aspect_FM_TILED – tiles the view with the image;
  • Aspect_FM_STRETCH – stretches the image over the view.

Dumping a 3D scene into an image file

The 3D scene displayed in the view can be dumped in high resolution into an image file. The high resolution (8192x8192 on some implementations) is achieved using the Frame Buffer Objects (FBO) provided by the graphic driver. Frame Buffer Objects enable off-screen rendering into a virtual view to produce images in the background mode (without displaying any graphics on the screen).

The V3d_View has the following methods for dumping the 3D scene:

1 Standard_Boolean V3d_View::Dump
2  (const Standard_CString theFile,
3  const Image_TypeOfImage theBufferType)

Dumps the scene into an image file with the view dimensions.

1 Standard_Boolean V3d_View::Dump
2  (const Standard_CString theFile,
3  const Aspect_FormatOfSheetPaper theFormat,
4  const Image_TypeOfImage theBufferType)

Makes the dimensions of the output image compatible to a certain format of printing paper passed by theFormat argument.

These methods dump the 3D scene into an image file passed by its name and path as theFile.

The raster image data handling algorithm is based on the Image_PixMap class. The supported extensions are ".png", ".bmp", ".png", ".png".

The value passed as theBufferType argument defines the type of the buffer for an output image (RGB, RGBA, floating-point, RGBF, RGBAF). Both methods return Standard_True if the scene has been successfully dumped.

There is also class Image_AlienPixMap providing import / export from / to external image files in formats supported by FreeImage library.

Note that dumping the image for a paper format with large dimensions is a memory consuming operation, it might be necessary to take care of preparing enough free memory to perform this operation.

1 Handle_Image_PixMap V3d_View::ToPixMap
2  (const Standard_Integer theWidth,
3  const Standard_Integer theHeight,
4  const Image_TypeOfImage theBufferType,
5  const Standard_Boolean theForceCentered)

Dumps the displayed 3d scene into a pixmap with a width and height passed as theWidth and theHeight arguments.

The value passed as theBufferType argument defines the type of the buffer for a pixmap (RGB, RGBA, floating-point, RGBF, RGBAF). The last parameter allows centering the 3D scene on dumping.

All these methods assume that you have created a view and displayed a 3d scene in it. However, the window used for such a view could be virtual, so you can dump the 3d scene in the background mode without displaying it on the screen. To use such an opportunity you can perform the following steps:

  • Create display connection;
  • Initialize graphic driver;
  • Create a window;
  • Set up the window as virtual, Aspect_Window::SetVirtual() ;
  • Create a view and an interactive context;
  • Assign the virtual window to the view;
  • Display a 3D scene;
  • Use one of the functions described above to dump the 3D scene.

The following example demonstrates this procedure for WNT_Window :

1 // create a dummy display connection
2 Handle(Aspect_DisplayConnection) aDisplayConnection;
3 
4 // create a graphic driver
5 Handle (Graphic3d_GraphicDriver) aDriver = Graphic3d::InitGraphicDriver (aDisplayConnection);
6 
7 // create a window
8 Standard_Integer aDefWidth = 800;
9 Standard_Integer aDefHeight = 600;
10 Handle (WNT_WClass) aWClass = new WNT_WClass ("Virtual Class",DefWindowProc,
11  CS_VREDRAW | CS_HREDRAW, 0, 0,
12  ::LoadCursor (NULL, IDC_ARROW));
13 Handle (WNT_Window) aWindow = new WNT_Window ("VirtualWnd", aWClass,
14  WS_OVERLAPPEDWINDOW, 0, 0,
15  aDefWidth, aDefHeight);
16 
17 // set up the window as virtual
18 aWindow->SetVirtual (Standard_True);
19 
20 // create a view and an interactive context
21 Handle (V3d_Viewer) aViewer = new V3d_Viewer (aDriver,
22  Standard_ExtString ("Virtual"));
23 Handle (AIS_InteractiveContext) aContext = new AIS_InteractiveContext (aViewer);
24 Handle (V3d_View) aView = aViewer->CreateView ();
25 
26 // assign the virtual window to the view
27 aView->SetWindow (aWindow);
28 
29 // display a 3D scene
30 Handle (AIS_Shape) aBox = new AIS_Shape (BRepPrimAPI_MakeBox (5, 5, 5));
31 aContext->Display (aBox);
32 aView->FitAll();
33 
34 // dump the 3D scene into an image file
35 aView->Dump ("3dscene.png");

Printing a 3D scene

The contents of a view can be printed out. Moreover, the OpenGl graphic driver used by the v3d view supports printing in high resolution. The print method uses the OpenGl frame buffer (Frame Buffer Object) for rendering the view contents and advanced print algorithms that allow printing in, theoretically, any resolution.

The method void V3d_View::Print(const Aspect_Handle hPrnDC, const Standard_Boolean showDialog, const Standard_Boolean showBackground, const Standard_CString filename, const Aspect_PrintAlgo printAlgorithm) prints the view contents:

hPrnDC is the printer device handle. You can pass your own printer handle or NULL to select the printer by the default dialog. In that case you can use the default dialog or pass Standard_False as the showDialog argument to select the default printer automatically.

You can define the filename for the printer driver if you want to print out the result into a file. If you do not want to print the background, you can pass Standard_False as the showBackground argument. The printAlgorithm argument allows choosing between two print algorithms that define how the 3d scene is mapped to the print area when the maximum dimensions of the frame buffer are smaller than the dimensions of the print area by choosing Aspect_PA_STRETCH or Aspect_PA_TILE

The first value defines the stretch algorithm: the scene is drawn with the maximum possible frame buffer dimensions and then is stretched to the whole printing area. The second value defines TileSplit algorithm: covering the whole printing area by rendering multiple parts of the viewer.

Note that at the moment the printing is implemented only for Windows.

Vector image export

The 3D content of a view can be exported to the vector image file format. The vector image export is powered by the GL2PS library. You can export 3D scenes into a file format supported by the GL2PS library: PostScript (PS), Encapsulated PostScript (EPS), Portable Document Format (PDF), Scalable Vector Graphics (SVG), LaTeX file format and Portable LaTeX Graphics (PGF).

The method void Visual3d_View::Export (const Standard_CString FileName, const Graphic3d_ExportFormat Format, const Graphic3d_SortType aSortType, const Standard_Real Precision, const Standard_Address ProgressBarFunc, const Standard_Address ProgressObject) of Visual3d_View class allows exporting a 3D scene:

The FileName defines the output image file name and the Format argument defines the output file format:

  • Graphic3d_EF_PostScript (PS),
  • Graphic3d_EF_EhnPostScript (EPS),
  • Graphic3d_EF_TEX (TEX),
  • Graphic3d_EF_PDF (PDF),
  • Graphic3d_EF_SVG (SVG),
  • Graphic3d_EF_PGF (PGF).

The aSortType parameter defines GL2PS sorting algorithm for the primitives. The Precision, ProgressBarFunc and ProgressObject parameters are implemented for future uses and at the moment have no effect.

The Export method supports only basic 3d graphics and has several limitations:

  • Rendering large scenes could be slow and can lead to large output files;
  • Transparency is only supported for PDF and SVG output;
  • Textures and some effects are not supported by the GL2PS library.

Ray tracing support

OCCT visualization provides rendering by real-time ray tracing technique. It is allowed to switch easily between usual rasterization and ray tracing rendering modes. The core of OCCT ray tracing is written using GLSL shaders. The ray tracing has a wide list of features:

  • Hard shadows
  • Refractions
  • Reflection
  • Transparency
  • Texturing
  • Support of non-polygon objects, such as lines, text, highlighting, selection.
  • Performance optimization using 2-level bounding volume hierarchy (BVH).

The ray tracing algorithm is recursive (Whitted's algorithm). It uses BVH effective optimization structure. The structure prepares optimized data for a scene geometry for further displaying it in real-time. The time-consuming re-computation of the BVH is not necessary for view operations, selections, animation and even editing of the scene by transforming location of the objects. It is only necessary when the list of displayed objects or their geometry changes. To make the BVH reusable it has been added into an individual reusable OCCT package TKMath/BVH.

There are several ray-tracing options that user can switch on/off:

  • Maximum ray tracing depth
  • Shadows rendering
  • Specular reflections
  • Adaptive anti aliasing
  • Transparency shadow effects

Example:

1 Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
2 // specifies rendering mode
3 aParams.Method = Graphic3d_RM_RAYTRACING;
4 // maximum ray-tracing depth
5 aParams.RaytracingDepth = 3;
6 // enable shadows rendering
7 aParams.IsShadowEnabled = Standard_True;
8 // enable specular reflections.
9 aParams.IsReflectionEnabled = Standard_True;
10 // enable adaptive anti-aliasing
11 aParams.IsAntialiasingEnabled = Standard_True;
12 // enable light propagation through transparent media.
13 aParams.IsTransparentShadowEnabled = Standard_True;
14 // update the view
15 aView->Update();

Display priorities

Structure display priorities control the order, in which structures are drawn. When you display a structure you specify its priority. The lower is the value, the lower is the display priority. When the display is regenerated, the structures with the lowest priority are drawn first. The structures with the same display priority are drawn in the same order as they have been displayed. OCCT supports eleven structure display priorities.

Z-layer support

OCCT features depth-arranging functionality called z-layer. A graphical presentation can be put into a z-layer. In general, this function can be used for implementing "bring to front" functionality in a graphical application.

Example:

1 // set z-layer to an interactive object
2 Handle(AIS_InteractiveContext) aContext = ...
3 Handle(AIS_InteractiveObject) anInterObj = ...
4 Standard_Integer anId = 3;
5 aViewer->AddZLayer (anId);
6 aContext->SetZLayer (anInterObj, anId);

For each z-layer, it is allowed to:

  • Enable / disable depth test for layer.
  • Enable / disable depth write for layer.
  • Enable / disable depth buffer clearing.
  • Enable / disable polygon offset.

The corresponding method SetZLayerOption (...) is available in Graphic3d_GraphicDriver interface. You can get the options using getter from Visual3d_ViewManager and V3d_Viewer. It returns Graphic3d_ZLayerSettings cached in Visual3d_ViewManager for a given LayerId.

Example:

1 // change z-layer settings
2 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
3 aSettings.EnableSetting (Graphic3d_ZLayerDepthTest);
4 aSettings.EnableSetting (Graphic3d_ZLayerDepthWrite);
5 aSettings.EnableSetting (Graphic3d_ZLayerDepthClear);
6 aSettings.EnableSetting (Graphic3d_ZLayerDepthOffset);
7 aViewer->SetZLayerSettings (anId, aSettings);

Clipping planes

The ability to define custom clipping planes could be very useful for some tasks. OCCT provides such an opportunity.

The Graphic3d_ClipPlane class provides the services for clipping planes: it holds the plane equation coefficients and provides its graphical representation. To set and get plane equation coefficients you can use the following methods:

1 Graphic3d_ClipPlane::Graphic3d_ClipPlane(const gp_Pln& thePlane)
2 void Graphic3d_ClipPlane::SetEquation (const gp_Pln& thePlane)
3 Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Equation& theEquation)
4 void Graphic3d_ClipPlane::SetEquation (const Equation& theEquation)
5 gp_Pln Graphic3d_ClipPlane::ToPlane() const

The clipping planes can be activated with the following method:

1 void Graphic3d_ClipPlane::SetOn (const Standard_Boolean theIsOn)

The number of clipping planes is limited. You can check the limit value via method Graphic3d_GraphicDriver::InquirePlaneLimit();

1 // get the limit of clipping planes for the current view
2 Standard_Integer aMaxClipPlanes = aView->Viewer()->Driver()->InquirePlaneLimit();

Let us see for example how to create a new clipping plane with custom parameters and add it to a view or to an object:

1 // create a new clipping plane
2 const Handle(Graphic3d_ClipPlane)& aClipPlane = new Graphic3d_ClipPlane();
3 // change equation of the clipping plane
4 Standard_Real aCoeffA = ...
5 Standard_Real aCoeffB = ...
6 Standard_Real aCoeffC = ...
7 Standard_Real aCoeffD = ...
8 aClipPlane->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
9 // set capping
10 aClipPlane->SetCapping (aCappingArg == "on");
11 // set the material with red color of clipping plane
12 Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
13 Quantity_Color aColor (1.0, 0.0, 0.0, Quantity_TOC_RGB);
14 aMat.SetAmbientColor (aColor);
15 aMat.SetDiffuseColor (aColor);
16 aClipPlane->SetCappingMaterial (aMat);
17 // set the texture of clipping plane
18 Handle(Graphic3d_Texture2Dmanual) aTexture = ...
19 aTexture->EnableModulate();
20 aTexture->EnableRepeat();
21 aClipPlane->SetCappingTexture (aTexture);
22 // add the clipping plane to an interactive object
23 Handle(AIS_InteractiveObject) aIObj = ...
24 aIObj->AddClipPlane (aClipPlane);
25 // or to the whole view
26 aView->AddClipPlane (aClipPlane);
27 // activate the clipping plane
28 aClipPlane->SetOn(Standard_True);
29 // update the view
30 aView->Update();

Automatic back face culling

Back face culling reduces the rendered number of triangles (which improves the performance) and eliminates artifacts at shape boundaries. However, this option can be used only for solid objects, where the interior is actually invisible from any point of view. Automatic back-face culling mechanism is turned on by default, which is controlled by V3d_View::SetBackFacingModel().

The following features are applied in StdPrs_ToolShadedShape::IsClosed(), which is used for definition of back face culling in ShadingAspect:

  • disable culling for free closed Shells (not inside the Solid) since reversed orientation of a free Shell is a valid case;
  • enable culling for Solids packed into a compound;
  • ignore Solids with incomplete triangulation.

Back face culling is turned off at TKOpenGl level in the following cases:

  • clipping/capping planes are in effect;
  • for translucent objects;
  • with hatching presentation style.

Examples: creating a 3D scene

To create 3D graphic objects and display them in the screen, follow the procedure below:

  1. Create attributes.
  2. Create a 3D viewer.
  3. Create a view.
  4. Create an interactive context.
  5. Create interactive objects.
  6. Create primitives in the interactive object.
  7. Display the interactive object.

Create attributes

Create colors.

1 Quantity_Color aBlack (Quantity_NOC_BLACK);
2 Quantity_Color aBlue (Quantity_NOC_MATRABLUE);
3 Quantity_Color aBrown (Quantity_NOC_BROWN4);
4 Quantity_Color aFirebrick (Quantity_NOC_FIREBRICK);
5 Quantity_Color aForest (Quantity_NOC_FORESTGREEN);
6 Quantity_Color aGray (Quantity_NOC_GRAY70);
7 Quantity_Color aMyColor (0.99, 0.65, 0.31, Quantity_TOC_RGB);
8 Quantity_Color aBeet (Quantity_NOC_BEET);
9 Quantity_Color aWhite (Quantity_NOC_WHITE);

Create line attributes.

1 Handle(Graphic3d_AspectLine3d) anAspectBrown = new Graphic3d_AspectLine3d();
2 Handle(Graphic3d_AspectLine3d) anAspectBlue = new Graphic3d_AspectLine3d();
3 Handle(Graphic3d_AspectLine3d) anAspectWhite = new Graphic3d_AspectLine3d();
4 anAspectBrown->SetColor (aBrown);
5 anAspectBlue ->SetColor (aBlue);
6 anAspectWhite->SetColor (aWhite);

Create marker attributes.

1 Handle(Graphic3d_AspectMarker3d aFirebrickMarker = new Graphic3d_AspectMarker3d();
2 // marker attributes
3 aFirebrickMarker->SetColor (Firebrick);
4 aFirebrickMarker->SetScale (1.0);
5 aFirebrickMarker->SetType (Aspect_TOM_BALL);
6 // or this
7 // it is a preferred way (supports full-color images on modern hardware).
8 aFirebrickMarker->SetMarkerImage (theImage)

Create facet attributes.

1 Handle(Graphic3d_AspectFillArea3d) aFaceAspect = new Graphic3d_AspectFillArea3d();
2 Graphic3d_MaterialAspect aBrassMaterial (Graphic3d_NOM_BRASS);
3 Graphic3d_MaterialAspect aGoldMaterial (Graphic3d_NOM_GOLD);
4 aFaceAspect->SetInteriorStyle (Aspect_IS_SOLID);
5 aFaceAspect->SetInteriorColor (aMyColor);
6 aFaceAspect->SetDistinguishOn ();
7 aFaceAspect->SetFrontMaterial (aGoldMaterial);
8 aFaceAspect->SetBackMaterial (aBrassMaterial);
9 aFaceAspect->SetEdgeOn();

Create text attributes.

1 Handle(Graphic3d_AspectText3d) aTextAspect = new Graphic3d_AspectText3d (aForest, Graphic3d_NOF_ASCII_MONO, 1.0, 0.0);

Create a 3D Viewer (a Windows example)

1 // create a default connection
2 Handle(Aspect_DisplayConnection) aDisplayConnection;
3 // create a graphic driver from default connection
4 Handle(OpenGl_GraphicDriver) aGraphicDriver = new OpenGl_GraphicDriver (GetDisplayConnection());
5 // create a viewer
6 TCollection_ExtendedString aName ("3DV");
7 myViewer = new V3d_Viewer (aGraphicDriver,aName.ToExtString(), "");
8 // set parameters for V3d_Viewer
9 // defines default lights -
10 // positional-light 0.3 0.0 0.0
11 // directional-light V3d_XnegYposZpos
12 // directional-light V3d_XnegYneg
13 // ambient-light
14 a3DViewer->SetDefaultLights();
15 // activates all the lights defined in this viewer
16 a3DViewer->SetLightOn();
17 // set background color to black
18 a3DViewer->SetDefaultBackgroundColor (Quantity_NOC_BLACK);

Create a 3D view (a Windows example)

It is assumed that a valid Windows window may already be accessed via the method GetSafeHwnd().

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

Create an interactive context

1 myAISContext = new AIS_InteractiveContext (myViewer);

You are now able to display interactive objects such as an AIS_Shape.

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

Create your own interactive object

Follow the procedure below to compute the presentable object:

  1. Build a presentable object inheriting from AIS_InteractiveObject (refer to the Chapter on Presentable Objects).
  2. Reuse the Prs3d_Presentation provided as an argument of the compute methods.

Note that there are two compute methods: one for a standard representation, and the other for a degenerated representation, i.e. in hidden line removal and wireframe modes.

Let us look at the example of compute methods

1 Void
2 myPresentableObject::Compute
3  (const Handle(PrsMgr_PresentationManager3d)& thePrsManager,
4  const Handle(Prs3d_Presentation)& thePrs,
5  const Standard_Integer theMode)
6 (
7  //...
8 )
9 
10 void
11 myPresentableObject::Compute (const Handle(Prs3d_Projector)& ,
12  const Handle(Prs3d_Presentation)& thePrs)
13 (
14  //...
15 )

Create primitives in the interactive object

Get the group used in Prs3d_Presentation.

1 Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs);

Update the group attributes.

1 aGroup->SetPrimitivesAspect (anAspectBlue);

Create two triangles in aGroup.

1 Standard_Integer aNbTria = 2;
2 Handle(Graphic3d_ArrayOfTriangles) aTriangles = new Graphic3d_ArrayOfTriangles (3 * aNbTria, 0, Standard_True);
3 Standard_Integer anIndex;
4 for (anIndex = 1; anIndex <= aNbTria; nt++)
5 {
6  aTriangles->AddVertex (anIndex * 5., 0., 0., 1., 1., 1.);
7  aTriangles->AddVertex (anIndex * 5 + 5, 0., 0., 1., 1., 1.);
8  aTriangles->AddVertex (anIndex * 5 + 2.5, 5., 0., 1., 1., 1.);
9 }
10 aGroup->BeginPrimitives();
11 aGroup->AddPrimitiveArray (aTriangles);
12 aGroup->EndPrimitives();

The methods BeginPrimitives() and EndPrimitives() are used when creating a set of various primitives in the same group. Use the polyline function to create a boundary box for the thePrs structure in group aGroup.

1 Standard_Real Xm, Ym, Zm, XM, YM, ZM;
2 thePrs->MinMaxValues (Xm, Ym, Zm, XM, YM, ZM);
3 
4 Handle(Graphic3d_ArrayOfPolylines) aPolylines = new Graphic3d_ArrayOfPolylines (16, 4);
5 aPolylines->AddBound (4);
6 aPolylines->AddVertex (Xm, Ym, Zm);
7 aPolylines->AddVertex (Xm, Ym, ZM);
8 aPolylines->AddVertex (Xm, YM, ZM);
9 aPolylines->AddVertex (Xm, YM, Zm);
10 aPolylines->AddBound (4);
11 aPolylines->AddVertex (Xm, Ym, Zm);
12 aPolylines->AddVertex (XM, Ym, Zm);
13 aPolylines->AddVertex (XM, Ym, ZM);
14 aPolylines->AddVertex (XM, YM, ZM);
15 aPolylines->AddBound (4);
16 aPolylines->AddVertex (XM, YM, Zm);
17 aPolylines->AddVertex (XM, Ym, Zm);
18 aPolylines->AddVertex (XM, YM, Zm);
19 aPolylines->AddVertex (Xm, YM, Zm);
20 aPolylines->AddBound (4);
21 aPolylines->AddVertex (Xm, YM, ZM);
22 aPolylines->AddVertex (XM, YM, ZM);
23 aPolylines->AddVertex (XM, Ym, ZM);
24 aPolylines->AddVertex (Xm, Ym, ZM);
25 
26 aGroup->BeginPrimitives();
27 aGroup->AddPrimitiveArray(aPolylines);
28 aGroup->EndPrimitives();

Create text and markers in group aGroup.

1 static char* texte[3] =
2 {
3  "Application title",
4  "My company",
5  "My company address."
6 };
7 Handle(Graphic3d_ArrayOfPoints) aPtsArr = new Graphic3d_ArrayOfPoints (2, 1);
8 aPtsArr->AddVertex (-40.0, -40.0, -40.0);
9 aPtsArr->AddVertex (40.0, 40.0, 40.0);
10 aGroup->BeginPrimitives();
11 aGroup->AddPrimitiveArray (aPtsArr);
12 aGroup->EndPrimitives();
13 
14 Graphic3d_Vertex aMarker (0.0, 0.0, 0.0);
15 for (i=0; i <= 2; i++)
16 {
17  aMarker.SetCoord (-(Standard_Real )i * 4 + 30,
18  (Standard_Real )i * 4,
19  -(Standard_Real )i * 4);
20  aGroup->Text (texte[i], Marker, 20.);
21 }

Mesh Visualization Services

MeshVS (Mesh Visualization Service) component extends 3D visualization capabilities of Open CASCADE Technology. It provides flexible means of displaying meshes along with associated pre- and post-processor data.

From a developer's point of view, it is easy to integrate the MeshVS component into any mesh-related application with the following guidelines:

  • Derive a data source class from the MeshVS_DataSource class.
  • Re-implement its virtual methods, so as to give the MeshVS component access to the application data model. This is the most important part of the job, since visualization performance is affected by performance of data retrieval methods of your data source class.
  • Create an instance of MeshVS_Mesh class.
  • Create an instance of your data source class and pass it to a MeshVS_Mesh object through the SetDataSource() method.
  • Create one or several objects of MeshVS_PrsBuilder-derived classes (standard, included in the MeshVS package, or your custom ones).
  • Each PrsBuilder is responsible for drawing a MeshVS_Mesh presentation in a certain display mode(s) specified as a PrsBuilder constructor's argument. Display mode is treated by MeshVS classes as a combination of bit flags (two least significant bits are used to encode standard display modes: wireframe, shading and shrink).
  • Pass these objects to the MeshVS_Mesh::AddBuilder() method. MeshVS_Mesh takes advantage of improved selection highlighting mechanism: it highlights its selected entities itself, with the help of so called "highlighter" object. You can set one of PrsBuilder objects to act as a highlighter with the help of a corresponding argument of the AddBuilder() method.

Visual attributes of the MeshVS_Mesh object (such as shading color, shrink coefficient and so on) are controlled through MeshVS_Drawer object. It maintains a map "Attribute ID --> attribute value" and can be easily extended with any number of custom attributes.

In all other respects, MeshVS_Mesh is very similar to any other class derived from AIS_InteractiveObject and it should be used accordingly (refer to the description of AIS package in the documentation).