403749d53ef92929ecf0341e1ff82366f4d90738
[occt.git] / dox / user_guides / visualization / visualization.md
1 Visualization    {#occt_user_guides__visualization}
2 ========================
3 @tableofcontents 
4
5 @section occt_visu_1 Introduction
6
7 Visualization in Open CASCADE Technology is based on the separation of:
8   * on the one hand -- the data which stores the geometry and topology of the entities you want to display and select, and
9   * on the other hand -- its **presentation** (what you see when an object is displayed in a scene)
10     and **selection** (possibility to choose the whole object or its sub-parts interactively to apply application-defined operations to the selected entities).
11
12 Presentations are managed through the **Presentation** component, and selection through the **Selection** component.
13
14 **Application Interactive Services** (AIS) provides the means to create links between an application GUI viewer and the packages,
15 which are used to manage selection and presentation, which makes management of these functionalities in 3D more intuitive and consequently, more transparent.
16
17 *AIS* uses the notion of the *Interactive Object*, a displayable and selectable entity, which represents an element from the application data.
18 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.
19
20 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.
21 To do this requires familiarity with such fundamental concepts as the Sensitive Primitive and the Presentable Object.
22
23 The the following packages are used to display 3D objects:
24   * *AIS*;
25   * *StdPrs*;
26   * *Prs3d*;
27   * *PrsMgr*;
28   * *V3d*;
29   * *Graphic3d*.
30
31 The packages used to display 3D objects are also applicable for visualization of 2D objects.
32
33 The figure below presents a schematic overview of the relations between the key concepts and packages in visualization.
34 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.
35
36 @figure{visualization_image003.png,"Key concepts and packages in visualization",400}
37
38 To answer different needs of CASCADE users, this User's Guide offers the following three paths in reading it.
39
40   * If the 3D services proposed in AIS meet your requirements, you need only read chapter 3  @ref occt_visu_3 "AIS: Application Interactive Services".
41   * If you need more detail, for example, a selection filter on another type of entity -- you should read
42     chapter 2 @ref occt_visu_2 "Fundamental Concepts", chapter 3 @ref occt_visu_3 "AIS: Application Interactive Services", and 4 @ref occt_visu_4 "3D Presentations".
43     You may want to begin with the chapter presenting AIS.
44
45 @section occt_visu_2 Fundamental Concepts
46
47 @subsection occt_visu_2_1 Presentation
48
49 In Open CASCADE Technology, presentation services are separated from the data, which they represent, which is generated by applicative algorithms.
50 This division allows you to modify a geometric or topological algorithm and its resulting objects without modifying the visualization services.
51
52 @subsubsection occt_visu_2_1_1 Structure of the Presentation
53
54 Displaying an object on the screen involves three kinds of entities:
55   * a presentable object, the *AIS_InteractiveObject*
56   * a viewer
57   * an interactive context, the *AIS_InteractiveContext*.
58
59 #### The presentable object
60
61 The purpose of a presentable object is to provide the graphical representation of an object in the form of *Graphic3d_Structure*.
62 On the first display request, it creates this structure by calling the appropriate algorithm and retaining this framework for further display.
63
64 Standard presentation algorithms are provided in the *StdPrs* and *Prs3d* packages.
65 You can, however, write specific presentation algorithms of your own, provided that they create presentations made of structures from the *Graphic3d* packages.
66 You can also create several presentations of a single presentable object: one for each visualization mode supported by your application.
67
68 Each object to be presented individually must be presentable or associated with a presentable object.
69
70 #### The viewer
71
72 The viewer allows interactively manipulating views of the object.
73 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.
74 Creating Graphic3d structures in your presentation algorithms allows you to use the 3D viewers provided in Open CASCADE Technology for 3D visualization.
75
76 #### The Interactive Context
77
78 The interactive context controls the entire presentation process from a common high-level API.
79 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.
80
81 @subsubsection occt_visu_2_1_2 Presentation packages
82
83 Presentation involves at least the *AIS, PrsMgr, StdPrs* and *V3d* packages.
84 Additional packages, such as *Prs3d* and *Graphic3d* may be used if you need to implement your own presentation algorithms.
85
86 * Standard Interactive Objects
87   * *AIS* package provides classes to implement interactive objects (presentable and selectable entities).
88   * *PrsDim* package provides presentable objects for drawing dimensions and relations.
89   * *MeshVS* package provides presentable object MeshVS_Mesh for working with mesh data.
90 * Standard presentation builders
91   * *Prs3d* package provides ready-to-use standard presentation algorithms for simple geometries like arrow, cylinder, sphere.
92     It also defines *Prs3d_Drawer* class controlling the attributes of the presentation to be created in terms of color, line type, thickness, etc.
93   * *StdPrs* package provides ready-to-use standard presentation algorithms for B-Rep shapes.
94     It provides generic presentation algorithms such as shading, wireframe, isolines and hidden line removal.
95   * *DsgPrs* package provides tools for display of dimensions, relations and XYZ trihedrons.
96 * Selection services
97   * *Select3D*, *SelectBasics* and *SelectMgr* implement selection (picking) services.
98   * *StdSelect* package provide selection builders for B-Rep shapes.
99 * Viewer management
100   *V3d* package provides the services supported by the 3D viewer.
101 * Low-level interfaces
102   * *PrsMgr* package defines basic interfaces and tools for presentable object.
103     It contains all classes needed to implement the presentation process:
104     abstract classes *PrsMgr_Presentation* and *PrsMgr_PresentableObject* and concrete class *PrsMgr_PresentationManager*.
105   * *Graphic3d* package provides low-level graphic structures.
106     It also defines an interface of Graphic3d_GraphicDriver providing a connection with low-level graphics APIs like OpenGL.
107
108 @subsubsection occt_visu_2_1_3 A Basic Example: How to display a 3D object
109
110 ~~~~~{.cpp}
111 Handle(V3d_Viewer) theViewer;
112 Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (theViewer);
113
114 BRepPrimAPI_MakeWedge aWedgeMaker (theWedgeDX, theWedgeDY, theWedgeDZ, theWedgeLtx);
115 TopoDS_Solid aShape = aWedgeMaker.Solid();
116 Handle(AIS_Shape) aShapePrs = new AIS_Shape (aShape); // creation of the presentable object
117 aContext->Display (aShapePrs, AIS_Shaded, 0, true);   // display the presentable object and redraw 3d viewer
118 ~~~~~
119
120 The shape is created using the *BRepPrimAPI_MakeWedge* command.
121 An *AIS_Shape* is then created from the shape.
122 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.
123 See figure below.
124
125 @figure{visualization_image004.svg,"Processes involved in displaying a presentable shape",400}
126
127 @subsection occt_visu_2_2 Selection
128
129 Standard OCCT selection algorithm is represented by 2 parts: dynamic and static.
130 Dynamic selection causes objects to be automatically highlighted as the mouse cursor moves over them.
131 Static selection allows to pick particular object (or objects) for further processing.
132
133 There are 3 different selection types:
134   - **Point selection** -- allows picking and highlighting a single object (or its part) located under the mouse cursor;
135   - **Rectangle selection** -- allows picking objects or parts located under the rectangle defined by the start and end mouse cursor positions;
136   - **Polyline selection** -- allows picking objects or parts located under a user-defined non-self-intersecting polyline.
137
138 For OCCT selection algorithm, all selectable objects are represented as a set of sensitive zones, called **sensitive entities**.
139 When the mouse cursor moves in the view, the sensitive entities of each object are analyzed for collision.
140
141 @subsubsection occt_visu_2_2_1 Terms and notions
142
143 This section introduces basic terms and notions used throughout the algorithm description.
144
145 #### Sensitive entity
146
147 Sensitive entities in the same way as entity owners are links between objects and the selection mechanism.
148
149 The purpose of entities is to define what parts of the object will be selectable in particular.
150 Thus, any object that is meant to be selectable must be split into sensitive entities (one or several).
151 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.
152
153 @figure{visualization_image005.png,"Example of a shape divided into sensitive entities",400}
154
155 Depending on the user's needs, sensitive entities may be atomic (point or edge) or complex.
156 Complex entities contain many sub-elements that can be handled by detection mechanism in a similar way
157 (for example, a polyline stored as a set of line segments or a triangulation).
158
159 Entities are used as internal units of the selection algorithm and do not contain any topological data,
160 hence they have a link to an upper-level interface that maintains topology-specific methods.
161
162 #### Entity owner
163
164 Each *Select3D_SensitiveEntity* stores a reference to its owner *SelectMgr_EntityOwner*,
165 which is a class connecting the entity and the corresponding selectable object (*SelectMgr_SelectableObject*).
166 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.
167
168 #### Selection
169
170 To simplify the handling of different selection modes of an object, sensitive entities linked to their owners are organized into sets, called **selections** (*SelectMgr_Selection*).
171 Each selection contains entities created for a certain mode along with the sensitivity and update states.
172
173 #### Selectable object
174
175 Selectable object (*SelectMgr_SelectableObject* or more precisely *AIS_InteractiveObject*) stores information about all created selection modes and sensitive entities.
176
177 All successors of a selectable object must implement the method that splits its presentation into sensitive entities according to the given mode.
178 The computed entities are arranged in one selection and added to the list of all selections of this object.
179 No selection will be removed from the list until the object is deleted permanently.
180
181 For all standard OCCT interactive objects, zero mode is supposed to select the whole object (but it may be redefined in the custom object).
182 For example, the *AIS_Shape* object determine the following modes (see AIS_Shape::SelectionMode()):
183   - 0 -- selection of the entire object (AIS_Shape);
184   - 1 -- selection of the vertices (TopAbs_VERTEX);
185   - 2 -- selection of the edges (TopAbs_EDGE);
186   - 3 -- selection of the wires (TopAbs_WIRE);
187   - 4 -- selection of the faces (TopAbs_FACE);
188   - 5 -- selection of the shells (TopAbs_SHELL);
189   - 6 -- selection of the constituent solids (TopAbs_SOLID).
190
191 @figure{visualization_image006.png,"Hierarchy of references from sensitive entity to selectable object",400}
192
193 @figure{visualization_image007.png,"The principle of entities organization within the selectable object",400}
194
195 #### Viewer selector
196
197 For each OCCT viewer there is a **Viewer selector** class *SelectMgr_ViewerSelector3d*.
198 It provides a high-level API for the whole selection algorithm and encapsulates the processing of objects and sensitive entities for each mouse pick.
199 The viewer selector maintains activation and deactivation of selection modes, launches the algorithm, which detects candidate entities to be picked,
200 and stores its results, as well as implements an interface for keeping selection structures up-to-date.
201
202 #### Selection manager
203
204 Selection manager *SelectMgr_SelectionManager* is a high-level API to manipulate selection of all displayed objects.
205 It handles all viewer selectors, activates and deactivates selection modes for the objects in all or particular selectors,
206 manages computation and update of selections for each object.
207 Moreover, it keeps selection structures updated taking into account applied changes.
208
209 @figure{visualization_image008.png,"The relations chain between viewer selector and selection manager",400}
210
211 @subsubsection occt_visu_2_2_2 Algorithm
212
213 All three types of OCCT selection are implemented as a single concept,
214 based on the search for overlap between frustum and sensitive entity through 3-level BVH tree traversal.
215
216 #### Selection Frustum
217
218 The first step of each run of selection algorithm is to build the selection frustum according to the currently activated selection type.
219
220 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.
221 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.
222 Thus, this type of selection uses a set of triangular frustums for overlap detection.
223
224 The frustum length is limited by near and far view volume planes and each plane is built parallel to the corresponding view volume plane.
225
226 @figure{visualization_image009.png,"",400}
227
228 The image above shows the rectangular frustum: a) after mouse move or click, b) after applying the rectangular selection.
229
230 @figure{visualization_image010.png,"",400}
231
232 In the image above triangular frustum is set: a) by a user-defined polyline, b) by triangulation of the polygon based on the given polyline, c) by a triangular frustum based on one of the triangles.
233
234 #### BVH trees
235
236 To maintain selection mechanism at the viewer level, a speedup structure composed of 3 BVH trees is used.
237
238 The first level tree is constructed of axis-aligned bounding boxes of each selectable object.
239 Hence, the root of this tree contains the combination of all selectable boundaries even if they have no currently activated selections.
240 Objects are added during the display of *AIS_InteractiveObject* and will be removed from this tree only when the object is destroyed.
241 The 1st level BVH tree is build on demand simultaneously with the first run of the selection algorithm.
242
243 The second level BVH tree consists of all sensitive entities of one selectable object.
244 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.
245
246 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.
247 It is built on demand for sensitive entities with more than 800K sub-elements (defined by *StdSelect_BRepSelectionTool::PreBuildBVH()*).
248
249 @figure{visualization_image022.png,"Selection BVH tree hierarchy: from the biggest object-level (first) to the smallest complex entity level (third)",400}
250
251 #### Stages of the algorithm
252
253 The algorithm includes pre-processing and three main stages.
254
255 ##### Pre-processing
256
257 Implies calculation of the selection frustum and its main characteristics.
258
259 ##### First stage -- traverse of the first level BVH tree
260
261 After successful building of the selection frustum, the algorithm starts traversal of the object-level BVH tree.
262 The nodes containing axis-aligned bounding boxes are tested for overlap with the selection frustum following the terms of *separating axis theorem (SAT)*.
263 When the traversal goes down to the leaf node, it means that a candidate object with possibly overlapping sensitive entities has been found.
264 If no such objects have been detected, the algorithm stops and it is assumed that no object needs to be selected.
265 Otherwise it passes to the next stage to process the entities of the found selectable object.
266
267 ##### Second stage -- traversal of the second level BVH tree
268
269 At this stage it is necessary to determine if there are candidates among all sensitive entities of one object.
270
271 First of all, at this stage the algorithm checks if there is any transformation applied for the current object.
272 If it has its own location, then the correspondingly transformed frustum will be used for further calculations.
273 At the next step the nodes of the second level BVH tree of the given object are visited to search for overlapping leaves.
274 If no such leafs have been found, the algorithm returns to the second stage.
275 Otherwise it starts processing the found entities by performing the following checks:
276   - activation check - the entity may be inactive at the moment as it belongs to deactivated selection;
277   - 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;
278     thus, at this step the frustum may be scaled.
279
280 After these checks the algorithm passes to the last stage.
281
282 ##### Third stage -- overlap or inclusion test of a particular sensitive entity
283
284 If the entity is atomic, a simple SAT test is performed.
285 In case of a complex entity, the third level BVH tree is traversed.
286 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).
287 The result of detection is stored and the algorithm returns to the second stage.
288
289 @subsubsection occt_visu_2_2_3 Packages and classes
290
291 Selection is implemented as a combination of various algorithms divided among several packages -- *SelectBasics*, *Select3D*, *SelectMgr* and *StdSelect*.
292
293 #### SelectBasics
294
295 *SelectBasics* package contains basic classes and interfaces for selection.
296 The most notable are:
297   - *SelectBasics_PickResult* -- the structure for storing quantitative results of detection procedure, for example, depth and distance to the center of geometry;
298   - *SelectBasics_SelectingVolumeManager* -- the interface for interaction with the current selection frustum.
299
300 Each custom sensitive entity must inherit at least *SelectBasics_SensitiveEntity*.
301
302 #### Select3D
303
304 *Select3D* package provides a definition of standard sensitive entities, such as:
305   - box;
306   - circle;
307   - curve;
308   - face;
309   - group;
310   - point;
311   - segment;
312   - triangle;
313   - triangulation;
314   - wire.
315
316 Each basic sensitive entity inherits *Select3D_SensitiveEntity*.
317 The package also contains two auxiliary classes, *Select3D_SensitivePoly* and *Select3D_SensitiveSet*.
318
319 *Select3D_SensitiveEntity* -- the base definition of a sensitive entity.
320
321 *Select3D_SensitiveSet* -- a base class for all complex sensitive entities that require the third level BVH usage.
322 It implements traverse of the tree and defines an interface for the methods that check sub-entities.
323
324 *Select3D_SensitivePoly* -- describes an arbitrary point set and implements basic functions for selection.
325 It is important to know that this class does not perform any internal data checks.
326 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.
327
328 #### SelectMgr
329
330 *SelectMgr* package is used to maintain the whole selection process.
331 For this purpose, the package provides the following services:
332   - activation and deactivation of selection modes for all selectable objects;
333   - interfaces to compute selection mode of the object;
334   - definition of selection filter classes;
335   - keeping selection BVH data up-to-date.
336
337 A brief description of the main classes:
338   - *SelectMgr_BaseFrustum*, *SelectMgr_Frustum*, *SelectMgr_RectangularFrustum*, *SelectMgr_TriangularFrustum* and *SelectMgr_TriangularFrustumSet* -- interfaces and implementations of selecting frustums.
339     These classes implement different SAT tests for overlap and inclusion detection.
340     They also contain methods to measure characteristics of detected entities (depth, distance to center of geometry).
341   - *SelectMgr_SensitiveEntity*, *SelectMgr_Selection* and *SelectMgr_SensitiveEntitySet* -- store and handle sensitive entities.
342     *SelectMgr_SensitiveEntitySet* implements a primitive set for the second level BVH tree.
343   - *SelectMgr_SelectableObject* and *SelectMgr_SelectableObjectSet* -- describe selectable objects.
344     They also manage storage, calculation and removal of selections.
345     *SelectMgr_SelectableObjectSet* implements a primitive set for the first level BVH tree.
346   - *SelectMgr_ViewerSelector* -- encapsulates all logics of the selection algorithm and implements the third level BVH tree traverse.
347   - *SelectMgr_SelectionManager* -- manages activation/deactivation, calculation and update of selections of every selectable object, and keeps BVH data up-to-date.
348
349 #### StdSelect
350
351 *StdSelect* package contains the implementation of some *SelectMgr* classes and tools for creation of selection structures.
352 For example,
353   - *StdSelect_BRepOwner* -- defines an entity owner with a link to its topological shape and methods for highlighting;
354   - *StdSelect_BRepSelectionTool* -- contains algorithms for splitting standard AIS shapes into sensitive primitives;
355   - *StdSelect_FaceFilter*, *StdSelect_EdgeFilter* -- implementation of selection filters.
356
357 @subsubsection occt_visu_2_2_4 Examples of usage
358
359 The first code snippet illustrates the implementation of *SelectMgr_SelectableObject::ComputeSelection()* method in a custom interactive object.
360 The method is used for computation of user-defined selection modes.
361 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).
362 To select the whole box, the application can create a sensitive primitive for each face of the interactive object.
363 In this case, all primitives share the same owner -- the box itself.
364 To select box's edge, the application must create one sensitive primitive per edge.
365 Here all sensitive entities cannot share the owner since different geometric primitives must be highlighted as the result of selection procedure.
366
367 ~~~~{.cpp}
368 void InteractiveBox::ComputeSelection (const Handle(SelectMgr_Selection)& theSel,
369                                        const Standard_Integer theMode)
370 {
371   switch (theMode)
372   {
373     case 0:   // creation of face sensitives for selection of the whole box
374     {
375       Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this, 5);
376       for (Standard_Integer aFaceIter = 1; aFaceIter <= myNbFaces; ++aFaceIter)
377       {
378         Select3D_TypeOfSensitivity aSensType = myIsInterior;
379         theSel->Add (new Select3D_SensitiveFace (anOwner, myFaces[aFaceIter]->PointArray(), aSensType));
380       }
381       break;
382     }
383     case 1: // creation of edge sensitives for selection of box edges only
384     {
385       for (Standard_Integer anEdgeIter = 1; anEdgeIter <= 12; ++anEdgeIter)
386       {
387         // 1 owner per edge, where 6 is a priority of the sensitive
388         Handle(MySelection_EdgeOwner) anOwner = new MySelection_EdgeOwner (this, anEdgeIter, 6);
389         theSel->Add (new Select3D_SensitiveSegment (anOwner, myFirstPnt[anEdgeIter]), myLastPnt[anEdgeIter]));
390       }
391       break;
392     }
393   }
394 }
395 ~~~~
396
397 The algorithms for creating selection structures store sensitive primitives in *SelectMgr_Selection* instance.
398 Each *SelectMgr_Selection* sequence in the list of selections of the object must correspond to a particular selection mode.
399 To describe the decomposition of the object into selectable primitives, a set of ready-made sensitive entities is supplied in *Select3D* package.
400 Custom sensitive primitives can be defined through inheritance from *Select3D_SensitiveEntity*.
401 To make custom interactive objects selectable or customize selection modes of existing objects, the entity owners must be defined.
402 They must inherit *SelectMgr_EntityOwner* interface.
403
404 Selection structures for any interactive object are created in *SelectMgr_SelectableObject::ComputeSelection()* method.
405 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*.
406
407 ~~~~{.cpp}
408   void MyInteractiveObject::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
409                                               const Standard_Integer theMode)
410   {
411     switch (theMode)
412     {
413       case 0: StdSelect_BRepSelectionTool::Load (theSelection, this, myShape, TopAbs_SHAPE);  break;
414       case 1: StdSelect_BRepSelectionTool::Load (theSelection, this, myShape, TopAbs_VERTEX); break;
415       case 2: StdSelect_BRepSelectionTool::Load (theSelection, this, myShape, TopAbs_EDGE);   break;
416       case 3: StdSelect_BRepSelectionTool::Load (theSelection, this, myShape, TopAbs_WIRE);   break;
417       case 4: StdSelect_BRepSelectionTool::Load (theSelection, this, myShape, TopAbs_FACE);   break;
418     }
419   }
420 ~~~~
421
422 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*.
423
424 The traditional way of highlighting selected entity owners adopted by Open CASCADE Technology assumes that each entity owner highlights itself on its own.
425 This approach has two drawbacks:
426
427   - each entity owner has to maintain its own *Graphic3d_Structure* object, that results in a considerable memory overhead;
428   - drawing selected owners one by one is not efficient from the visualization point of view.
429
430 Therefore, to overcome these limitations, OCCT has an alternative way to implement the highlighting of a selected presentation.
431 Using this approach, the interactive object itself will be responsible for the highlighting, not the entity owner.
432
433 On the basis of *SelectMgr_EntityOwner::IsAutoHilight()* return value, *AIS_InteractiveContext* object either uses the traditional way of highlighting
434 (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()*,
435 passing a group of owners as an argument.
436
437 Hence, an application can derive its own interactive object and redefine virtual methods *HilightSelected()*, *ClearSelected()* and *HilightOwnerWithColor()* from *SelectMgr_SelectableObject*.
438 *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.
439
440 After all the necessary sensitive entities are computed and packed in *SelectMgr_Selection* instance with the corresponding owners
441 in a redefinition of *SelectMgr_SelectableObject::ComputeSelection()* method,
442 it is necessary to register the prepared selection in *SelectMgr_SelectionManager* through the following steps:
443   - if there was no *AIS_InteractiveContext* opened, create an interactive context and display the selectable object in it;
444   - load the selectable object to the selection manager of the interactive context using *AIS_InteractiveContext::Load()* method.
445     If the selection mode passed as a parameter to this method is not equal to -1, *ComputeSelection()* for this selection mode will be called;
446   - activate or deactivate the defined selection mode using *AIS_InteractiveContext::Activate()* or *AIS_InteractiveContext::Deactivate()* methods.
447
448 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.
449
450 The code snippet below illustrates the above steps.
451 It also contains the code to start the detection procedure and parse the results of selection.
452
453 ~~~~~{.cpp}
454 // Suppose there is an instance of class InteractiveBox from the previous sample.
455 // It contains an implementation of method InteractiveBox::ComputeSelection() for selection
456 // modes 0 (whole box must be selected) and 1 (edge of the box must be selectable)
457 Handle(InteractiveBox) theBox;
458 Handle(AIS_InteractiveContext) theContext;
459 // To prevent automatic activation of the default selection mode
460 theContext->SetAutoActivateSelection (false);
461 theContext->Display (theBox, false);
462
463 // Load a box to the selection manager without computation of any selection mode
464 theContext->Load (theBox, -1, true);
465 // Activate edge selection
466 theContext->Activate (theBox, 1);
467
468 // Run the detection mechanism for activated entities in the current mouse coordinates and in the current view.
469 // Detected owners will be highlighted with context highlight color
470 theContext->MoveTo (aXMousePos, aYMousePos, myView, false);
471 // Select the detected owners
472 theContext->Select();
473 // Iterate through the selected owners
474 for (theContext->InitSelected(); theContext->MoreSelected() && !aHasSelected; theContext->NextSelected())
475 {
476   Handle(AIS_InteractiveObject) anIO = theContext->SelectedInteractive();
477 }
478
479 // deactivate all selection modes for aBox1
480 theContext->Deactivate (aBox1);
481 ~~~~~
482
483 It is also important to know, that there are 2 types of detection implemented for rectangular selection in OCCT:
484   - <b>inclusive</b> detection.
485     In this case the sensitive primitive is considered detected only when all its points are included in the area defined by the selection rectangle;
486   - <b>overlap</b> detection.
487     In this case the sensitive primitive is considered detected when it is partially overlapped by the selection rectangle.
488
489 The standard OCCT selection mechanism uses inclusion detection by default.
490 To change this, use the following code:
491
492 ~~~~~{.cpp}
493 // Assume there is a created interactive context
494 const Handle(AIS_InteractiveContext) theContext;
495 // Retrieve the current viewer selector
496 const Handle(StdSelect_ViewerSelector3d)& aMainSelector = theContext->MainSelector();
497 // Set the flag to allow overlap detection
498 aMainSelector->AllowOverlapDetection (true);
499 ~~~~~
500
501 @section occt_visu_3 Application Interactive Services
502 @subsection occt_visu_3_1 Introduction
503
504 Application Interactive Services allow managing presentations and dynamic selection in a viewer in a simple and transparent manner.
505 The central entity for management of visualization and selections is the **Interactive Context** (*AIS_InteractiveContext*).
506 It is connected to the main viewer (*V3d_Viewer*).
507
508 Interactive context by default starts at **Neutral Point** with each selectable object picked as a whole,
509 but the user might activate **Local Selection** for specific objects to make selectable parts of the objects.
510 Local/global selection is managed by a list of selection modes activated for each displayed object with 0 (default selection mode) usually meaning Global (entire object) selection.
511
512 **Interactive Objects** (*AIS_InteractiveObject*) are the entities, which are visualized and selected.
513 You can use classes of standard interactive objects for which all necessary functions have already been programmed,
514 or you can implement your own classes of interactive objects, by respecting a certain number of rules and conventions described below.
515
516 An Interactive Object is a "virtual" entity, which can be presented and selected.
517 An Interactive Object can have a certain number of specific graphic attributes, such as visualization mode, color and material.
518 When an Interactive Object is visualized, the required graphic attributes are taken from its own **Drawer** (*Prs3d_Drawer*)
519 if it has the required custom attributes or otherwise from the context drawer.
520
521 @figure{visualization_image017.png,"",360}
522
523 It can be necessary to filter the entities to be selected.
524 Consequently there are **Filter** entities (*SelectMgr_Filter*), which allow refining the dynamic detection context.
525 Some of these filters can be used only within at the Neutral Point, others only within Local Selection.
526 It is possible to program custom filters and load them into the interactive context.
527
528 @subsection occt_visu_3_2 Interactive objects
529
530 Entities which are visualized and selected in the AIS viewer are objects (*AIS_InteractiveObject*).
531 They connect the underlying reference geometry of a model to its graphic representation in *AIS*.
532 You can use the predefined OCCT classes of standard interactive objects, for which all necessary functions have already been programmed,
533 or, if you are an advanced user, you can implement your own classes of interactive objects.
534
535 @subsubsection occt_visu_3_2_1 Presentations
536
537 An interactive object can have as many presentations as its creator wants to give it.
538 3D presentations are managed by **Presentation Manager** (*PrsMgr_PresentationManager*).
539 As this is transparent in AIS, the user does not have to worry about it.
540
541 A presentation is identified by an index (*Display Mode*) and by the reference to the Presentation Manager, which it depends on.
542 By convention, the default mode of representation for the Interactive Object has index 0.
543
544 @figure{visualization_image018.png,"",360}
545
546 Calculation of different presentations of an interactive object is done by the *Compute* functions inheriting from *PrsMgr_PresentableObject::Compute* functions.
547 They are automatically called by *PresentationManager* at a visualization or an update request.
548
549 If you are creating your own type of interactive object, you must implement the Compute function in one of the following ways:
550
551 #### For 3D:
552
553 ~~~~~{.cpp}
554 void PackageName_ClassName::Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
555                                      const Handle(Prs3d_Presentation)& thePresentation,
556                                      const Standard_Integer theMode);
557 ~~~~~
558
559 #### For hidden line removal (HLR) mode in 3D:
560
561 ~~~~~{.cpp}
562 void PackageName_ClassName::Compute (const Handle(Prs3d_Projector)& theProjector,
563                                      const Handle(Prs3d_Presentation)& thePresentation);
564 ~~~~~
565
566 @subsubsection occt_visu_3_2_2 Hidden Line Removal
567
568 The view can have two states: the normal mode or the computed mode (Hidden Line Removal mode).
569 When the latter is active, the view looks for all presentations displayed in the normal mode, which have been signaled as accepting HLR mode.
570 An internal mechanism allows calling the interactive object's own *Compute*, that is projector function.
571
572 By convention, the Interactive Object accepts or rejects the representation of HLR mode.
573 It is possible to make this declaration in one of two ways:
574
575 * Initially by using one of the values of the enumeration *PrsMgr_TypeOfPresentation3d*:
576   * *PrsMgr_TOP_AllView*,
577   * *PrsMgr_TOP_ProjectorDependant*
578
579 * Later by using the function *PrsMgr_PresentableObject::SetTypeOfPresentation*
580
581 *AIS_Shape* class is an example of an interactive object that supports HLR representation.
582 The type of the HLR algorithm is stored in *Prs3d_Drawer* of the shape.
583 It is a value of the *Prs3d_TypeOfHLR* enumeration and can be set to:
584   * *Prs3d_TOH_PolyAlgo* for a polygonal algorithm based on the shape's triangulation;
585   * *Prs3d_TOH_Algo*  for an exact algorithm that works with the shape's real geometry;
586   * *Prs3d_TOH_NotSet*  if the type of algorithm is not set for the given interactive object instance.
587
588 The type of the HLR algorithm used for *AIS_Shape* can be changed by calling the *AIS_Shape::SetTypeOfHLR()* method.
589 The current HLR algorithm type can be obtained using *AIS_Shape::TypeOfHLR()* method is to be used.
590
591 These methods get the value from the drawer of *AIS_Shape*.
592 If the HLR algorithm type in the *Prs3d_Drawer* is set to *Prs3d_TOH_NotSet*, the *Prs3d_Drawer* gets the value from the default drawer of *AIS_InteractiveContext*.
593 So it is possible to change the default HLR algorithm used by all newly displayed interactive objects.
594 The value of the HLR algorithm type stored in the context drawer can be *Prs3d_TOH_Algo* or *Prs3d_TOH_PolyAlgo*.
595 The polygonal algorithm is the default one.
596
597 @subsubsection occt_visu_3_2_3 Presentation modes
598
599 There are four types of interactive objects in AIS:
600   * the "construction element" or Datum,
601   * the Relation (dimensions and constraints)
602   * the Object
603   * the None type (when the object is of an unknown type).
604
605 Inside these categories, additional characterization is available by means of a signature (an index).
606 By default, the interactive object has a NONE type and a signature of 0 (equivalent to NONE).
607 If you want to give a particular type and signature to your interactive object, you must redefine two virtual functions:
608   * *AIS_InteractiveObject::Type*
609   * *AIS_InteractiveObject::Signature*.
610
611 **Note** that some signatures are already used by "standard" objects provided in AIS (see the @ref occt_visu_3_5 "List of Standard Interactive Object Classes").
612
613 The interactive context can have a default mode of representation for the set of interactive objects.
614 This mode may not be accepted by a given class of objects.
615 Consequently, to get information about this class it is necessary to use virtual function *AIS_InteractiveObject::AcceptDisplayMode*.
616
617 #### Display Mode
618
619 The functions *AIS_InteractiveContext::SetDisplayMode* and *AIS_InteractiveContext::UnsetDisplayMode* allow setting a custom display mode for an objects,
620 which can be different from that proposed by the interactive context.
621
622 #### Highlight Mode
623
624 At dynamic detection, the presentation echoed by the Interactive Context, is by default the presentation already on the screen.
625
626 The functions *AIS_InteractiveObject::SetHilightMode* and *AIS_InteractiveObject::UnsetHilightMode* allow specifying the display mode used for highlighting (so called highlight mode),
627 which is valid independently from the active representation of the object.
628 It makes no difference whether this choice is temporary or definitive.
629
630 Note that the same presentation (and consequently the same highlight mode) is used for highlighting *detected* objects and for highlighting *selected* objects,
631 the latter being drawn with a special *selection color* (refer to the section related to *Interactive Context* services).
632
633 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.
634 Thus, you set the highlight mode to *0* in the constructor of the interactive object.
635 Do not forget to implement this representation mode in the *Compute* functions.
636
637 #### Infinite Status
638
639 If you do not want an object to be affected by a *FitAll* view, you must declare it infinite;
640 you can cancel its "infinite" status using *AIS_InteractiveObject::SetInfiniteState* and *AIS_InteractiveObject::IsInfinite* functions.
641
642 Let us take for example the class called *IShape* representing an interactive object:
643
644 ~~~~~{.cpp}
645 myPk_IShape::myPk_IShape (const TopoDS_Shape& theShape, PrsMgr_TypeOfPresentation theType)
646 : AIS_InteractiveObject (theType), myShape (theShape) { SetHilightMode (0); }
647
648 Standard_Boolean myPk_IShape::AcceptDisplayMode (const Standard_Integer theMode) const
649 {
650   return theMode == 0 || theMode == 1;
651 }
652
653 void myPk_IShape::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
654                            const Handle(Prs3d_Presentation)& thePrs,
655                            const Standard_Integer theMode)
656 {
657   switch (theMode)
658   {
659     // algo for calculation of wireframe presentation
660     case 0: StdPrs_WFDeflectionShape::Add (thePrs, myShape, myDrawer); return;
661     // algo for calculation of shading presentation
662     case 1: StdPrs_ShadedShape::Add (thePrs, myShape, myDrawer); return;
663   }
664 }
665
666 void myPk_IShape::Compute (const Handle(Prs3d_Projector)& theProjector,
667                            const Handle(Prs3d_Presentation)& thePrs)
668 {
669   // Hidden line mode calculation algorithm
670   StdPrs_HLRPolyShape::Add (thePrs, myShape, myDrawer, theProjector);
671 }  
672 ~~~~~
673
674 @subsubsection occt_visu_3_2_4 Selection
675
676 An interactive object can have an indefinite number of selection modes, each representing a "decomposition" into sensitive primitives.
677 Each primitive has an **Owner** (*SelectMgr_EntityOwner*) which allows identifying the exact interactive object or shape which has been detected (see @ref occt_visu_2_2 "Selection" chapter).
678
679 The set of sensitive primitives, which correspond to a given mode, is stocked in a **Selection** (*SelectMgr_Selection*).
680
681 Each selection mode is identified by an index.
682 By convention, the default selection mode that allows us to grasp the interactive object in its entirety is mode *0*.
683 However, it can be modified in the custom interactive objects using method *SelectMgr_SelectableObject::setGlobalSelMode()*.
684
685 The calculation of selection primitives (or sensitive entities) is done in a virtual function *ComputeSelection*.
686 It should be implemented for each type of interactive object that is assumed to have different selection modes using the function *AIS_InteractiveObject::ComputeSelection*.
687 A detailed explanation of the mechanism and the manner of implementing this function has been given in @ref occt_visu_2_2 "Selection" chapter.
688
689 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).
690 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*.
691     
692 @subsubsection occt_visu_3_2_5 Graphic attributes
693
694 Graphic attributes manager, or *Prs3d_Drawer*, stores graphic attributes for specific interactive objects and for interactive objects controlled by interactive context.
695
696 Initially, all drawer attributes are filled out with the predefined values which will define the default 3D object appearance.
697 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.
698
699 Keep in mind the following points concerning graphic attributes:
700   * Each interactive object can have its own visualization attributes.
701   * By default, the interactive object takes the graphic attributes of the context in which it is visualized
702     (visualization mode, deflection values for the calculation of presentations, number of isoparameters, color, type of line, material, etc.)
703   * In the *AIS_InteractiveObject* abstract class, standard attributes including color, line thickness, material, and transparency have been privileged.
704     Consequently, there is a certain number of virtual functions, which allow acting on these attributes.
705     Each new class of interactive object can redefine these functions and change the behavior of the class.
706
707 @figure{visualization_image020.svg,"Redefinition of virtual functions for changes in AIS_Shape and AIS_TextLabel.",360}
708
709 The following virtual functions provide settings for color, width, material and transparency:
710   * *AIS_InteractiveObject::UnsetColor*
711   * *AIS_InteractiveObject::SetWidth*
712   * *AIS_InteractiveObject::UnsetWidth*
713   * *AIS_InteractiveObject::SetMaterial*
714   * *AIS_InteractiveObject::UnsetMaterial*
715   * *AIS_InteractiveObject::SetTransparency*
716   * *AIS_InteractiveObject::UnsetTransparency*
717
718 These methods can be used as a shortcut assigning properties in common way, but result might be not available.
719 Some interactive objects might not implement these methods at all or implement only a sub-set of them.
720 Direct modification of *Prs3d_Drawer* properties returned by *AIS_InteractiveObject::Attributes* can be used for more precise and predictable configuration.
721
722 It is important to know which functions may imply the recalculation of presentations of the object.
723 If the presentation mode of an interactive object is to be updated, a flag from *PrsMgr_PresentableObject* indicates this.
724 The mode can be updated using the functions *Display* and *Redisplay* in *AIS_InteractiveContext*.
725
726 @subsubsection occt_visu_3_2_6 Complementary Services
727
728 When you use complementary services for interactive objects, pay special attention to the cases mentioned below.
729
730 #### Change the location of an interactive object
731
732 The following functions allow "moving" the representation and selection of Interactive Objects in a view without recalculation (and modification of the original shape).
733   * *AIS_InteractiveContext::SetLocation*
734   * *AIS_InteractiveContext::ResetLocation*
735   * *AIS_InteractiveContext::HasLocation*
736   * *AIS_InteractiveContext::Location*
737
738 #### Connect an interactive object to an applicative entity
739
740 Each Interactive Object has functions that allow attributing it an *GetOwner* in form of a *Transient*.
741   * *AIS_InteractiveObject::SetOwner*
742   * *AIS_InteractiveObject::HasOwner*
743   * *AIS_InteractiveObject::GetOwner*
744
745 An interactive object can therefore be associated or not with an applicative entity, without affecting its behavior.
746
747 **NOTE:** Don't be confused by owners of another kind - *SelectMgr_EntityOwner* used for identifying selectable parts of the object or object itself.
748
749 #### Resolving coincident topology
750
751 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.
752
753 To the problem when the elements of two or more Interactive Objects are coincident you can apply the polygon offset.
754 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.
755 The graphical elements that accept this kind of offsets are solid polygons or displayed as boundary lines and points.
756 The polygons could be displayed as lines or points by setting the appropriate interior style.
757
758 The methods *AIS_InteractiveObject::SetPolygonOffsets* and *AIS_InteractiveContext::SetPolygonOffsets* allow setting up the polygon offsets.
759
760 @subsubsection occt_visu_3_2_7 Object hierarchy
761
762 Each *PrsMgr_PresentableObject* has a list of objects called *myChildren*.
763 Any transformation of *PrsMgr_PresentableObject* is also applied to its children.
764 This hierarchy does not propagate to *Graphic3d* level and below.
765
766 *PrsMgr_PresentableObject* sends its combined (according to the hierarchy) transformation down to *Graphic3d_Structure*.
767 The materials of structures are not affected by the hierarchy.
768
769 Object hierarchy can be controlled by the following API calls:
770 * *PrsMgr_PresentableObject::AddChild*;
771 * *PrsMgr_PresentableObject::RemoveChild*.
772
773 @subsubsection occt_visu_3_2_8 Instancing
774
775 The conception of instancing operates the object hierarchy as follows:
776 * Instances are represented by separated *AIS* objects.
777 * Instances do not compute any presentations.
778
779 Classes *AIS_ConnectedInteractive* and *AIS_MultipleConnectedInteractive* are used to implement this conception.
780
781 *AIS_ConnectedInteractive* is an object instance, which reuses the geometry of the connected object but has its own transformation and visibility flag.
782 This connection is propagated down to *OpenGl* level, namely to *OpenGl_Structure*.
783 *OpenGl_Structure* can be connected only to a single other structure.
784
785 *AIS_ConnectedInteractive* can be referenced to any *AIS_InteractiveObject* in general.
786 When it is referenced to another *AIS_ConnectedInteractive*, it just copies the reference.
787
788 *AIS_MultipleConnectedInteractive* represents an assembly, which does not have its own presentation.
789 The assemblies are able to participate in the object hierarchy and are intended to handle a grouped set of instanced objects.
790 It behaves as a single object in terms of selection.
791 It applies high level transformation to all sub-elements since it is located above in the hierarchy.
792
793 All *AIS_MultipleConnectedInteractive* are able to have child assemblies.
794 Deep copy of object instances tree is performed if one assembly is attached to another.
795
796 Note that *AIS_ConnectedInteractive* cannot reference *AIS_MultipleConnectedInteractive*.
797 *AIS_ConnectedInteractive* copies sensitive entities of the origin object for selection, unlike *AIS_MultipleConnectedInteractive* that re-uses the entities of the origin object.
798
799 Instances can be controlled by the following DRAW commands:
800 * *vconnect* : Creates and displays *AIS_MultipleConnectedInteractive* object from input objects and location.
801 * *vconnectto* : Makes an instance of object with the given position.
802 * *vdisconnect* : Disconnects all objects from an assembly or disconnects an object by name or number.
803 * *vaddconnected* : Adds an object to the assembly.
804 * *vlistconnected* : Lists objects in the assembly.
805
806 Have a look at the examples below:
807 ~~~~~
808 pload MODELING VISUALIZATION
809 vinit
810 psphere s 1
811 vdisplay s
812 vconnectto s2 3 0 0 s  # make instance
813 vfit
814 ~~~~~
815
816 See how proxy *OpenGl_Structure* is used to represent instance:
817
818 @figure{/user_guides/visualization/images/visualization_image029.png,"",240}
819
820 The original object does not have to be displayed in order to make instance.
821 Also selection handles transformations of instances correctly:
822
823 ~~~~~
824 pload MODELING VISUALIZATION
825 vinit
826 psphere s 1
827 psphere p 0.5
828 vdisplay s             # p is not displayed
829 vsetloc s -2 0 0
830 vconnect x 3 0 0 s p   # make assembly
831 vfit
832 ~~~~~
833
834 @figure{/user_guides/visualization/images/visualization_image030.png,"",420}
835
836 Here is the example of a more complex hierarchy involving sub-assemblies:
837
838 ~~~~~
839 pload MODELING VISUALIZATION
840 vinit
841 box b 1 1 1
842 psphere s 0.5
843 vdisplay b s
844 vsetlocation s 0 2.5 0
845 box d 0.5 0.5 3
846 box d2 0.5 3 0.5
847 vdisplay d d2
848
849 vconnectto b1 -2 0 0 b
850 vconnect z 2 0 0 b s
851 vconnect z2 4 0 0 d d2
852 vconnect z3 6 0 0 z z2
853 vfit
854 ~~~~~
855
856 @subsection occt_visu_3_3 Interactive Context
857
858 @subsubsection occt_visu_3_3_1 Rules
859
860 The Interactive Context allows managing in a transparent way the graphic and **selectable** behavior of interactive objects in one or more viewers.
861 Most functions which allow modifying the attributes of interactive objects, and which were presented in the preceding chapter, will be looked at again here.
862
863 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.
864 You can only directly call the functions available for an interactive object if it has not been loaded into an Interactive Context.
865
866 ~~~~~{.cpp}
867 Handle(AIS_Shape) aShapePrs = new AIS_Shape (theShape);
868 myIntContext->Display (aShapePrs, AIS_Shaded, 0, false, aShapePrs->AcceptShapeDecomposition());
869 myIntContext->SetColor(aShapePrs, Quantity_NOC_RED);
870 ~~~~~
871
872 You can also write
873
874 ~~~~~{.cpp}
875 Handle(AIS_Shape) aShapePrs = new AIS_Shape (theShape);
876 aShapePrs->SetColor (Quantity_NOC_RED);
877 aShapePrs->SetDisplayMode (AIS_Shaded);
878 myIntContext->Display (aShapePrs);
879 ~~~~~
880
881 @subsubsection occt_visu_3_3_2 Groups of functions
882
883 **Neutral Point** and **Local Selection** constitute the two operating modes or states of the **Interactive Context**,
884 which is the central entity which pilots visualizations and selections.
885 The **Neutral Point**, which is the default mode, allows easily visualizing and selecting interactive objects, which have been loaded into the context.
886 Activating **Local Selection** for specific Objects allows selecting of their sub-parts.
887
888 @subsubsection occt_visu_3_3_3 Management of the Interactive Context
889
890 An interactive object can have a certain number of specific graphic attributes, such as visualization mode, color, and material.
891 Correspondingly, the interactive context has a set of graphic attributes, the *Drawer*, which is valid by default for the objects it controls.
892 When an interactive object is visualized, the required graphic attributes are first taken from the object's own *Drawer* if it exists, or from the context drawer if otherwise.
893
894 The following adjustable settings allow personalizing the behavior of presentations and selections:
895   * Default Drawer, containing all the color and line attributes which can be used by interactive objects, which do not have their own attributes.
896   * Default Visualization Mode for interactive objects. By default: *mode 0*;
897   * Highlight color of entities detected by mouse movement. By default: *Quantity_NOC_CYAN1*;
898   * Pre-selection color. By default: *Quantity_NOC_GREEN*;
899   * Selection color (when you click on a detected object). By default: *Quantity_NOC_GRAY80*;
900
901 All of these settings can be modified by functions proper to the AIS_InteractiveContext.
902 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.
903
904 Let us examine the case of two interactive objects: *theObj1* and *theObj2*:
905
906 ~~~~~{.cpp}
907 theCtx->Display (theObj1, false);
908 theCtx->Display (theObj2, true);  // TRUE for viewer update
909 theCtx->SetDisplayMode (theObj1, 3, false);
910 theCtx->SetDisplayMode (2, true);
911 // theObj2 is visualized in mode 2 (if it accepts this mode)
912 // theObj1 stays visualized in its mode 3
913 ~~~~~
914
915 *PrsMgr_PresentationManager* and *SelectMgr_ViewerSelector3d*, which manage the presentation and selection of present interactive objects, are associated to the main Viewer.
916
917 *WARNING!* Do NOT use integer values (like in sample above) in real code - use appropriate enumerations instead!
918 Each presentable object has independent list of supported display and selection modes; for instance, *AIS_DisplayMode* enumeration is applicable only to *AIS_Shape* presentations.
919
920 @subsection occt_visu_3_4 Local Selection
921
922 @subsubsection occt_visu_3_4_1 Selection Modes
923
924 The Local Selection is defined by index (Selection Mode).
925 The Selection Modes implemented by a specific interactive object and their meaning should be checked within the documentation of this class.
926 See, for example, *MeshVS_SelectionModeFlags* for *MeshVS_Mesh* object.
927
928 *AIS_Shape* is the most used interactive object.
929 It provides API to manage selection operations on the constituent elements of shapes (selection of vertices, edges, faces, etc.).
930 The Selection Mode for a specific shape type (*TopAbs_ShapeEnum*) is returned by method *AIS_Shape::SelectionMode()*.
931
932 The method *AIS_InteractiveContext::Display()* without a Selection Mode argument activates the default Selection Mode of the object.
933 The methods *AIS_InteractiveContext::Activate()* and *AIS_InteractiveContext::Deactivate()* activate and deactivate a specific Selection Mode.
934
935 More than one Selection Mode can be activated at the same time (but default 0 mode for selecting entire object is exclusive - it cannot be combined with others).
936 The list of active modes can be retrieved using function *AIS_InteractiveContext::ActivatedModes*.
937
938 @subsubsection occt_visu_3_4_2 Filters
939
940 To define an environment of dynamic detection, you can use standard filter classes or create your own.
941 A filter questions the owner of the sensitive primitive to determine if it has the desired qualities.
942 If it answers positively, it is kept. If not, it is rejected.
943
944 The root class of objects is *SelectMgr_Filter*.
945 The principle behind it is straightforward: a filter tests to see whether the owners (*SelectMgr_EntityOwner*) detected in mouse position by selector answer *OK*.
946 If so, it is kept, otherwise it is rejected.
947 You can create a custom class of filter objects by implementing the deferred function *SelectMgr_Filter::IsOk()*.
948
949 In *SelectMgr*, there are also Composition filters (AND Filters, OR Filters), which allow combining several filters.
950 In Interactive Context, all filters that you add are stored in an OR filter (which answers *OK* if at least one filter answers *OK*).
951
952 There are Standard filters, which have already been implemented in several packages:
953   * *StdSelect_EdgeFilter* -- for edges, such as lines and circles;
954   * *StdSelect_FaceFilter* -- for faces, such as planes, cylinders and spheres;
955   * *StdSelect_ShapeTypeFilter* -- for shape types, such as compounds, solids, shells and wires;
956   * *AIS_TypeFilter* -- for types of interactive objects;
957   * *AIS_SignatureFilter* -- for types and signatures of interactive objects;
958   * *AIS_AttributeFilter* -- for attributes of Interactive Objects, such as color and width.
959
960 There are several functions to manipulate filters:
961 * *AIS_InteractiveContext::AddFilter* adds a filter passed as an argument.
962 * *AIS_InteractiveContext::RemoveFilter* removes a filter passed as an argument.
963 * *AIS_InteractiveContext::RemoveFilters* removes all present filters.
964 * *AIS_InteractiveContext::Filters* gets the list of filters active in a context.
965
966 #### Example
967
968 ~~~~~{.cpp}
969 // shading visualization mode, no specific mode, authorization for decomposition into sub-shapes
970 const TopoDS_Shape theShape;
971 Handle(AIS_Shape) aShapePrs = new AIS_Shape (theShape);
972 myContext->Display (aShapePrs, AIS_Shaded, -1, true, true);
973
974 // activates decomposition of shapes into faces
975 const int aSubShapeSelMode = AIS_Shape::SelectionMode (TopAbs_Face);
976 myContext->Activate (aShapePrs, aSubShapeSelMode);
977
978 Handle(StdSelect_FaceFilter) aFil1 = new StdSelect_FaceFilter (StdSelect_Revol);
979 Handle(StdSelect_FaceFilter) aFil2 = new StdSelect_FaceFilter (StdSelect_Plane);
980 myContext->AddFilter (aFil1);
981 myContext->AddFilter (aFil2);
982
983 // only faces of revolution or planar faces will be selected
984 myContext->MoveTo (thePixelX, thePixelY, myView, true);
985 ~~~~~
986
987 @subsubsection occt_visu_3_4_6 Selection
988
989 Dynamic detection and selection are put into effect in a straightforward way.
990 There are only a few conventions and functions to be familiar with:
991   * *AIS_InteractiveContext::MoveTo* -- passes mouse position to Interactive Context selectors.
992   * *AIS_InteractiveContext::SelectDetected* -- stores what has been detected at the last *MoveTo*.
993     Changes the previously selected object. Depending on the selection scheme, the selection is enriched, replaced or other.
994   * *AIS_InteractiveContext::SelectPoint/SelectRectangle/SelectPolygon* -- Applies selection to point, rectangular or surrounding area.
995     Changes the previously selected object. Depending on the selection scheme, the selection is enriched, replaced or other.
996
997 Highlighting of detected and selected entities is automatically managed by the Interactive Context.
998 The Highlight colors are those dealt with above. You can nonetheless disconnect this automatic mode if you want to manage this part yourself:
999 ~~~~~{.cpp}
1000   AIS_InteractiveContext::SetAutomaticHilight
1001   AIS_InteractiveContext::AutomaticHilight
1002 ~~~~~
1003
1004 You can question the Interactive context by moving the mouse.
1005 The following functions can be used:
1006   * *AIS_InteractiveContext::HasDetected* -- checks if there is a detected entity;
1007   * *AIS_InteractiveContext::DetectedOwner* -- returns the (currently highlighted) detected entity.
1008
1009 After using the *Select* function, you can explore the list of selections.
1010 The following functions can be used:
1011   * *AIS_InteractiveContext::InitSelected* -- initializes an iterator;
1012   * *AIS_InteractiveContext::MoreSelected* -- checks if the iterator is valid;
1013   * *AIS_InteractiveContext::NextSelected* -- moves the iterator to the next position;
1014   * *AIS_InteractiveContext::SelectedOwner* -- returns an entity at the current iterator position.
1015
1016 The owner object *SelectMgr_EntityOwner* is a key object identifying the selectable entity in the viewer (returned by methods *AIS_InteractiveContext::DetectedOwner* and *AIS_InteractiveContext::SelectedOwner*).
1017 The Interactive Object itself can be retrieved by method *SelectMgr_EntityOwner::Selectable*, while identifying a sub-part depends on the type of Interactive Object.
1018 In case of *AIS_Shape*, the (sub)shape is returned by method *StdSelect_BRepOwner::Shape*.
1019
1020 #### Example
1021
1022 ~~~~~{.cpp}
1023 for (myAISCtx->InitSelected(); myAISCtx->MoreSelected(); myAISCtx->NextSelected())
1024 {
1025   Handle(SelectMgr_EntityOwner) anOwner = myAISCtx->SelectedOwner();
1026   Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
1027   if (Handle(StdSelect_BRepOwner) aBRepOwner = Handle(StdSelect_BRepOwner)::DownCast (anOwner))
1028   {
1029     // to be able to use the picked shape
1030     TopoDS_Shape aShape = aBRepOwner->Shape();
1031   }
1032 }
1033 ~~~~~
1034
1035 @subsubsection occt_visu_3_4_7 Selection schemes
1036
1037 Select* methods of AIS_InteractiveContext accept some selection scheme as parameter. The table below describes available selection schemes.
1038
1039 | Type | Reaction on click |  | Type | Reaction on click |
1040 | :----- | :----- | :----- | :----- | :----- |
1041 | AIS_SelectionScheme_Replace | @figure{visualization_selection_scheme_replace.svg, ""} |  | AIS_SelectionScheme_XOR | @figure{visualization_selection_scheme_XOR.svg, ""} |
1042 | AIS_SelectionScheme_Add | @figure{visualization_selection_scheme_add.svg, ""} |  | AIS_SelectionScheme_Clear | @figure{visualization_selection_scheme_clear.svg, ""} |
1043 | AIS_SelectionScheme_Remove | @figure{visualization_selection_scheme_remove.svg, ""} |  |  |  |
1044
1045
1046 @subsection occt_visu_3_5 Standard Interactive Object Classes
1047
1048 Interactive Objects are selectable and viewable objects connecting graphic representation and the underlying reference geometry.
1049
1050 They are divided into four types:
1051   * the **Datum** -- a construction geometric element;
1052   * the **Relation** -- a constraint on the interactive shape and the corresponding reference geometry;
1053   * the **Object** -- a topological shape or connection between shapes;
1054   * **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.
1055
1056 Inside these categories, there is a possibility of additional characterization by means of a signature.
1057 The signature provides an index to the further characterization.
1058 By default, the **Interactive Object** has a *None* type and a signature of 0 (equivalent to *None*).
1059 If you want to give a particular type and signature to your interactive object, you must redefine the two virtual methods: *Type* and *Signature*.
1060
1061 @subsubsection occt_visu_3_5_1 Datum
1062
1063 The **Datum** groups together the construction elements such as lines, circles, points, trihedrons, plane trihedrons, planes and axes.
1064
1065 *AIS_Point, AIS_Axis, AIS_Line, AIS_Circle, AIS_Plane* and *AIS_Trihedron* have four selection modes:
1066   * mode AIS_TrihedronSelectionMode_EntireObject : selection of a trihedron;
1067   * mode AIS_TrihedronSelectionMode_Origin : selection of the origin of the trihedron;
1068   * mode AIS_TrihedronSelectionMode_Axes : selection of the axes;
1069   * mode AIS_TrihedronSelectionMode_MainPlanes : selection of the planes XOY, YOZ, XOZ.
1070
1071 when you activate one of modes, you pick AIS objects of type:
1072   * *AIS_Point*;
1073   * *AIS_Axis* (and information on the type of axis);
1074   * *AIS_Plane* (and information on the type of plane).
1075
1076 *AIS_PlaneTrihedron* offers three selection modes:
1077   * mode 0 : selection of the whole trihedron;
1078   * mode 1 : selection of the origin of the trihedron;
1079   * mode 2 : selection of the axes -- same remarks as for the Trihedron.
1080
1081 For the presentation of planes and trihedra, the default length unit is millimeter and the default value for the representation of axes is 10.
1082 To modify these dimensions, you must temporarily recover the object **Drawer**.
1083 From it, take the *DatumAspect()* and  change the value *FirstAxisLength*.
1084 Finally, recalculate the presentation.
1085
1086 @subsubsection occt_visu_3_5_2 Object
1087
1088 The **Object** type includes topological shapes, and connections between shapes.
1089
1090 *AIS_Shape* has two visualization modes:
1091   * mode AIS_WireFrame : Line (default mode)
1092   * mode AIS_Shaded : Shading (depending on the type of shape)
1093
1094 *AIS_ConnectedInteractive* is an Interactive Object connecting to another interactive object reference,
1095 and located elsewhere in the viewer makes it possible not to calculate presentation and selection, but to deduce them from your object reference.
1096 *AIS_MultipleConnectedInteractive* is an object connected to a list of interactive objects
1097 (which can also be Connected objects; it does not require memory-hungry presentation calculations).
1098
1099 *MeshVS_Mesh* is an Interactive Object that represents meshes, it has a data source that provides geometrical information (nodes, elements)
1100 and can be built up from the source data with a custom presentation builder.
1101
1102 The class *AIS_ColoredShape* allows using custom colors and line widths for *TopoDS_Shape* objects and their sub-shapes.
1103
1104 ~~~~~{.cpp}
1105   AIS_ColoredShape aColoredShape = new AIS_ColoredShape (theShape);
1106
1107   // setup color of entire shape
1108   aColoredShape->SetColor (Quantity_NOC_RED);
1109
1110   // setup line width of entire shape
1111   aColoredShape->SetWidth (1.0);
1112
1113   // set transparency value
1114   aColoredShape->SetTransparency (0.5);
1115
1116   // customize color of specified sub-shape
1117   aColoredShape->SetCustomColor (theSubShape, Quantity_NOC_BLUE1);
1118
1119   // customize line width of specified sub-shape
1120   aColoredShape->SetCustomWidth (theSubShape, 0.25);
1121 ~~~~~
1122
1123 The presentation class *AIS_PointCloud* can be used for efficient drawing of large arbitrary sets of colored points.
1124 It uses *Graphic3d_ArrayOfPoints* to pass point data into OpenGl graphic driver to draw a set points as an array of "point sprites".
1125 The point data is packed into vertex buffer object for performance.
1126 - The type of point marker used to draw points can be specified as a presentation aspect.
1127 - The presentation provides selection by a bounding box of the visualized set of points.
1128   It supports two display / highlighting modes: points or bounding box.
1129
1130 @figure{point_cloud.png,"A random colored cloud of points",240}
1131
1132 Example:
1133 ~~~~~{.cpp}
1134 Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (2000, Standard_True);
1135 aPoints->AddVertex (gp_Pnt(-40.0, -40.0, -40.0), Quantity_Color (Quantity_NOC_BLUE1));
1136 aPoints->AddVertex (gp_Pnt (40.0,  40.0,  40.0), Quantity_Color (Quantity_NOC_BLUE2));
1137
1138 Handle(AIS_PointCloud) aPntCloud = new AIS_PointCloud();
1139 aPntCloud->SetPoints (aPoints);
1140 ~~~~~
1141
1142 The draw command *vpointcloud* builds a cloud of points from shape triangulation.
1143 This command can also draw a sphere surface or a volume with a large amount of points (more than one million).
1144
1145 @subsubsection occt_visu_3_5_3 Relations 
1146
1147 The **Relation** is made up of constraints on one or more interactive shapes and the corresponding reference geometry.
1148 For example, you might want to constrain two edges in a parallel relation.
1149 This constraint is considered as an object in its own right, and is shown as a sensitive primitive.
1150 This takes the graphic form of a perpendicular arrow marked with the || symbol and lying between the two edges.
1151
1152 The following relations are provided by *PrsDim*:
1153   * *PrsDim_ConcentricRelation*
1154   * *PrsDim_FixRelation*
1155   * *PrsDim_IdenticRelation*
1156   * *PrsDim_ParallelRelation*
1157   * *PrsDim_PerpendicularRelation*
1158   * *PrsDim_Relation*
1159   * *PrsDim_SymmetricRelation*
1160   * *PrsDim_TangentRelation*
1161
1162 The list of relations is not exhaustive.
1163
1164 @subsubsection occt_visu_3_5_4 Dimensions
1165   * *PrsDim_AngleDimension*
1166   * *PrsDim_Chamf3dDimension*
1167   * *PrsDim_DiameterDimension*
1168   * *PrsDim_DimensionOwner*
1169   * *PrsDim_LengthDimension*
1170   * *PrsDim_OffsetDimension*
1171   * *PrsDim_RadiusDimension*
1172
1173 @subsubsection occt_visu_3_5_5 MeshVS_Mesh
1174
1175 *MeshVS_Mesh* is an Interactive Object that represents meshes.
1176 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.
1177 As a result, you can provide your own data source.
1178
1179 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.
1180
1181 The presentations of *MeshVS_Mesh* are built with the presentation builders *MeshVS_PrsBuilder*.
1182 You can choose between the builders to represent the object in a different way.
1183 Moreover, you can redefine the base builder class and provide your own presentation builder.
1184
1185 You can add/remove builders using the following methods:
1186 ~~~~~{.cpp}
1187   MeshVS_Mesh::AddBuilder (const Handle(MeshVS_PrsBuilder)& theBuilder, Standard_Boolean theToTreatAsHilighter);
1188   MeshVS_Mesh::RemoveBuilder (const Standard_Integer theIndex);
1189   MeshVS_Mesh::RemoveBuilderById (const Standard_Integer theId);
1190 ~~~~~
1191
1192 There is a set of reserved display and highlighting mode flags for *MeshVS_Mesh*.
1193 Mode value is a number of bits that allows selecting additional display parameters and combining the following mode flags,
1194 which allow displaying mesh in wireframe, shading and shrink modes:
1195 ~~~~~{.cpp}
1196   MeshVS_DMF_WireFrame
1197   MeshVS_DMF_Shading
1198   MeshVS_DMF_Shrink
1199 ~~~~~
1200
1201 It is also possible to display deformed mesh in wireframe, shading or shrink modes using:
1202 ~~~~~{.cpp}
1203   MeshVS_DMF_DeformedPrsWireFrame
1204   MeshVS_DMF_DeformedPrsShading
1205   MeshVS_DMF_DeformedPrsShrink
1206 ~~~~~
1207
1208 The following methods represent different kinds of data:
1209 ~~~~~{.cpp}
1210   MeshVS_DMF_VectorDataPrs
1211   MeshVS_DMF_NodalColorDataPrs
1212   MeshVS_DMF_ElementalColorDataPrs
1213   MeshVS_DMF_TextDataPrs
1214   MeshVS_DMF_EntitiesWithData
1215 ~~~~~
1216
1217 The following methods provide selection and highlighting:
1218 ~~~~~{.cpp}
1219   MeshVS_DMF_SelectionPrs
1220   MeshVS_DMF_HilightPrs
1221 ~~~~~
1222
1223 *MeshVS_DMF_User* is a user-defined mode.
1224
1225 These values will be used by the presentation builder.
1226 There is also a set of selection modes flags that can be grouped in a combination of bits:
1227   * *MeshVS_SMF_0D*
1228   * *MeshVS_SMF_Link*
1229   * *MeshVS_SMF_Face*
1230   * *MeshVS_SMF_Volume*
1231   * *MeshVS_SMF_Element* -- groups *0D, Link, Face* and *Volume* as a bit mask;
1232   * *MeshVS_SMF_Node*
1233   * *MeshVS_SMF_All* -- groups *Element* and *Node* as a bit mask;
1234   * *MeshVS_SMF_Mesh*
1235   * *MeshVS_SMF_Group*
1236
1237 Such an object, for example, can be used for displaying the object and stored in the STL file format:
1238
1239 ~~~~~{.cpp}
1240 // read the data and create a data source
1241 Handle(Poly_Triangulation) aSTLMesh = RWStl::ReadFile (aFileName);
1242 Handle(XSDRAWSTLVRML_DataSource) aDataSource = new XSDRAWSTLVRML_DataSource (aSTLMesh);
1243
1244 // create mesh
1245 Handle(MeshVS_Mesh) aMeshPrs = new MeshVS();
1246 aMeshPrs->SetDataSource (aDataSource);
1247
1248 // use default presentation builder
1249 Handle(MeshVS_MeshPrsBuilder) aBuilder = new MeshVS_MeshPrsBuilder (aMeshPrs);
1250 aMeshPrs->AddBuilder (aBuilder, true);
1251 ~~~~~
1252
1253 *MeshVS_NodalColorPrsBuilder* allows representing a mesh with a color scaled texture mapped on it.
1254 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.
1255 The following example demonstrates how you can do this (check if the view has been set up to display textures):
1256
1257 ~~~~~{.cpp}
1258 // assign nodal builder to the mesh
1259 Handle(MeshVS_NodalColorPrsBuilder) aBuilder = new MeshVS_NodalColorPrsBuilder (theMeshPrs, MeshVS_DMF_NodalColorDataPrs | MeshVS_DMF_OCCMask);
1260 aBuilder->UseTexture (true);
1261
1262 // prepare color map
1263 Aspect_SequenceOfColor aColorMap;
1264 aColorMap.Append (Quantity_NOC_RED);
1265 aColorMap.Append (Quantity_NOC_BLUE1);
1266
1267 // assign color scale map  values (0..1) to nodes
1268 TColStd_DataMapOfIntegerReal aScaleMap;
1269 ...
1270 // iterate through the  nodes and add an node id and an appropriate value to the map
1271 aScaleMap.Bind (anId, aValue);
1272
1273 // pass color map and color scale values to the builder
1274 aBuilder->SetColorMap (aColorMap);
1275 aBuilder->SetInvalidColor (Quantity_NOC_BLACK);
1276 aBuilder->SetTextureCoords (aScaleMap);
1277 aMesh->AddBuilder (aBuilder, true);
1278 ~~~~~
1279
1280 @subsection occt_visu_3_6 Dynamic Selection
1281
1282 The dynamic selection represents the topological shape, which you want to select,
1283 by decomposition of *sensitive primitives* -- the sub-parts of the shape that will be detected and highlighted.
1284 The sets of these primitives are handled by the powerful three-level BVH tree selection algorithm.
1285
1286 For more details on the algorithm and examples of usage, refer to @ref occt_visu_2_2 "Selection" chapter.
1287
1288 @section occt_visu_4 3D Presentations
1289
1290 @subsection occt_visu_4_1 Glossary of 3D terms
1291
1292 * **Group** -- a set of primitives and attributes on those primitives.
1293   Primitives and attributes may be added to a group but cannot be removed from it, unless erased globally.
1294   A group can have a pick identity.
1295 * **Light**
1296   There are five kinds of light source -- ambient, headlight, directional, positional and spot.
1297 * **Primitive** -- a drawable element.
1298   It has a definition in 3D space.
1299   Primitives can either be lines, faces, text, or markers.
1300   Once displayed markers and text remain the same size.
1301   Lines and faces can be modified e.g. zoomed.
1302   Attributes are set within the group.
1303   Primitives must be stored in a group.
1304 * **Structure** -- manages a set of groups.
1305   The groups are mutually exclusive.
1306   A structure can be edited, adding or removing groups.
1307   A structure can reference other structures to form a hierarchy.
1308   It has a default (identity) transformation and other transformations may be applied to it (rotation, translation, scale, etc).
1309   Each structure has a display priority associated with it, which rules the order in which it is redrawn in a 3D viewer.
1310 * **View** -- is defined by a view orientation, a view mapping, and a context view.
1311 * **Viewer** -- manages a set of views.
1312 * **View orientation** -- defines the manner in which the observer looks at the scene in terms of View Reference Coordinates.
1313 * **View mapping** -- defines the transformation from View Reference Coordinates to the Normalized Projection Coordinates.
1314   This follows the Phigs scheme.
1315 * **Z-Buffering** -- a form of hidden surface removal in shading mode only.
1316   This is always active for a view in the shading mode and cannot be suppressed.
1317
1318 @subsection occt_visu_4_2 Graphic primitives
1319
1320 The *Graphic3d* package is used to create 3D graphic objects in a 3D viewer.
1321 These objects called **structures** are made up of groups of primitives, such as line segments, triangles, text and markers,
1322 and attributes, such as color, transparency, reflection, line type, line width, and text font.
1323 A group is the smallest editable element of a structure.
1324 A transformation can be applied to a structure.
1325 Structures can be connected to form a tree of structures, composed by transformations.
1326 Structures are globally manipulated by the viewer.
1327
1328 Graphic structures can be:
1329   * Displayed,
1330   * Highlighted,
1331   * Erased,
1332   * Transformed,
1333   * Connected to form a tree hierarchy of structures, created by transformations.
1334
1335 There are classes for:
1336   * Visual attributes for lines, faces, markers, text, materials,
1337   * Vectors and vertices,
1338   * Graphic objects, groups, and structures.
1339
1340 @subsubsection occt_visu_4_2_2 Structure hierarchies
1341
1342 The root is the top of a structure hierarchy or structure network.
1343 The attributes of a parent structure are passed to its descendants.
1344 The attributes of the descendant structures do not affect the parent.
1345 Recursive structure networks are not supported.
1346
1347 @subsubsection occt_visu_4_2_3 Graphic primitives
1348 * **Markers**
1349   * Have one or more vertices,
1350   * Have a type, a scale factor, and a color,
1351   * Have a size, shape, and orientation independent of transformations.
1352 * **Triangulation**
1353   * Has at least three vertices,
1354   * Has nodal normals defined for shading,
1355   * Has interior attributes -- style, color, front and back material, texture and reflection ratio.
1356 * **Polylines** or **Segments**
1357   * Have two or more vertices,
1358   * Have the following attributes -- type, width scale factor, color.
1359 * **Text**
1360   * Has geometric and non-geometric attributes,
1361   * Geometric attributes -- character height, character up vector, text path, horizontal and vertical alignment, orientation, three-dimensional position, zoomable flag
1362   * Non-geometric attributes -- text font, character spacing, character expansion factor, color.
1363
1364 @subsubsection occt_visu_4_2_4 Primitive arrays
1365
1366 The different types of primitives could be presented with the following primitive arrays:
1367   * *Graphic3d_ArrayOfPoints,*
1368   * *Graphic3d_ArrayOfPolylines,*
1369   * *Graphic3d_ArrayOfSegments,*
1370   * *Graphic3d_ArrayOfTriangleFans,*
1371   * *Graphic3d_ArrayOfTriangles,*
1372   * *Graphic3d_ArrayOfTriangleStrips.*
1373
1374 The *Graphic3d_ArrayOfPrimitives* is a base class for these primitive arrays.
1375 Method set *Graphic3d_ArrayOfPrimitives::AddVertex* allows adding vertices to the primitive array with their attributes (color, normal, texture coordinates).
1376 You can also modify the values assigned to the vertex or query these values by the vertex index.
1377
1378 The following example shows how to define an array of points:
1379
1380 ~~~~~{.cpp}
1381 // create an array
1382 Handle(Graphic3d_ArrayOfPoints) anArray = new Graphic3d_ArrayOfPoints (theVerticiesMaxCount);
1383
1384 // add vertices to the array
1385 anArray->AddVertex (10.0, 10.0, 10.0);
1386 anArray->AddVertex (0.0,  10.0, 10.0);
1387
1388 // add the array to the structure
1389 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
1390 aGroup->AddPrimitiveArray (anArray);
1391 aGroup->SetGroupPrimitivesAspect (myDrawer->PointAspect()->Aspect());
1392 ~~~~~
1393
1394 If the primitives share the same vertices (polygons, triangles, etc.) then you can define them as indices of the vertices array.
1395 The method *Graphic3d_ArrayOfPrimitives::AddEdge* allows defining the primitives by indices.
1396 This method adds an "edge" in the range *[1, VertexNumber()]* in the array.
1397 It is also possible to query the vertex defined by an edge using method *Graphic3d_ArrayOfPrimitives::Edge*.
1398
1399 The following example shows how to define an array of triangles:
1400
1401 ~~~~~{.cpp}
1402 // create an array
1403 Handle(Graphic3d_ArrayOfTriangles) anArray = new Graphic3d_ArrayOfTriangles (theVerticesMaxCount, theEdgesMaxCount, Graphic3d_ArrayFlags_None);
1404 // add vertices to the array
1405 anArray->AddVertex (-1.0, 0.0, 0.0); // vertex 1
1406 anArray->AddVertex ( 1.0, 0.0, 0.0); // vertex 2
1407 anArray->AddVertex ( 0.0, 1.0, 0.0); // vertex 3
1408 anArray->AddVertex ( 0.0,-1.0, 0.0); // vertex 4
1409
1410 // add edges to the array
1411 anArray->AddEdges (1, 2, 3); // first triangle
1412 anArray->AddEdges (1, 2, 4); // second triangle
1413
1414 // add the array to the structure
1415 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
1416 aGroup->AddPrimitiveArray (anArray);
1417 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
1418 ~~~~~
1419
1420 @subsubsection occt_visu_4_2_5 Text primitive
1421
1422 *TKOpenGl* toolkit renders text labels using texture fonts.
1423 *Graphic3d* text primitives have the following features:
1424   * fixed size (non-zoomable) or zoomable,
1425   * can be rotated to any angle in the view plane,
1426   * support unicode charset.
1427
1428 The text attributes for the group could be defined with the *Graphic3d_AspectText3d* attributes group.
1429 To add any text to the graphic structure you can use the following methods:
1430 ~~~~~{.cpp}
1431 void Graphic3d_Group::AddText (const Handle(Graphic3d_Text)& theTextParams,
1432                                const Standard_Boolean theToEvalMinMax);
1433 ~~~~~
1434
1435 You can pass FALSE as *theToEvalMinMax* if you do not want the Graphic3d structure boundaries to be affected by the text position.
1436
1437 **Note** that the text orientation angle can be defined by *Graphic3d_AspectText3d* attributes.
1438
1439 See the example:
1440 ~~~~~{.cpp}
1441 // get the group
1442 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
1443
1444 // change the text aspect
1445 Handle(Graphic3d_AspectText3d) aTextAspect = new Graphic3d_AspectText3d();
1446 aTextAspect->SetTextZoomable (true);
1447 aTextAspect->SetTextAngle (45.0);
1448 aGroup->SetPrimitivesAspect (aTextAspect);
1449
1450 // add a text primitive to the structure
1451 Handle(Graphic3d_Text) aText = new Graphic3d_Text (16.0f);
1452 aText->SetText ("Text");
1453 aText->SetPosition (gp_Pnt (1, 1, 1));
1454 aGroup->AddText (aText);
1455 ~~~~~
1456
1457 @subsubsection occt_visu_4_2_6 Materials
1458
1459 A *Graphic3d_MaterialAspect* defines the following Common material properties:
1460   * Transparency;
1461   * Diffuse reflection -- a component of the object color;
1462   * Ambient reflection;
1463   * Specular reflection -- a component of the color of the light source.
1464
1465 The following items are required to determine the three colors of reflection:
1466   * Color;
1467   * Coefficient of diffuse reflection;
1468   * Coefficient of ambient reflection;
1469   * Coefficient of specular reflection.
1470
1471 Common material properties are used within Gouraud and Phong shading models (Graphic3d_TOSM_FACET, Graphic3d_TOSM_VERTEX and Graphic3d_TOSM_FRAGMENT).
1472 Within PBR shading model (Graphic3d_TOSM_PBR and Graphic3d_TOSM_PBR_FACET), material properties are defined by the following *Graphic3d_PBRMaterial* properties (Graphic3d_MaterialAspect::PBRMaterial()):
1473   * Albedo (main color);
1474   * Metallic factor;
1475   * Roughness factor;
1476   * Transparency;
1477   * Index of refraction.
1478
1479 @subsubsection occt_visu_4_2_7 Textures
1480
1481 A *texture* is defined by a name.
1482 Three types of texture are available:
1483   * 1D;
1484   * 2D;
1485   * Environment mapping.
1486
1487 @subsubsection occt_visu_4_2_8 Custom shaders
1488
1489 OCCT visualization core supports GLSL shaders.
1490 Custom shaders can be assigned to a generic presentation by its drawer attributes (Graphic3d aspects).
1491 To enable custom shader for a specific AIS_Shape in your application, the following API functions can be used:
1492
1493 ~~~~~{.cpp}
1494 // Create shader program
1495 Handle(Graphic3d_ShaderProgram) aProgram = new Graphic3d_ShaderProgram();
1496
1497 // Attach vertex shader
1498 aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_VERTEX, "<Path to VS>"));
1499
1500 // Attach fragment shader
1501 aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile (Graphic3d_TOS_FRAGMENT, "<Path to FS>"));
1502
1503 // Set values for custom uniform variables (if they are)
1504 aProgram->PushVariable ("MyColor", Graphic3d_Vec3 (0.0f, 1.0f, 0.0f));
1505
1506 // Set aspect property for specific AIS_Shape
1507 theAISShape->Attributes()->ShadingAspect()->Aspect()->SetShaderProgram (aProgram);
1508 ~~~~~
1509
1510 @subsection occt_visu_4_3 Graphic attributes
1511
1512 @subsubsection occt_visu_4_3_1 Aspect package overview
1513
1514 The *Aspect* package provides classes for the graphic elements in the viewer:
1515   * Groups of graphic attributes;
1516   * Edges, lines, background;
1517   * Window;
1518   * Driver;
1519   * Enumerations for many of the above.
1520
1521 @subsection occt_visu_4_4 3D view facilities
1522
1523 @subsubsection occt_visu_4_4_1 Overview
1524
1525 The *V3d* package provides the resources to define a 3D viewer and the views attached to this viewer (orthographic, perspective).
1526 This package provides the commands to manipulate the graphic scene of any 3D object visualized in a view on screen.
1527
1528 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, etc.) in any particular view.
1529
1530 The *V3d* package is basically a set of tools directed by commands from the viewer front-end.
1531 This tool set contains methods for creating and editing classes of the viewer such as:
1532   * Default parameters of the viewer,
1533   * Views (orthographic, perspective),
1534   * Lighting (positional, directional, ambient, spot, headlight),
1535   * Clipping planes,
1536   * Instantiated sequences of views, planes, light sources, graphic structures, and picks,
1537   * Various package methods.
1538
1539 @subsubsection occt_visu_4_4_2 A programming example
1540
1541 This sample TEST program for the *V3d* Package uses primary packages *Xw* and *Graphic3d* and secondary packages *Visual3d, Aspect, Quantity* and *math*.
1542
1543 ~~~~~{.cpp}
1544 // create a default display connection
1545 Handle(Aspect_DisplayConnection) aDispConnection = new Aspect_DisplayConnection();
1546 // create a Graphic Driver
1547 Handle(OpenGl_GraphicDriver) aGraphicDriver = new OpenGl_GraphicDriver (aDispConnection);
1548 // create a Viewer to this Driver
1549 Handle(V3d_Viewer) aViewer = new V3d_Viewer (aGraphicDriver);
1550 aViewer->SetDefaultBackgroundColor (Quantity_NOC_DARKVIOLET);
1551 // Create a structure in this Viewer
1552 Handle(Graphic3d_Structure) aStruct = new Graphic3d_Structure (aViewer->StructureManager());
1553 aStruct->SetVisual (Graphic3d_TOS_SHADING); // Type of structure
1554
1555 // Create a group of primitives  in this structure
1556 Handle(Graphic3d_Group) aPrsGroup = aStruct->NewGroup();
1557
1558 // Fill this group with one quad of size 100
1559 Handle(Graphic3d_ArrayOfTriangleStrips) aTriangles = new Graphic3d_ArrayOfTriangleStrips (4);
1560 aTriangles->AddVertex (-100./2., -100./2., 0.0);
1561 aTriangles->AddVertex (-100./2.,  100./2., 0.0);
1562 aTriangles->AddVertex ( 100./2., -100./2., 0.0);
1563 aTriangles->AddVertex ( 100./2.,  100./2., 0.0);
1564
1565 Handle(Graphic3d_AspectFillArea3d) anAspects = new Graphic3d_AspectFillArea3d (Aspect_IS_SOLID, Quantity_NOC_RED,
1566                                                                                Quantity_NOC_RED, Aspect_TOL_SOLID, 1.0f,
1567                                                                                Graphic3d_NameOfMaterial_Gold, Graphic3d_NameOfMaterial_Gold);
1568 aPrsGroup->SetGroupPrimitivesAspect (anAspects);
1569 aPrsGroup->AddPrimitiveArray (aTriangles);
1570
1571 // Create Ambient and Infinite Lights in this Viewer
1572 Handle(V3d_AmbientLight)     aLight1 = new V3d_AmbientLight (Quantity_NOC_GRAY50);
1573 Handle(V3d_DirectionalLight) aLight2 = new V3d_DirectionalLight (V3d_Zneg, Quantity_NOC_WHITE, true);
1574 aViewer->AddLight (aLight1);
1575 aViewer->AddLight (aLight2);
1576 aViewer->SetLightOn();
1577
1578 // Create a 3D quality  Window with the same DisplayConnection
1579 Handle(Xw_Window) aWindow = new Xw_Window (aDispConnection, "Test V3d", 100, 100, 500, 500);
1580 aWindow->Map(); // Map this Window to this screen
1581
1582 // Create a Perspective  View in this Viewer
1583 Handle(V3d_View) aView = new V3d_View (aViewer);
1584 aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
1585 // Associate this View with the Window
1586 aView->SetWindow (aWindow);
1587 // Display presentation in this View
1588 aStruct->Display();
1589 // Finally update the Visualization in this View
1590 aView->Update();
1591 // Fit view to object size
1592 aView->FitAll();
1593 ~~~~~
1594
1595 @subsubsection occt_visu_4_4_3 Define viewing parameters
1596
1597 View projection and orientation in OCCT *V3d_View* are driven by camera.
1598 The camera calculates and supplies projection and view orientation matrices for rendering by OpenGL.
1599 The allows to the user to control all projection parameters.
1600 The camera is defined by the following properties:
1601
1602  * **Eye** -- defines the observer (camera) position.
1603    Make sure the Eye point never gets between the Front and Back clipping planes.
1604  * **Center** -- defines the origin of View Reference Coordinates (where camera is aimed at).
1605  * **Direction** -- defines the direction of camera view (from the Eye to the Center).
1606  * **Distance** -- defines the distance between the Eye and the Center.
1607  * **Front** Plane -- defines the position of the front clipping plane in View Reference Coordinates system.
1608  * **Back** Plane -- defines the position of the back clipping plane in View Reference Coordinates system.
1609  * **ZNear** -- defines the distance between the Eye and the Front plane.
1610  * **ZFar** -- defines the distance between the Eye and the Back plane.
1611
1612 Most common view manipulations (panning, zooming, rotation) are implemented as convenience methods of *V3d_View* class or by *AIS_ViewController* tool.
1613 However *Graphic3d_Camera* class can also be used directly by application developers.
1614 Example:
1615 ~~~~~{.cpp}
1616 // rotate camera by X axis on 30.0 degrees
1617 gp_Trsf aTrsf;
1618 aTrsf.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Dir (1.0, 0.0, 0.0)), M_PI / 4.0);
1619 aView->Camera()->Transform (aTrsf);
1620 ~~~~~
1621
1622 @subsubsection occt_visu_4_4_4 Orthographic Projection
1623
1624 @figure{view_frustum.png,"Perspective and orthographic projection",420}
1625
1626 The following code configures the camera for orthographic rendering:
1627
1628 ~~~~~{.cpp}
1629 // Create an orthographic View in this Viewer
1630 Handle(V3d_View) aView = new V3d_View (theViewer);
1631 aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
1632 aView->Update(); // update the Visualization in this View
1633 ~~~~~
1634
1635 @subsubsection occt_visu_4_4_5 Perspective Projection
1636
1637 **Field of view (FOVy)** -- defines the field of camera view by y axis in degrees (45° is default).
1638
1639 @figure{camera_perspective.png,"Perspective frustum",420}
1640
1641 The following code configures the camera for perspective rendering:
1642
1643 ~~~~~{.cpp}
1644 // Create a perspective View in this Viewer
1645 Handle(V3d_View) aView = new V3d_View (theViewer);
1646 aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
1647 aView->Update();
1648 ~~~~~
1649
1650 @subsubsection occt_visu_4_4_6 Stereographic Projection
1651
1652 **IOD** -- defines the intraocular distance (in world space units).
1653
1654 There are two types of IOD:
1655 * _Graphic3d_Camera::IODType_Absolute_ : Intraocular distance is defined as an absolute value.
1656 * _Graphic3d_Camera::IODType_Relative_ : Intraocular distance is defined relative to the camera focal length (as its coefficient).
1657
1658 **Field of view (FOV)** -- defines the field of camera view by y axis in degrees (45° is default).
1659
1660 **ZFocus** -- defines the distance to the point of stereographic focus.
1661
1662 @figure{stereo.png,"Stereographic projection",420}
1663
1664 To enable stereo projection for active (shutter) 3D glasses, your workstation should meet the following requirements:
1665
1666 * The graphic card should support quad buffering.
1667 * You need active 3D glasses (LCD shutter glasses).
1668 * The graphic driver needs to be configured to impose quad buffering for newly created OpenGl contexts;
1669   the viewer and the view should be created after that.
1670
1671 In stereographic projection mode the camera prepares two projection matrices to display different stereo-pictures for the left and for the right eye.
1672 In a non-stereo camera this effect is not visible because only the same projection is used for both eyes.
1673
1674 To enable quad buffering support you should provide the following settings to the graphic driver *OpenGl_Caps*:
1675
1676 ~~~~~{.cpp}
1677 Handle(OpenGl_GraphicDriver) aDriver = new OpenGl_GraphicDriver();
1678 OpenGl_Caps& aCaps = aDriver->ChangeOptions();
1679 aCaps.contextStereo = Standard_True;
1680 ~~~~~
1681
1682 The following code configures the camera for stereographic rendering:
1683
1684 ~~~~~{.cpp}
1685 // Create a Stereographic View in this Viewer
1686 Handle(V3d_View) aView = new V3d_View (theViewer);
1687 aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
1688 // Change stereo parameters
1689 aView->Camera()->SetIOD (IODType_Absolute, 5.0);
1690 // Finally update the Visualization in this View
1691 aView->Update();
1692 ~~~~~
1693
1694 Other 3D displays are also supported, including row-interlaced with passive glasses and anaglyph glasses - see *Graphic3d_StereoMode* enumeration.
1695 Example to activate another stereoscopic display:
1696 ~~~~~{.cpp}
1697 Handle(V3d_View) theView;
1698 theView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
1699 theView->ChangeRenderingParams().StereoParams = Graphic3d_StereoMode_RowInterlaced;
1700 ~~~~~
1701
1702 Supporting of VR/AR headsets in application is more involving.
1703 Class *Aspect_XRSession* defines a basic interface for working with extended reality.
1704
1705 @subsubsection occt_visu_4_4_7 View frustum culling
1706
1707 The algorithm of frustum culling on CPU-side is activated by default for 3D viewer.
1708 This algorithm allows skipping the presentation outside camera at the rendering stage, providing better performance.
1709 The following features support this method:
1710 * *Graphic3d_Structure::CalculateBoundBox()* is used to calculate axis-aligned bounding box of a presentation considering its transformation.
1711 * *V3d_View::SetFrustumCulling* enables or disables frustum culling for the specified view.
1712 * Classes *Graphic3d_BvhCStructureSet* and *Graphic3d_CullingTool* handle the detection of outer objects and usage of acceleration structure for frustum culling.
1713 * *BVH_BinnedBuilder* class splits several objects with null bounding box.
1714
1715 @subsubsection occt_visu_4_4_9 View background styles
1716 There are several types of background styles available for *V3d_View*: solid color, gradient color, image and environment cubemap.
1717
1718 To set solid color for the background you can use the following method:
1719 ~~~~~{.cpp}
1720 void V3d_View::SetBackgroundColor (const Quantity_Color& theColor);
1721 ~~~~~
1722
1723 The gradient background style could be set up with the following method:
1724 ~~~~~{.cpp}
1725 void V3d_View::SetBgGradientColors (const Quantity_Color& theColor1,
1726                                     const Quantity_Color& theColor2,
1727                                     const Aspect_GradientFillMethod theFillStyle,
1728                                     const Standard_Boolean theToUpdate = false);
1729 ~~~~~
1730
1731 The *theColor1* and *theColor2* parameters define the boundary colors of interpolation, the *theFillStyle* parameter defines the direction of interpolation.
1732
1733 To set the image as a background and change the background image style you can use the following method:
1734 ~~~~~{.cpp}
1735 void V3d_View::SetBackgroundImage (const Standard_CString theFileName,
1736                                    const Aspect_FillMethod theFillStyle,
1737                                    const Standard_Boolean theToUpdate = false);
1738 ~~~~~
1739
1740 The *theFileName* parameter defines the image file name and the path to it, the *theFillStyle* parameter defines the method of filling the background with the image.
1741 The methods are:
1742   * *Aspect_FM_NONE* --  draws the image in the default position;
1743   * *Aspect_FM_CENTERED* -- draws the image at the center of the view;
1744   * *Aspect_FM_TILED* -- tiles the view with the image;
1745   * *Aspect_FM_STRETCH* -- stretches the image over the view.
1746
1747 @subsubsection occt_visu_4_4_10 Dumping a 3D scene into an image file
1748
1749 The 3D scene displayed in the view can be dumped into image file with resolution independent from window size (using offscreen buffer).
1750 The *V3d_View* has the following methods for dumping the 3D scene:
1751 ~~~~{.cpp}
1752 Standard_Boolean V3d_View::Dump (const Standard_CString theFile,
1753                                  const Image_TypeOfImage theBufferType);
1754 ~~~~
1755 Dumps the scene into an image file with the view dimensions.
1756 The raster image data handling algorithm is based on the *Image_AlienPixMap* class.
1757 The supported extensions are ".png", ".bmp", ".jpg" and others supported by **FreeImage** library.
1758 The value passed as *theBufferType* argument defines the type of the buffer for an output image (RGB, RGBA, floating-point, RGBF, RGBAF).
1759 Method returns TRUE if the scene has been successfully dumped.
1760
1761 ~~~~{.cpp}
1762 Standard_Boolean V3d_View::ToPixMap (Image_PixMap&               theImage,
1763                                      const V3d_ImageDumpOptions& theParams);
1764 ~~~~
1765 Dumps the displayed 3d scene into a pixmap with a width and height passed through parameters structure *theParams*.
1766
1767 @subsubsection occt_visu_4_4_13 Ray tracing support
1768
1769 OCCT visualization provides rendering by real-time ray tracing technique.
1770 It is allowed to switch easily between usual rasterization and ray tracing rendering modes.
1771 The core of OCCT ray tracing is written using GLSL shaders.
1772 The ray tracing has a wide list of features:
1773 * Hard shadows
1774 * Refractions
1775 * Reflection
1776 * Transparency
1777 * Texturing
1778 * Support of non-polygon objects, such as lines, text, highlighting, selection.
1779 * Performance optimization using 2-level bounding volume hierarchy (BVH).
1780
1781 The ray tracing algorithm is recursive (Whitted's algorithm).
1782 It uses BVH effective optimization structure.
1783 The structure prepares optimized data for a scene geometry for further displaying it in real-time.
1784 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.
1785 It is only necessary when the list of displayed objects or their geometry changes.
1786 To make the BVH reusable it has been added into an individual reusable OCCT package *TKMath/BVH*.
1787
1788 There are several ray-tracing options that user can switch on/off:
1789 * Maximum ray tracing depth
1790 * Shadows rendering
1791 * Specular reflections
1792 * Adaptive anti aliasing
1793 * Transparency shadow effects
1794
1795 Example:
1796 ~~~~~{.cpp}
1797 Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
1798 // specifies rendering mode
1799 aParams.Method = Graphic3d_RM_RAYTRACING;
1800 // maximum ray-tracing depth
1801 aParams.RaytracingDepth = 3;
1802 // enable shadows rendering
1803 aParams.IsShadowEnabled = true;
1804 // enable specular reflections
1805 aParams.IsReflectionEnabled = true;
1806 // enable adaptive anti-aliasing
1807 aParams.IsAntialiasingEnabled = true;
1808 // enable light propagation through transparent media
1809 aParams.IsTransparentShadowEnabled = true;
1810 // update the view
1811 aView->Update();
1812 ~~~~~
1813
1814 @subsubsection occt_visu_4_4_14 Display priorities
1815
1816 Structure display priorities control the order, in which structures are drawn.
1817 When you display a structure you specify its priority.
1818 The lower is the value, the lower is the display priority.
1819 When the display is regenerated, the structures with the lowest priority are drawn first.
1820 The structures with the same display priority are drawn in the same order as they have been displayed.
1821 OCCT supports eleven structure display priorities within [0, 10] range.
1822
1823 @subsubsection occt_visu_4_4_15 Z-layer support
1824
1825 OCCT features depth-arranging functionality called z-layer.
1826 A graphical presentation can be put into a z-layer.
1827 In general, this function can be used for implementing "bring to front" functionality in a graphical application.
1828
1829 Example:
1830
1831 ~~~~~{.cpp}
1832 // set z-layer to an interactive object
1833 Handle(AIS_InteractiveContext) theContext;
1834 Handle(AIS_InteractiveObject) theInterObj;
1835 Standard_Integer anId = -1;
1836 aViewer->AddZLayer (anId);
1837 theContext->SetZLayer (theInterObj, anId);
1838 ~~~~~
1839
1840 For each z-layer, it is allowed to:
1841 * Enable / disable depth test for layer.
1842 * Enable / disable depth write for layer.
1843 * Enable / disable depth buffer clearing.
1844 * Enable / disable polygon offset.
1845
1846 You can get the options using getter from *V3d_Viewer*.
1847 It returns *Graphic3d_ZLayerSettings* for a given *LayerId*.
1848
1849 Example:
1850 ~~~~~{.cpp}
1851 // change z-layer settings
1852 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
1853 aSettings.SetEnableDepthTest (true);
1854 aSettings.SetEnableDepthWrite(true);
1855 aSettings.SetClearDepth      (true);
1856 aSettings.SetPolygonOffset   (Graphic3d_PolygonOffset());
1857 aViewer->SetZLayerSettings (anId, aSettings);
1858 ~~~~~
1859
1860 Another application for Z-Layer feature is treating visual precision issues when displaying objects far from the World Center.
1861 The key problem with such objects is that visualization data is stored and manipulated with single precision floating-point numbers (32-bit).
1862 Single precision 32-bit floating-point numbers give only 6-9 significant decimal digits precision,
1863 while double precision 64-bit numbers give 15-17 significant decimal digits precision, which is sufficient enough for most applications.
1864
1865 When moving an Object far from the World Center, float number steadily eats precision.
1866 The camera Eye position adds leading decimal digits to the overall Object transformation, which discards smaller digits due to floating point number nature.
1867 For example, the object of size 0.0000123 moved to position 1000 has result transformation 1000.0000123,
1868 which overflows single precision floating point - considering the most optimistic scenario of 9 significant digits (but it is really not this case), the result number will be 1000.00001.
1869
1870 This imprecision results in visual artifacts of two kinds in the 3D Viewer:
1871
1872 * Overall per-vertex Object distortion.
1873   This happens when each vertex position has been defined within World Coordinate system.
1874 * The object itself is not distorted, but its position in the World is unstable and imprecise - the object jumps during camera manipulations.
1875   This happens when vertices have been defined within Local Coordinate system at the distance small enough to keep precision within single precision float,
1876   however Local Transformation applied to the Object is corrupted due to single precision float.
1877
1878 The first issue cannot be handled without switching the entire presentation into double precision (for each vertex position).
1879 However, visualization hardware is much faster using single precision float number rather than double precision - so this is not an option in most cases.
1880 The second issue, however, can be negated by applying special rendering tricks.
1881
1882 So, to apply this feature in OCCT, the application:
1883
1884 * Defines Local Transformation for each object to fit the presentation data into single precision float without distortion.
1885 * Spatially splits the world into smaller areas/cells where single precision float will be sufficient.
1886   The size of such cell might vary and depends on the precision required by application (e.g. how much user is able to zoom in camera within application).
1887 * Defines a Z-Layer for each spatial cell containing any object.
1888 * Defines the Local Origin property of the Z-Layer according to the center of the cell.
1889
1890 ~~~~~{.cpp}
1891 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
1892 aSettings.SetLocalOrigin (400.0, 0.0, 0.0);
1893 ~~~~~
1894 * Assigns a presentable object to the nearest Z-Layer.
1895
1896 Note that Local Origin of the Layer is used only for rendering - everything outside will be still defined in the World Coordinate System,
1897 including Local Transformation of the Object and Detection results.
1898 E.g., while moving the presentation between Z-layers with different Local Origins, the Object will stay at the same place - only visualization quality will vary.
1899
1900 @subsubsection occt_visu_4_4_16 Clipping planes
1901
1902 The ability to define custom clipping planes could be very useful for some tasks.
1903 OCCT provides such an opportunity.
1904
1905 The *Graphic3d_ClipPlane* class provides the services for clipping planes:
1906 it holds the plane equation coefficients and provides its graphical representation.
1907 To set and get plane equation coefficients you can use the following methods:
1908
1909 ~~~~~{.cpp}
1910 Graphic3d_ClipPlane::Graphic3d_ClipPlane (const gp_Pln& thePlane)
1911 void Graphic3d_ClipPlane::SetEquation (const gp_Pln& thePlane)
1912 Graphic3d_ClipPlane::Graphic3d_ClipPlane (const Equation& theEquation)
1913 void Graphic3d_ClipPlane::SetEquation (const Equation& theEquation)
1914 gp_Pln Graphic3d_ClipPlane::ToPlane() const
1915 ~~~~~
1916
1917 The clipping planes can be activated with the following method:
1918 ~~~~~{.cpp}
1919 void Graphic3d_ClipPlane::SetOn (const Standard_Boolean theIsOn)
1920 ~~~~~
1921
1922 The number of clipping planes is limited.
1923 You can check the limit value via method *Graphic3d_GraphicDriver::InquireLimit()*;
1924
1925 ~~~~~{.cpp}
1926 // get the limit of clipping planes for the current view
1927 Standard_Integer aMaxClipPlanes = aView->Viewer()->Driver()->InquireLimit (Graphic3d_TypeOfLimit_MaxNbClipPlanes);
1928 ~~~~~
1929
1930 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:
1931 ~~~~~{.cpp}
1932 // create a new clipping plane
1933 Handle(Graphic3d_ClipPlane) aClipPlane = new Graphic3d_ClipPlane();
1934 // change equation of the clipping plane
1935 Standard_Real aCoeffA, aCoeffB, aCoeffC, aCoeffD = ...
1936 aClipPlane->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
1937 // set capping
1938 aClipPlane->SetCapping (aCappingArg == "on");
1939 // set the material with red color of clipping plane
1940 Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
1941 Quantity_Color aColor (1.0, 0.0, 0.0, Quantity_TOC_RGB);
1942 aMat.SetAmbientColor (aColor);
1943 aMat.SetDiffuseColor (aColor);
1944 aClipPlane->SetCappingMaterial (aMat);
1945 // set the texture of clipping plane
1946 Handle(Graphic3d_Texture2Dmanual) aTexture = ...
1947 aTexture->EnableModulate();
1948 aTexture->EnableRepeat();
1949 aClipPlane->SetCappingTexture (aTexture);
1950 // add the clipping plane to an interactive object
1951 Handle(AIS_InteractiveObject) aIObj = ...
1952 aIObj->AddClipPlane (aClipPlane);
1953 // or to the whole view
1954 aView->AddClipPlane (aClipPlane);
1955 // activate the clipping plane
1956 aClipPlane->SetOn (Standard_True);
1957 // update the view
1958 aView->Update();
1959 ~~~~~
1960
1961 @subsubsection occt_visu_4_4_17 Automatic back face culling
1962
1963 Back face culling reduces the rendered number of triangles (which improves the performance) and eliminates artifacts at shape boundaries.
1964 However, this option can be used only for solid objects, where the interior is actually invisible from any point of view.
1965 Automatic back-face culling mechanism is turned on by default, which is controlled by *V3d_View::SetBackFacingModel()*.
1966
1967 The following features are applied in *StdPrs_ToolTriangulatedShape::IsClosed()*, which is used for definition of back face culling in *ShadingAspect*:
1968 * disable culling for free closed Shells (not inside the Solid) since reversed orientation of a free Shell is a valid case;
1969 * enable culling for Solids packed into a compound;
1970 * ignore Solids with incomplete triangulation.
1971
1972 Back face culling is turned off at TKOpenGl level in the following cases:
1973 * clipping/capping planes are in effect;
1974 * for translucent objects;
1975 * with hatching presentation style.
1976
1977 @subsection occt_visu_4_5 Examples: creating a 3D scene
1978
1979 To create 3D graphic objects and display them in the screen, follow the procedure below:
1980 1. Create attributes.
1981 2. Create a 3D viewer.
1982 3. Create a view.
1983 4. Create an interactive context.
1984 5. Create interactive objects.
1985 6. Create primitives in the interactive object.
1986 7. Display the interactive object.
1987
1988 @subsubsection occt_visu_4_5_1 Create attributes
1989
1990 Create colors.
1991
1992 ~~~~~{.cpp}
1993 Quantity_Color aBlack (Quantity_NOC_BLACK);
1994 Quantity_Color aBlue (Quantity_NOC_MATRABLUE);
1995 Quantity_Color aBrown (Quantity_NOC_BROWN4);
1996 Quantity_Color aFirebrick (Quantity_NOC_FIREBRICK);
1997 Quantity_Color aForest (Quantity_NOC_FORESTGREEN);
1998 Quantity_Color aGray (Quantity_NOC_GRAY70);
1999 Quantity_Color aMyColor (0.99, 0.65, 0.31, Quantity_TOC_RGB);
2000 Quantity_Color aBeet (Quantity_NOC_BEET);
2001 Quantity_Color aWhite (Quantity_NOC_WHITE);
2002 ~~~~~
2003
2004 Create line attributes.
2005
2006 ~~~~~{.cpp}
2007 Handle(Graphic3d_AspectLine3d) anAspectBrown = new Graphic3d_AspectLine3d();
2008 Handle(Graphic3d_AspectLine3d) anAspectBlue  = new Graphic3d_AspectLine3d();
2009 Handle(Graphic3d_AspectLine3d) anAspectWhite = new Graphic3d_AspectLine3d();
2010 anAspectBrown->SetColor (aBrown);
2011 anAspectBlue ->SetColor (aBlue);
2012 anAspectWhite->SetColor (aWhite);
2013 ~~~~~
2014
2015 Create marker attributes.
2016 ~~~~~{.cpp}
2017 Handle(Graphic3d_AspectMarker3d aFirebrickMarker = new Graphic3d_AspectMarker3d();
2018 // marker attributes
2019 aFirebrickMarker->SetColor (Firebrick);
2020 aFirebrickMarker->SetScale (1.0f);
2021 aFirebrickMarker->SetType (Aspect_TOM_BALL);
2022 // or custom image
2023 aFirebrickMarker->SetMarkerImage (theImage)
2024 ~~~~~
2025
2026 Create facet attributes.
2027 ~~~~~{.cpp}
2028 Handle(Graphic3d_AspectFillArea3d) aFaceAspect = new Graphic3d_AspectFillArea3d();
2029 Graphic3d_MaterialAspect aBrassMaterial (Graphic3d_NameOfMaterial_Brass);
2030 Graphic3d_MaterialAspect aGoldMaterial  (Graphic3d_NameOfMaterial_Gold);
2031 aFaceAspect->SetInteriorStyle (Aspect_IS_SOLID_WIREFRAME);
2032 aFaceAspect->SetInteriorColor (aMyColor);
2033 aFaceAspect->SetDistinguishOn ();
2034 aFaceAspect->SetFrontMaterial (aGoldMaterial);
2035 aFaceAspect->SetBackMaterial  (aBrassMaterial);
2036 ~~~~~
2037
2038 Create text attributes.
2039 ~~~~~{.cpp}
2040 Handle(Graphic3d_AspectText3d) aTextAspect = new Graphic3d_AspectText3d (aForest, Font_NOF_MONOSPACE, 1.0, 0.0);
2041 ~~~~~
2042
2043 @subsubsection occt_visu_4_5_2 Create a 3D Viewer (a Windows example)
2044
2045 ~~~~~{.cpp}
2046 // create a graphic driver
2047 Handle(OpenGl_GraphicDriver) aGraphicDriver = new OpenGl_GraphicDriver (Handle(Aspect_DisplayConnection)());
2048 // create a viewer
2049 myViewer = new V3d_Viewer (aGraphicDriver);
2050 // set parameters for V3d_Viewer
2051 // defines default lights -
2052 //   positional-light 0.3 0.0 0.0
2053 //   directional-light V3d_XnegYposZpos
2054 //   directional-light V3d_XnegYneg
2055 //   ambient-light
2056 a3DViewer->SetDefaultLights();
2057 // activates all the lights defined in this viewer
2058 a3DViewer->SetLightOn();
2059 // set background color to black
2060 a3DViewer->SetDefaultBackgroundColor (Quantity_NOC_BLACK);
2061 ~~~~~
2062
2063 @subsubsection occt_visu_4_5_3 Create a 3D view (a Windows example)
2064
2065 It is assumed that a valid Windows window may already be accessed via the method *GetSafeHwnd()* (as in case of MFC sample).
2066 ~~~~~{.cpp}
2067 Handle(WNT_Window) aWNTWindow = new WNT_Window (GetSafeHwnd());
2068 myView = myViewer->CreateView();
2069 myView->SetWindow (aWNTWindow);
2070 ~~~~~
2071
2072 @subsubsection occt_visu_4_5_4 Create an interactive context
2073
2074 ~~~~~{.cpp}
2075 myAISContext = new AIS_InteractiveContext (myViewer);
2076 ~~~~~
2077
2078 You are now able to display interactive objects such as an *AIS_Shape*.
2079
2080 ~~~~~{.cpp}
2081 TopoDS_Shape aShape = BRepAPI_MakeBox (10, 20, 30).Solid();
2082 Handle(AIS_Shape) anAISShape = new AIS_Shape (aShape);
2083 myAISContext->Display (anAISShape, true);
2084 ~~~~~
2085
2086 @subsubsection occt_visu_4_5_5 Create your own interactive object
2087
2088 Follow the procedure below to compute the presentable object:
2089
2090 1. Build a presentable object inheriting from *AIS_InteractiveObject* (refer to the Chapter on @ref occt_visu_2_1 "Presentable Objects").
2091 2. Reuse the *Graphic3d_Structure* provided as an argument of the compute methods.
2092
2093 **Note** that there are two compute methods: one for a standard representation, and the other for a degenerated representation,
2094 i.e. in hidden line removal and wireframe modes.
2095
2096 Let us look at the example of compute methods
2097
2098 ~~~~~{.cpp}
2099 void MyPresentableObject::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsManager,
2100                                    const Handle(Graphic3d_Structure)& thePrs,
2101                                    const Standard_Integer theMode)
2102 (
2103   //...
2104 )
2105
2106 void MyPresentableObject::Compute (const Handle(Prs3d_Projector)& theProjector,
2107                                    const Handle(Graphic3d_Structure)& thePrs)
2108 (
2109   //...
2110 )
2111 ~~~~~
2112
2113 @subsubsection occt_visu_4_5_6 Create primitives in the interactive object
2114
2115 Get the group used in *Graphic3d_Structure*.
2116
2117 ~~~~~{.cpp}
2118 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
2119 ~~~~~
2120
2121 Update the group attributes.
2122
2123 ~~~~~{.cpp}
2124 aGroup->SetGroupPrimitivesAspect (anAspectBlue);
2125 ~~~~~
2126
2127 Create two triangles in *aGroup*.
2128
2129 ~~~~~{.cpp}
2130 Standard_Integer aNbTria = 2;
2131 Handle(Graphic3d_ArrayOfTriangles) aTriangles = new Graphic3d_ArrayOfTriangles (3 * aNbTria, 0, Graphic3d_ArrayFlags_VertexNormal);
2132 for (Standard_Integer aTriIter = 1; aTriIter <= aNbTria; ++aTriIter)
2133 {
2134   aTriangles->AddVertex (aTriIter * 5.,      0., 0., 1., 1., 1.);
2135   aTriangles->AddVertex (aTriIter * 5 + 5,   0., 0., 1., 1., 1.);
2136   aTriangles->AddVertex (aTriIter * 5 + 2.5, 5., 0., 1., 1., 1.);
2137 }
2138 aGroup->AddPrimitiveArray (aTriangles);
2139 aGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectFillArea3d());
2140 ~~~~~
2141
2142 Use the polyline function to create a boundary box for the *thePrs* structure in group *aGroup*.
2143
2144 ~~~~~{.cpp}
2145 Standard_Real Xm, Ym, Zm, XM, YM, ZM;
2146 thePrs->MinMaxValues (Xm, Ym, Zm, XM, YM, ZM);
2147
2148 Handle(Graphic3d_ArrayOfPolylines) aPolylines = new Graphic3d_ArrayOfPolylines (16, 4);
2149 aPolylines->AddBound (4);
2150 aPolylines->AddVertex (Xm,  Ym, Zm);
2151 aPolylines->AddVertex (Xm,  Ym, ZM);
2152 aPolylines->AddVertex (Xm,  YM, ZM);
2153 aPolylines->AddVertex (Xm,  YM, Zm);
2154 aPolylines->AddBound (4);
2155 aPolylines->AddVertex (Xm,  Ym, Zm);
2156 aPolylines->AddVertex (XM,  Ym, Zm);
2157 aPolylines->AddVertex (XM,  Ym, ZM);
2158 aPolylines->AddVertex (XM,  YM, ZM);
2159 aPolylines->AddBound (4);
2160 aPolylines->AddVertex (XM,  YM, Zm);
2161 aPolylines->AddVertex (XM,  Ym, Zm);
2162 aPolylines->AddVertex (XM,  YM, Zm);
2163 aPolylines->AddVertex (Xm,  YM, Zm);
2164 aPolylines->AddBound (4);
2165 aPolylines->AddVertex (Xm,  YM, ZM);
2166 aPolylines->AddVertex (XM,  YM, ZM);
2167 aPolylines->AddVertex (XM,  Ym, ZM);
2168 aPolylines->AddVertex (Xm,  Ym, ZM);
2169
2170 aGroup->AddPrimitiveArray(aPolylines);
2171 aGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d());
2172 ~~~~~
2173
2174 Create text and markers in group *aGroup*.
2175
2176 ~~~~~{.cpp}
2177 static char* THE_TEXT[3] =
2178 {
2179   "Application title",
2180   "My company",
2181   "My company address."
2182 };
2183 Handle(Graphic3d_ArrayOfPoints) aPtsArr = new Graphic3d_ArrayOfPoints (2, 1);
2184 aPtsArr->AddVertex (-40.0, -40.0, -40.0);
2185 aPtsArr->AddVertex (40.0, 40.0, 40.0);
2186 aGroup->AddPrimitiveArray (aPtsArr);
2187 aGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectText3d());
2188
2189 Graphic3d_Vertex aMarker (0.0, 0.0, 0.0);
2190 for (int i = 0; i <= 2; i++)
2191 {
2192   aMarker.SetCoord (-(Standard_Real )i * 4 + 30,
2193                      (Standard_Real )i * 4,
2194                     -(Standard_Real )i * 4);
2195   aGroup->Text (THE_TEXT[i], Marker, 20.);
2196 }
2197 ~~~~~
2198
2199 @section occt_visu_5 Mesh Visualization Services
2200
2201 *MeshVS* (Mesh Visualization Service) component extends 3D visualization capabilities of Open CASCADE Technology.
2202 It provides flexible means of displaying meshes along with associated pre- and post-processor data.
2203
2204 From a developer's point of view, it is easy to integrate the *MeshVS* component into any mesh-related application with the following guidelines:
2205
2206 * Derive a data source class from the *MeshVS_DataSource* class.
2207 * Re-implement its virtual methods, so as to give the *MeshVS* component access to the application data model.
2208   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.
2209 * Create an instance of *MeshVS_Mesh* class.
2210 * Create an instance of your data source class and pass it to a *MeshVS_Mesh* object through the *SetDataSource()* method.
2211 * Create one or several objects of *MeshVS_PrsBuilder*-derived classes (standard, included in the *MeshVS* package, or your custom ones).
2212 * Each *PrsBuilder* is responsible for drawing a *MeshVS_Mesh* presentation in a certain display mode(s) specified as a *PrsBuilder* constructor's argument.
2213   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).
2214 * Pass these objects to the *MeshVS_Mesh::AddBuilder()* method.
2215   *MeshVS_Mesh* takes advantage of improved selection highlighting mechanism: it highlights its selected entities itself, with the help of so called "highlighter" object.
2216   You can set one of *PrsBuilder* objects to act as a highlighter with the help of a corresponding argument of the *AddBuilder()* method.
2217
2218 Visual attributes of the *MeshVS_Mesh* object (such as shading color, shrink coefficient and so on) are controlled through *MeshVS_Drawer* object.
2219 It maintains a map "Attribute ID --> attribute value" and can be easily extended with any number of custom attributes.
2220
2221 In all other respects, *MeshVS_Mesh* is very similar to any other class derived from *AIS_InteractiveObject*
2222 and it should be used accordingly (refer to the description of *AIS package* in the documentation).