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