5e9cfcd815f06da6a691614c3daaa8187beef975
[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 <h4>The presentable object</h4>
54 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.  
55
56 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.  
57
58 Each object to be presented individually must be presentable  or associated with a presentable object. 
59
60 <h4>The viewer </h4>
61 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.  
62
63 <h4>The Interactive Context </h4>
64 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. 
65
66 @subsubsection occt_visu_2_1_2 Presentation packages
67
68 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.  
69
70 * *AIS* package provides all  classes to implement interactive objects (presentable and selectable entities).  
71 * *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*.
72 * *StdPrs* package  provides ready-to-use standard presentation algorithms for specific geometries: points, curves and  shapes of the geometry and topology toolkits.
73 * *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.
74 * *V3d* package provides  the services supported by the 3D viewer.
75 * *Graphic3d* package provides resources to create 3D graphic structures.
76 * *Visual3d* package contains classes implementing commands for 3D viewer.
77 * *DsgPrs* package provides tools for display of dimensions, relations and XYZ trihedrons.
78
79 @subsubsection occt_visu_2_1_3 A Basic Example: How to display a 3D object 
80
81 ~~~~~
82 Void Standard_Real dx  = ...; //Parameters   
83 Void Standard_Real dy  = ...; //to build  a wedge  
84 Void Standard_Real dz  = ...;  
85 Void Standard_Real ltx = ...; 
86
87 Handle(V3d_Viewer)aViewer = ...;  
88 Handle(AIS_InteractiveContext)aContext;  
89 aContext = new AIS_InteractiveContext(aViewer);     
90
91 BRepPrimAPI_MakeWedge w(dx, dy, dz, ltx);  
92 TopoDS_Solid & = w.Solid();  
93 Handle(AIS_Shape) anAis = new AIS_Shape(S);  
94 //creation of the presentable  object  
95 aContext -> Display(anAis);  
96 //Display the presentable  object in the 3d viewer. 
97 ~~~~~
98
99 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.  
100
101 @figure{visualization_image004.svg,"Processes involved in displaying a presentable shape",400}
102
103 @subsection occt_visu_2_2 Selection 
104
105 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.
106
107 There are 3 different selection types:
108   - **Point selection** -- allows picking and highlighting a single object (or its part) located under the mouse cursor;
109   - **Rectangle selection** -- allows picking objects or parts located under the rectangle defined by the start and end mouse cursor positions;
110   - **Polyline selection** -- allows picking objects or parts located under a user-defined non-self-intersecting polyline.
111
112 For OCCT selection algorithm, all selectable objects are represented as a set of sensitive zones, called <b>sensitive entities</b>. When the mouse cursor moves in the view, the sensitive entities of each object are analyzed for collision.
113
114 @subsubsection occt_visu_2_2_1 Terms and notions
115
116 This section introduces basic terms and notions used throughout the algorithm description.
117
118 <h4>Sensitive entity</h4>
119
120 Sensitive entities in the same way as entity owners are links between objects and the selection mechanism.
121
122 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.
123
124 @figure{visualization_image005.png,"Example of a shape divided into sensitive entities",400}
125
126 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).
127
128 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.
129
130 <h4>Entity owner</h4>
131
132 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.  
133
134 <h4>Selection</h4>
135
136 To simplify the handling of different selection modes of an object, sensitive entities linked to its owners are organized into sets, called **selections**.
137
138 Each selection contains entities created for a certain mode along with the sensitivity and update states.
139
140 <h4>Selectable object</h4>
141
142 Selectable object stores information about all created selection modes and sensitive entities.
143
144 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.
145
146 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:
147   - 0 -- selection of the *AIS_Shape*;
148   - 1 -- selection of the vertices;
149   - 2 -- selection of the edges;
150   - 3 -- selection of the wires;
151   - 4 -- selection of the faces;
152   - 5 -- selection of the shells;
153   - 6 -- selection of the constituent solids.
154
155 @figure{visualization_image006.png,"Hierarchy of references from sensitive entity to selectable object",400}
156
157 @figure{visualization_image007.png,"The principle of entities organization within the selectable object",400}
158
159 <h4>Viewer selector</h4>
160
161 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.
162
163 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.
164
165 <h4>Selection manager</h4>
166
167 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.
168
169 @figure{visualization_image008.png,"The relations chain between viewer selector and selection manager",400}
170
171 @subsubsection occt_visu_2_2_2 Algorithm
172
173 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.
174
175 <h4>Selection Frustum</h4>
176
177 The first step of each run of selection algorithm is to build the selection frustum according to the currently activated selection type.
178
179 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.
180
181 The frustum length is limited by near and far view volume planes and each plane is built parallel to the corresponding view volume plane.
182
183 @figure{visualization_image009.png,"",400}
184
185 The image above shows the rectangular frustum: a) after mouse move or click, b) after applying the rectangular selection.
186
187 @figure{visualization_image010.png,"",400}
188
189 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.
190
191 <h4>BVH trees</h4>
192
193 To maintain selection mechanism at the viewer level, a speedup structure composed of 3 BVH trees is used.
194
195 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 <i>AIS_InteractiveObject</i> 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.
196
197 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.
198
199 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.
200
201 @figure{visualization_image022.png,"Selection BVH tree hierarchy: from the biggest object-level (first) to the smallest complex entity level (third)",400}
202
203 <h4>Stages of the algorithm</h4>
204
205 The algorithm includes pre-processing and three main stages.
206
207 * **Pre-processing** -- implies calculation of the selection frustum and its main characteristics.
208 * **First stage** -- traverse of the first level BVH tree.
209
210 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 <i>separating axis theorem (SAT)</i>. When the traverse goes down to the leaf node, it means that a candidate object with possibly overlapping sensitive entities has been found. If no such objects have been detected, the algorithm stops and it is assumed that no object needs to be selected. Otherwise it passes to the next stage to process the entities of the found selectable.
211
212 * **Second stage** -- traverse of the second level BVH tree
213
214 At this stage it is necessary to determine if there are candidates among all sensitive entities of one object.
215
216 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:
217   - activation check - the entity may be inactive at the moment as it belongs to deactivated selection;
218   - 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.
219
220 After these checks the algorithm passes to the last stage.
221
222 * **Third stage** -- overlap or inclusion test of a particular sensitive entity
223
224 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.
225
226 @subsubsection occt_visu_2_2_3 Packages and classes
227
228 Selection is implemented as a combination of various algorithms divided among several packages -- <i>SelectBasics</i>, <i>Select3D</i>, <i>SelectMgr</i> and <i>StdSelect</i>.
229
230 <h4>SelectBasics</h4>
231
232 <i>SelectBasics</i> package contains basic classes and interfaces for selection. The most notable are:
233   - <i>SelectBasics_SensitiveEntity</i> -- the base definition of a sensitive entity;
234   - <i>SelectBasics_EntityOwner</i> -- the base definition of the an entity owner -- the link between the sensitive entity and the object to be selected;
235   - <i>SelectBasics_PickResult</i> -- the structure for storing quantitative results of detection procedure, for example, depth and distance to the center of geometry;
236   - <i>SelectBasics_SelectingVolumeManager</i> -- the interface for interaction with the current selection frustum.
237
238
239 Each custom sensitive entity must inherit at least <i>SelectBasics_SensitiveEntity</i>.
240
241 <h4>Select3D</h4>
242
243 <i>Select3D</i> package provides a definition of standard sensitive entities, such as:
244   - box;
245   - circle;
246   - curve;
247   - face;
248   - group;
249   - point;
250   - segment;
251   - triangle;
252   - triangulation;
253   - wire.
254
255 Each basic sensitive entity inherits <i>Select3D_SensitiveEntity</i>, which is a child class of <i>SelectBasics_SensitiveEntity</i>.
256
257 The package also contains two auxiliary classes, <i>Select3D_SensitivePoly</i> and <i>Select3D_SensitiveSet</i>.
258
259 <i>Select3D_SensitivePoly</i> -- 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 <i>Select3D_SensitivePoly</i> must satisfy the terms of Separating Axis Theorem to use standard OCCT overlap detection methods.
260
261 <i>Select3D_SensitiveSet</i> -- 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.
262
263 <h4>SelectMgr</h4>
264
265 <i>SelectMgr</i> package is used to maintain the whole selection process. For this purpose, the package provides the following services:
266   - activation and deactivation of selection modes for all selectable objects;
267   - interfaces to compute selection mode of the object;
268   - definition of selection filter classes;
269   - keeping selection BVH data up-to-date.
270
271 A brief description of the main classes:
272   - <i>SelectMgr_FrustumBase</i>, <i>SelectMgr_Frustum</i>, <i>SelectMgr_RectangularFrustum</i>, <i>SelectMgr_TriangluarFrustum</i> and <i>SelectMgr_TriangularFrustumSet</i> -- 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);
273   - <i>SelectMgr_SensitiveEntity</i>, <i>SelectMgr_Selection</i> and <i>SelectMgr_SensitiveEntitySet</i> -- store and handle sensitive entities; <i>SelectMgr_SensitiveEntitySet</i> implements a primitive set for the second level BVH tree;
274   - <i>SelectMgr_SelectableObject</i> and <i>SelectMgr_SelectableObjectSet</i> -- describe selectable objects. They also manage storage, calculation and removal of selections. <i>SelectMgr_SelectableObjectSet</i> implements a primitive set for the first level BVH tree;
275   - <i>SelectMgr_ViewerSelector</i> -- encapsulates all logics of the selection algorithm and implements the third level BVH tree traverse;
276   - <i>SelectMgr_SelectionManager</i> -- manages activation/deactivation, calculation and update of selections of every selectable object, and keeps BVH data up-to-date.
277
278 <h4>StdSelect</h4>
279
280 <i>StdSelect</i> package contains the implementation of some <i>SelectMgr</i> classes and tools for creation of selection structures. For example,
281   - <i>StdSelect_BRepOwner</i> -- defines an entity owner with a link to its topological shape and methods for highlighting;
282   - <i>StdSelect_BRepSelectionTool</i> -- contains algorithms for splitting standard AIS shapes into sensitive primitives;
283   - <i>StdSelect_ViewerSelector3d</i> -- an example of <i>SelectMgr_ViewerSelecor</i> implementation, which is used in a default OCCT selection mechanism;
284   - <i>StdSelect_FaceFilter</i>, <i>StdSelect_EdgeFilter</i> -- implementation of selection filters.
285
286 @subsubsection occt_visu_2_2_4 Examples of usage
287
288 The first code snippet illustrates the implementation of <i>SelectMgr_SelectableObject::ComputeSelection()</i> method in a custom interactive object. The method is used for computation of user-defined selection modes.
289
290 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).
291
292 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.
293
294 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.
295
296 ~~~~
297
298 void InteractiveBox::ComputeSelection (const  Handle(SelectMgr_Selection)& theSel,
299                                        const Standard_Integer theMode)
300 {
301   switch (theMode)
302   {
303   case 0:   // creation of face sensitives for selection of the whole box
304   {
305     Handle(SelectMgr_EntityOwner) anOwnr = new SelectMgr_EntityOwner (this, 5);
306     for (Standard_Integer  aFaceIdx = 1; aFaceIdx <= myNbFaces; aFaceIdx++)
307     {
308       Select3D_TypeOfSensitivity aIsInteriorSensitivity = myIsInterior;
309       theSel->Add (new  Select3D_SensitiveFace (anOwnr,
310                                                 myFaces[aFaceIdx]->PointArray(),
311                                                 aIsInteriorSensitivity));
312     }
313     break;
314   }
315   case 1: // creation of edge sensitives for selection of box edges only
316   {
317     for (Standard_Integer anEdgeIdx = 1; anEdgeIdx <= 12; anEdgeIdx++)
318     {
319       // 1 owner per edge, where 6 is a priority of the sensitive
320       Handle(MySelection_EdgeOwner) anOwnr = new MySelection_EdgeOwner (this, anEdgeIdx, 6);
321       theSel->Add (new  Select3D_SensitiveSegment (anOwnr,
322                                                    FirstPnt[anEdgeIdx]),
323                                                    LastPnt[anEdgeIdx]));
324     }
325     break;
326   }
327   }
328 }
329
330 ~~~~
331
332 The algorithms for creating selection structures store sensitive primitives in <i>SelectMgr_Selection</i> instance. Each <i>SelectMgr_Selection</i> sequence in the list of selections of the object must correspond to a particular selection mode.
333
334 To describe the decomposition of the object into selectable primitives, a set of ready-made sensitive entities is supplied in <i>Select3D</i> package. Custom sensitive primitives can be defined through inheritance from <i>SelectBasics_SensitiveEntity</i>.
335
336 To make custom interactive objects selectable or customize selection modes of existing objects, the entity owners must be defined. They must inherit <i>SelectMgr_EntityOwner</i> interface.
337
338
339 Selection structures for any interactive object are created in <i>SelectMgr_SelectableObject::ComputeSelection()</i> method.
340
341 The example below shows how computation of different selection modes of the topological shape can be done using standard OCCT mechanisms, implemented in <i>StdSelect_BRepSelectionTool</i>.
342
343 ~~~~
344   void MyInteractiveObject::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
345                                               const Standard_Integer theMode)
346   {
347     switch (theMode)
348     {
349       case 0:
350         StdSelect_BRepSelectionTool::Load (theSelection, this, myTopoDSShape, TopAbs_SHAPE);
351         break;
352       case 1:
353         StdSelect_BRepSelectionTool::Load (theSelection, this, myTopoDSShape, TopAbs_VERTEX);
354         break;
355       case 2:
356         StdSelect_BRepSelectionTool::Load (theSelection, this, myTopoDSShape, TopAbs_EDGE);
357         break;
358       case 3:
359         StdSelect_BRepSelectionTool::Load (theSelection, this, myTopoDSShape, TopAbs_WIRE);
360         break;
361       case 4:
362         StdSelect_BRepSelectionTool::Load (theSelection, this, myTopoDSShape, TopAbs_FACE);
363         break;
364     }
365   }
366 ~~~~
367
368 The <i>StdSelect_BRepSelectionTool</i> 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 <i>TopoDS_Shape</i>.
369
370 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:
371
372   - each entity owner has to maintain its own <i>Prs3d_Presentation</i> object, that results in a large memory overhead for thousands of owners;
373   - drawing selected owners one by one is not efficient from the OpenGL usage viewpoint.
374
375 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.
376
377 On the basis of <i>SelectMgr_EntityOwner::IsAutoHilight()</i> return value, <i>AIS_LocalContext</i> object either uses the traditional way of highlighting (in case if <i>IsAutoHilight()</i> returns true) or groups such owners according to their selectable objects and finally calls <i> SelectMgr_SelectableObject::HilightSelected()</i> or <i>SelectMgr_SelectableObject::ClearSelected()</i>, passing a group of owners as an argument.
378
379
380 Hence, an application can derive its own interactive object and redefine virtual methods <i>HilightSelected()</i>, <i>ClearSelected()</i> and <i>HilightOwnerWithColor()</i> from <i>SelectMgr_SelectableObject</i>. <i>SelectMgr_SelectableObject::GetHilightPresentation</i> and <i>SelectMgr_SelectableObject::GetSelectPresentation</i> methods can be used to optimize filling of selection and highlight presentations according to the user's needs.
381
382 The <i>AIS_InteractiveContext::HighlightSelected()</i> method can be used for efficient redrawing of the selection presentation for a given interactive object from an application code.
383
384
385 After all the necessary sensitive entities are computed and packed in <i>SelectMgr_Selection</i> instance with the corresponding owners in a redefinition of <i>SelectMgr_SelectableObject::ComputeSelection()</i> method, it is necessary to register the prepared selection in <i>SelectMgr_SelectionManager</i> through the following steps:
386   - if there was no <i>AIS_InteractiveContext</i> opened, create an interactive context and display the selectable object in it;
387   - load the selectable object to the selection manager of the interactive context using <i>AIS_InteractiveContext::Load()</i> method. If the selection mode passed as a parameter to this method is not equal to -1, <i>ComputeSelection()</i> for this selection mode will be called;
388   - activate or deactivate the defined selection mode using <i>AIS_InteractiveContext::Activate()</i> or <i>AIS_InteractiveContext::Deactivate()</i> methods.
389
390 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.
391
392 The code snippet below illustrates the above steps. It also contains the code to start the detection procedure and parse the results of selection.
393
394 ~~~~~
395
396 // Suppose there is an instance of class InteractiveBox from the previous sample.
397 // It contains an implementation of method InteractiveBox::ComputeSelection() for selection
398 // modes 0 (whole box must be selected) and 1 (edge of the box must be selectable)
399 Handle(InteractiveBox) aBox;
400
401 // Assume there is a created interactive context
402 const Handle(AIS_InteractiveContext)& aContext = GetContext();
403 // To prevent automatic activation of the default selection mode
404 aContext->SetAutoActivateSelection (Standard_False);
405
406 aContext->Display (aBox);
407
408 // Load a box to the selection manager without computation of any selection mode
409 aContext->Load (aBox, -1, Standard_True);
410 // Activate edge selection
411 aContext->Activate (aBox, 1);
412
413 // Run the detection mechanism for activated entities in the current mouse coordinates and
414 // in the current view. Detected owners will be highlighted with context highlight color
415 aContext->MoveTo (aXMousePos, aYMousePos, myView);
416 // Select the detected owners
417 aContext->Select();
418 // Iterate through the selected owners
419 for (aContext->InitSelected(); aContext->MoreSelected() && !aHasSelected; aContext->NextSelected())
420 {
421   Handle(AIS_InteractiveObject) anIO = aContext->SelectedInteractive();
422 }
423
424 // deactivate all selection modes for aBox1
425 aContext->Deactivate (aBox1);
426
427 ~~~~~
428
429 It is also important to know, that there are 2 types of detection implemented for rectangular selection in OCCT:
430   - <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;
431   - <b>overlap</b> detection. In this case the sensitive primitive is considered detected when it is partially overlapped by the selection rectangle.
432
433 The standard OCCT selection mechanism uses inclusion detection by default. To change this, use the following code:
434
435 ~~~~~
436
437 // Assume there is a created interactive context 
438 const Handle(AIS_InteractiveContext)& aContext = GetContext();
439 // Retrieve the current viewer selector
440 const Handle(StdSelect_ViewerSelector3d)& aMainSelector = aContext->MainSelector();
441 // Set the flag to allow overlap detection
442 aMainSelector->AllowOverlapDetection (Standard_True);
443
444 ~~~~~
445
446 @section occt_visu_3 Application Interactive Services 
447 @subsection occt_visu_3_1 Introduction 
448
449 Application Interactive Services allow managing presentations and dynamic selection in a viewer in a simple and  transparent manner. 
450
451 The central entity for management of visualization and selections is the **Interactive Context**. It is connected to the main viewer (and if  need be, the trash bin viewer). It has two operating modes: the Neutral Point and  the local visualization and selection context. 
452
453 The neutral point, which is the  default mode, allows easily visualizing and selecting interactive objects loaded into the context. 
454
455 **Local Contexts** can be opened to prepare and use a temporary selection environment without disturbing
456 the neutral point. It is possible to choose the interactive objects, which you want to act on, the selection modes, which you want to activate, and the temporary visualizations, which you will execute. 
457
458 When the operation is finished, you close the current local context and return to the state 
459 in which you were before opening it (neutral point or previous local context).  
460
461 **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.  
462
463 @figure{visualization_image016.png,"",240}
464
465 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. 
466
467 When an Interactive Object is visualized, the required graphic attributes are taken from its own **Drawer** if it has the required custom attributes or otherwise from the context drawer. 
468
469 @figure{visualization_image017.png,"",360}
470
471 It can be necessary to filter the entities to be selected. Consequently there are **Filter** entities, which allow refining the dynamic detection context.  Some of these filters can be used at the Neutral Point, others only in an open local context. It is possible to program custom filters and load them into the interactive context.  
472
473 @subsection occt_visu_3_2 Interactive objects
474
475 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.
476
477 @subsubsection occt_visu_3_2_1 Presentations
478
479 An interactive object can have as many  presentations as its creator wants to give it. 
480
481 3D presentations are managed by PresentationManager3D. As this is  transparent in AIS, the user does not have to worry about it. 
482
483 A presentation is identified by an index and by the reference to  the Presentation Manager which it depends on. 
484
485 By convention, the default mode of  representation for the Interactive Object has index 0. 
486
487 @figure{visualization_image018.png,"",360}
488
489 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.  
490
491 If you are creating your own type of interactive object, you  must implement the Compute function in one of the following ways:  
492
493 #### For 3D:
494
495 ~~~~~
496 void PackageName_ClassName::Compute  
497         (const  Handle(PrsMgr_PresentationManager3d)& aPresentationManager,   
498          const  Handle(Prs3d_Presentation)& aPresentation,  
499          const Standard_Integer aMode =  0);  
500 ~~~~~
501
502 ####  For hidden line removal (HLR) mode in 3D:
503 ~~~~~
504 void PackageName_ClassName::Compute  
505         (const  Handle(Prs3d_Projector)& aProjector,  
506          const  Handle(Prs3d_Presentation)& aPresentation);  
507 ~~~~~
508
509 @subsubsection occt_visu_3_2_2 Hidden Line Removal
510
511 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. 
512
513 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:
514
515 * Initially by using one of the values of the enumeration  *PrsMgr_TypeOfPresentation*: 
516   * *PrsMgr_TOP_AllView*,
517   * *PrsMgr_TOP_ProjectorDependant*
518
519 * Later by using the function *PrsMgr_PresentableObject::SetTypeOfPresentation* 
520
521 *AIS_Shape* class is an example of an interactive object that supports  HLR representation. It supports two types of the HLR algorithm:  
522 * the  polygonal algorithm based on the shape's triangulation; 
523 * the  exact algorithm that works with the shape's real geometry. 
524
525 The type of the HLR algorithm is stored in *AIS_Drawer* of the  shape. It is a value of the *Prs3d_TypeOfHLR* enumeration and can be set to: 
526         * *Prs3d_TOH_PolyAlgo* for a polygonal algorithm; 
527         * *Prs3d_TOH_Algo*  for an exact algorithm; 
528         * *Prs3d_TOH_NotSet*  if the type of algorithm is not set for the given interactive object instance. 
529
530 The type of the HLR algorithm used for *AIS_Shape* can be changed by calling the *AIS_Shape::SetTypeOfHLR()* method. 
531
532 The current  HLR algorithm type can be obtained using *AIS_Shape::TypeOfHLR()* method  is to be used. 
533
534 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*.
535
536 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. 
537
538 @subsubsection occt_visu_3_2_3 Presentation modes
539
540 There are four types of interactive objects in AIS:  
541   * the "construction element" or Datum, 
542   * the Relation (dimensions and constraints) 
543   * the Object 
544   * the None type (when the object is  of an unknown type). 
545
546 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:  
547   * *AIS_InteractiveObject::Type*  
548   * *AIS_InteractiveObject::Signature*.  
549
550 **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".  
551
552 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. 
553
554 Consequently, to get information about this class it is necessary to use virtual  function *AIS_InteractiveObject::AcceptDisplayMode*.  
555
556 #### Display Mode
557
558 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.
559
560 #### Highlight Mode
561
562 At dynamic detection, the presentation echoed  by the Interactive Context, is by default the presentation already on the screen. 
563
564 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. 
565
566 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). 
567
568 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.  
569
570 #### Infinite Status
571 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. 
572
573 Let us take for example the class called *IShape* representing  an interactive object :
574
575 ~~~~~ 
576 myPk_IShape::myPK_IShape  
577         (const TopoDS_Shape& SH,  PrsMgr_TypeOfPresentation aType):  
578         AIS_InteractiveObject(aType), myShape(SH), myDrwr(new AIS_Drawer())  {SetHilightMode(0);}   
579 void myPk_IShape::Compute  
580         (const Handle(PrsMgr_PresentationManager3d)  & PM,  
581          const Handle(Prs3d_Presentation)& P,   
582          const Standard_Integer TheMode) 
583
584         switch (TheMode){  
585         case 0: 
586         StdPrs_WFDeflectionShape::Add  (P,myShape,myDrwr);  //algo for  calculation of wireframe presentation break;  
587         case 1: 
588         StdPrs_ShadedShape::Add  (P,myShape,myDrwr);   //algo for calculation of shading presentation.  
589         break; 
590         }  
591 }  
592 void myPk_IsShape::Compute  
593         (const  Handle(Prs3d_Projector)& Prj,  
594         const  Handle(Prs3d_Presentation) P)  
595
596         StdPrs_HLRPolyShape::Add(P,myShape,myDrwr); 
597         //Hidden line mode calculation algorithm  
598 }  
599 ~~~~~
600
601 @subsubsection occt_visu_3_2_4 Selection 
602
603 An interactive object can have an indefinite number of selection modes, each representing a "decomposition" into sensitive primitives. Each primitive has an <i>owner</i> (*SelectMgr_EntityOwner*) which allows identifying the exact interactive object or shape which has been detected (see @ref occt_visu_2_2 "Selection" chapter).  
604
605 The set of sensitive primitives, which correspond to a given mode, is stocked in a <b>selection</b> (*SelectMgr_Selection*).
606
607 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 <i>SelectMgr_SelectableObject::setGlobalSelMode()</i>.
608
609 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*.
610
611 A detailed explanation of the mechanism and the manner of implementing this function has been given in @ref occt_visu_2_2 "Selection" chapter.
612
613 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*.  
614
615 You can change the default selection mode index of a custom interactive object using the following functions:
616   * *AIS_InteractiveObject::setGlobalSelMode* sets global selection mode;
617   * *AIS_InteractiveObject::GlobalSelectionMode* returns global selection mode of the object;
618   * *AIS_InteractiveObject::GlobalSelOwner* returns an entity owner that corresponds to a global selection mode.
619   
620 You also can temporarily change the priority of some interactive objects for selection of the global mode to facilitate their graphic detection using the following functions:
621   * *AIS_InteractiveObject::HasSelectionPriority* checks if there is a selection priority setting for the  owner; 
622   * *AIS_InteractiveObject::SelectionPriority* checks the current priority; 
623   * *AIS_InteractiveObject::SetSelectionPriority* sets a priority; 
624   * *AIS_InteractiveObject::UnsetSelectionPriority* unsets the priority.
625   
626     
627 @subsubsection occt_visu_3_2_5 Graphic attributes
628
629 Graphic attributes manager, or *AIS Drawer*, stores graphic attributes for specific interactive objects and for interactive objects controlled by interactive context.
630
631 Initially, all drawer attributes are filled out with the predefined values which will define the default 3D object appearance.
632
633 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.
634
635 Keep in mind the following points concerning graphic attributes:
636   * Each interactive object can have its own visualization  attributes.
637   * The set of graphic attributes of an interactive object is stocked  in an *AIS_Drawer*, which is only a *Prs3d_Drawer* with the  possibility of a link to another drawer 
638   * 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.) 
639   * 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. 
640
641 @figure{visualization_image019.png,"Redefinition of virtual functions for changes in AIS_Point",360}
642
643 @figure{visualization_image020.png,"Redefinition of virtual functions for changes in AIS_Shape.",360}
644
645 The  following virtual functions provide settings for color, width, material and transparency:  
646   * *AIS_InteractiveObject::UnsetColor* 
647   * *AIS_InteractiveObject::SetWidth* 
648   * *AIS_InteractiveObject::UnsetWidth* 
649   * *AIS_InteractiveObject::SetMaterial   (const Graphic3d_NameOfPhysicalMaterial & aName)* 
650   * *AIS_InteractiveObject::SetMaterial   (const Graphic3d_MaterialAspect & aMat)* 
651   * *AIS_InteractiveObject::UnsetMaterial* 
652   * *AIS_InteractiveObject::SetTransparency* 
653   * *AIS_InteractiveObject::UnsetTransparency* 
654
655 For other types of attribute, it is  appropriate to change the Drawer of the object directly using:  
656   * *AIS_InteractiveObject::SetAttributes*
657   * *AIS_InteractiveObject::UnsetAttributes*
658
659 It is important to know which functions may imply the recalculation of  presentations of the object. 
660
661 If the presentation mode of an interactive object is to be updated, a flag from *PrsMgr_PresentableObject*  indicates this. 
662
663 The mode can be updated using the functions *Display*  and *Redisplay* in *AIS_InteractiveContext*.  
664
665 @subsubsection occt_visu_3_2_6 Complementary  Services
666
667 When you use complementary services for interactive objects, pay special attention to the cases mentioned below. 
668
669 #### Change the location of an interactive object
670
671 The following functions  allow temporarily "moving" the representation and selection of  Interactive Objects in a view without recalculation.  
672   * *AIS_InteractiveContext::SetLocation*  
673   * *AIS_InteractiveContext::ResetLocation*  
674   * *AIS_InteractiveContext::HasLocation*  
675   * *AIS_InteractiveContext::Location*  
676  
677 #### Connect an interactive object to an applicative  entity
678
679 Each Interactive Object has functions that allow attributing it an *Owner* in form of a *Transient*.  
680   * *AIS_InteractiveObject::SetOwner*  
681   * *AIS_InteractiveObject::HasOwner*  
682   * *AIS_InteractiveObject::Owner*  
683
684 An interactive object can therefore be associated or not with an applicative entity, without affecting its behavior. 
685
686 #### Resolving coincident topology
687
688 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. 
689
690 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. 
691
692 The method *AIS_InteractiveObject::SetPolygonOffsets (const Standard_Integer aMode, const Standard_Real aFactor, const Standard_Real aUnits)* allows setting up the polygon  offsets.
693
694 The  parameter *aMode* can contain various combinations of *Aspect_PolygonOffsetMode* enumeration elements: 
695   * *Aspect_POM_None*
696   * *Aspect_POM_Off*
697   * *Aspect_POM_Fill*
698   * *Aspect_POM_Line*
699   * *Aspect_POM_Point*
700   * *Aspect_POM_All*
701
702 The combination  of these elements defines the polygon display modes that will use the given  offsets. You can switch off the polygon offsets by passing *Aspect_POM_Off*.  Passing *Aspect_POM_None* allows changing the *aFactor* and *aUnits* values  without changing the mode. If *aMode* is different from *Aspect_POM_Off*, the  *aFactor* and *aUnits* arguments are used by the graphics renderer to calculate the  depth offset value: 
703 ~~~~~
704  offset  = aFactor * m + aUnits * r
705 ~~~~~
706 where  *m* is the maximum depth slope for the currently displayed polygons, r is the minimum  depth resolution (implementation-specific). 
707
708 Negative  offset values move polygons closer to the viewer while positive values shift  polygons away. 
709
710 **Warning**
711  
712 This  method has a side effect -- it creates its own shading aspect if not yet  created, so it is better to set up the object shading aspect first. 
713
714 You can use the following  functions to obtain the current settings for polygon offsets: 
715 ~~~~~
716   void  AIS_InteractiveObject::PolygonOffsets
717                 (Standard_Integer &aMode, 
718                  Standard_Real &aFactor, 
719                  Standard_Real &aUnits) 
720   Standard_Boolean AIS_InteractiveObject::HasPolygonOffsets() 
721 ~~~~~
722
723 The same  operation could be performed for the interactive object known by the *AIS_InteractiveContext* with the following methods: 
724 ~~~~~
725 void  AIS_InteractiveContext::SetPolygonOffsets
726         (const Handle(AIS_InteractiveObject) &anObj, 
727          const Standard_Integer aMode,  
728          const Standard_Real aFactor, 
729          const Standard_Real aUnits) 
730 void  AIS_InteractiveContext::PolygonOffsets
731         (const Handle(AIS_InteractiveObject) &anObj, 
732          Standard_Integer &aMode,  
733          Standard_Real &aFactor, 
734          Standard_Real &aUnits) 
735 Standard_Boolean      AIS_InteractiveContext::HasPolygonOffsets
736         (const Handle(AIS_InteractiveObject) &anObj) 
737 ~~~~~
738
739
740 @subsubsection occt_visu_3_2_7 Object hierarchy
741
742 Each *PrsMgr_PresentableObject* has a list of objects called *myChildren*.
743 Any transformation of *PrsMgr_PresentableObject* is also applied to its children. This hierarchy does not propagate to *Graphic3d* level and below.
744
745 *PrsMgr_PresentableObject* sends its combined (according to the hierarchy) transformation down to *Graphic3d_Structure*.
746
747 The materials of structures are not affected by the hierarchy.
748
749 Object hierarchy can be controlled by the following API calls:
750 *       *PrsMgr_PresentableObject::AddChild*;
751 *       *PrsMgr_PresentableObject::RemoveChild*.
752
753 @subsubsection occt_visu_3_2_8 Instancing
754
755 The conception of instancing operates the object hierarchy as follows:
756 *       Instances are represented by separated *AIS* objects.
757 *       Instances do not compute any presentations.
758
759 Classes *AIS_ConnectedInteractive* and *AIS_MultipleConnectedInteractive* are used to implement this conception.
760
761 *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.
762
763 *AIS_ConnectedInteractive* can be referenced to any *AIS_Interactive* object in general. When it is referenced to another *AIS_ConnectedInteractive*, it just copies the reference.
764
765 *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.
766
767 All *AIS_MultipleConnectedInteractive* are able to have child assemblies. Deep copy of object instances tree is performed if one assembly is attached to another.
768
769 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.
770
771 Instances can be controlled by the following DRAW commands:
772 *       *vconnect* : Creates and displays *AIS_MultipleConnectedInteractive* object from input objects and location.
773 *       *vconnectto* : Makes an instance of object with the given position.
774 *       *vdisconnect* : Disconnects all objects from an assembly or disconnects an object by name or number.
775 *       *vaddconnected* : Adds an object to the assembly.
776 *       *vlistconnected* : Lists objects in the assembly.
777
778 Have a look at the examples below:
779 ~~~~~
780 pload ALL
781 vinit
782 psphere s 1
783 vdisplay s
784 vconnectto s2 3 0 0 s  # make instance
785 vfit
786 ~~~~~
787
788 See how proxy *OpenGl_Structure* is used to represent instance:
789
790 @figure{/user_guides/visualization/images/visualization_image029.png,"",240}
791
792 The original object does not have to be displayed in order to make instance. Also selection handles transformations of instances correctly:
793
794 ~~~~~
795 pload ALL
796 vinit
797 psphere s 1
798 psphere p 0.5
799 vdisplay s             # p is not displayed
800 vsetloc s -2 0 0
801 vconnect x 3 0 0 s p   # make assembly
802 vfit
803 ~~~~~
804
805 @figure{/user_guides/visualization/images/visualization_image030.png,"",420}
806
807 Here is the example of a more complex hierarchy involving sub-assemblies:
808
809 ~~~~~
810 pload ALL
811 vinit
812 box b 1 1 1
813 psphere s 0.5
814 vdisplay b s
815 vsetlocation s 0 2.5 0
816 box d 0.5 0.5 3
817 box d2 0.5 3 0.5
818 vdisplay d d2
819
820 vconnectto b1 -2 0 0 b
821 vconnect z 2 0 0 b s
822 vconnect z2 4 0 0 d d2
823 vconnect z3 6 0 0 z z2
824 vfit
825 ~~~~~
826
827
828 @subsection occt_visu_3_3 Interactive Context 
829
830 @subsubsection occt_visu_3_3_1 Rules 
831
832 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.  
833
834 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.  
835
836 ~~~~~
837 Handle (AIS_Shape) TheAISShape = new AIS_Shape (ashape);  
838         myIntContext->Display(TheAISShape);  
839         myIntContext->SetDisplayMode(TheAISShape ,1);  
840         myIntContext->SetColor(TheAISShape,Quantity_NOC_RED);  
841 ~~~~~
842
843 You can also write  
844
845 ~~~~~
846 Handle (AIS_Shape) TheAISShape = new AIS_Shape (ashape);  
847         TheAISShape->SetColor(Quantity_NOC_RED);  
848         TheAISShape->SetDisplayMode(1);  
849         myIntContext->Display(TheAISShape);  
850 ~~~~~
851
852 @subsubsection occt_visu_3_3_2 Groups of functions 
853
854 **Neutral Point** and **Local Context** constitute the two operating modes or states of the **Interactive Context**, which is the central entity which pilots visualizations and selections.
855
856 The **Neutral Point**, which is the default mode, allows easily visualizing and selecting interactive objects, which have been loaded into the context. Opening **Local contexts** allows preparing and using a temporary selection environment without disturbing the neutral point.
857
858 A set of functions allows choosing the interactive objects which you want to act on, the selection modes which you want to activate, and the temporary visualizations which you will execute. When the operation is finished, you close the current local context and return to the state in which you were before opening it (neutral point or previous local context).
859
860 The Interactive Context is composed of many  functions, which can be conveniently grouped according to the theme:  
861   * management proper to the context; 
862   * management in the local context; 
863   * presentations and selection in open/closed context; 
864   * selection strictly speaking. 
865
866 Some functions can only be used in open Local Context; others in closed local context; others do not have the same behavior in one state as in the other.
867
868 @subsubsection occt_visu_3_3_3 Management of the Interactive Context 
869
870 The **Interactive Context** is made up of a **Principal Viewer** and, optionally, a trash bin or **Collector Viewer**.
871
872 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.
873
874 When an interactive object is visualized, the required graphic attributes are first taken from the object's own <i>Drawer</i> if one exists, or from the context drawer for the others.
875
876 The following adjustable settings allow personalizing the behavior of presentations  and selections:
877   * Default Drawer, containing all the color and line attributes  which can be used by interactive objects, which do not have their own attributes.
878   * Default Visualization Mode for interactive objects.  By default: *mode  0* ;  
879   * Highlight color of entities detected by mouse movement. By default: *Quantity_NOC_CYAN1*;  
880   * Pre-selection color. By default:  *Quantity_NOC_GREEN*;  
881   * Selection color (when you click on a detected object). By default:  *Quantity_NOC_GRAY80*;  
882   * Sub-Intensity color. By default: *Quantity_NOC_GRAY40*.
883
884 All of these settings can be modified by functions proper to  the Context.  
885
886 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.  
887
888 Let us examine the case of two interactive objects: *obj1* and *obj2*:  
889
890 ~~~~~
891 TheCtx->Display(obj1,Standard_False); // False = no viewer update 
892 TheCtx->Display(obj2,Standard_True); // True = viewer update  
893 TheCtx->SetDisplayMode(obj1,3,Standard_False); 
894 TheCtx->SetDisplayMode(2); 
895 // obj2 is visualised in mode 2 (if it accepts this mode) 
896 // obj1 stays visualised in its mode 3.  
897 ~~~~~
898
899 *PresentationManager3D*  and *Selector3D*, which manage the presentation and selection of present  interactive objects,  are associated to the main Viewer. The same is true of the optional Collector. 
900
901 @subsection occt_visu_3_4 Local Context 
902
903 @subsubsection occt_visu_3_4_1 Rules and Conventions 
904
905   * Opening a local context allows preparing an environment for  temporary presentations and selections, which will disappear once the local  context is closed. 
906   * It is possible to open several local contexts, but only the last  one will be active. 
907   * When you close a local context, the previous one, which is still on  the stack, is activated again. If none is left, you return to Neutral Point. 
908   * Each local context has an index created when the context opens. You  should close the local context, which you have opened. 
909
910 The interactive object, which is used the most by  applications, is *AIS_Shape*. Consequently, standard functions are  available which allow you to easily prepare selection operations on the  constituent elements of shapes (selection of vertices, edges, faces etc) in an  open local context. The selection modes specific to "Shape" type objects are  called **Standard Activation Mode**. These modes are only taken into account  in open local context and only act on interactive objects which have redefined  the virtual function *AcceptShapeDecomposition()* so that it returns *TRUE*.   
911   * Objects, which are temporarily in a local context, are not  recognized by other local contexts a priori. Only objects visualized in Neutral  Point are recognized by all local contexts. 
912   * The state of a temporary interactive object in a local context  can only be modified while another local context is open. 
913
914 **Warning**
915
916 The specific modes of selection only concern the interactive  objects, which are present in the Main Viewer. In the Collector, you can only  locate interactive objects, which answer positively to the positioned filters  when a local context is open, however, they are never decomposed in  standard mode.  
917
918 @subsubsection occt_visu_3_4_2 Management of Local Context
919
920 The local context can be opened using method *AIS_InteractiveContext::OpenLocalContext*. The following options are available:
921   * *UseDisplayedObjects*: allows loading the  interactive objects visualized at Neutral Point in the opened local context. If *FALSE*, the local context is empty after being opened. If *TRUE*,  the objects at Neutral Point are modified by their default selection mode. 
922   * *AllowShapeDecomposition*: *AIS_Shape* allows or prevents  decomposition in standard shape location mode of objects at Neutral Point,  which are type-privileged (see @ref occt_visu_3_2_4 "Selection" chapter). This Flag is only taken  into account when *UseDisplayedObjects* is *TRUE*. 
923   * *AcceptEraseOfObjects*: authorizes other local contexts to erase  the interactive objects present in this context. This option is rarely used. The last option has no current use.
924
925 This function returns the index of the created local context.  It should be kept and used when the context is closed.  
926
927 To load objects visualized at Neutral Point into a local  context or remove them from it use methods
928 ~~~~~ 
929   AIS_InteractiveContext::UseDisplayedObjects  
930   AIS_InteractiveContext::NotUseDisplayedObjects  
931 ~~~~~
932 Closing Local Contexts is done by:  
933 ~~~~~
934   AIS_InteractiveContext::CloseLocalContext  
935   AIS_InteractiveContext::CloseAllContexts  
936 ~~~~~
937
938 *Warning* 
939 When the index is not specified in the first function, the  current Context is closed. This option can be dangerous, as other Interactive  Functions can open local contexts without necessarily warning the user. For  greater security, you have to close the context with the index given on  opening. 
940
941 To get the index of the current context, use function *AIS_InteractiveContext::IndexOfCurrentLocal*. It allows closing all open local  contexts at one go. In this case, you find yourself directly at Neutral Point.  
942
943 When you close a local context, all temporary interactive  objects are deleted, all selection modes concerning the context are canceled, and all content filters are emptied.
944
945
946 @subsubsection occt_visu_3_4_3 Presentation in a Neutral Point 
947
948 You must distinguish between the **Neutral Point** and the **Open Local Context** states. Although the majority of visualization  functions can be used in both situations, their behavior is different.
949
950 Neutral Point should be used to visualize the interactive  objects, which represent and select an applicative entity. Visualization and  Erasing orders are straightforward: 
951
952 ~~~~~
953 AIS_InteractiveContext::Display  
954         (const  Handle(AIS_InteractiveObject)& anIobj, 
955          const  Standard_Boolean updateviewer=Standard_True);  
956
957 AIS_InteractiveContext::Display  
958         (const  Handle(AIS_InteractiveObject)& anIobj,  
959          const  Standard_Integer amode, 
960          const  Standard_Integer aSelectionMode, 
961          const  Standard_Boolean updateviewer = Standard_True,  
962          const  Standard_Boolean allowdecomposition =  Standard_True);  
963
964   AIS_InteractiveContext::Erase  
965   AIS_InteractiveContext::EraseMode  
966   AIS_InteractiveContext::ClearPrs  
967   AIS_InteractiveContext::Redisplay  
968   AIS_InteractiveContext::Remove  
969   AIS_InteractiveContext::EraseAll  
970   AIS_InteractiveContext::Hilight  
971   AIS_InteractiveContext::HilightWithColor  
972 ~~~~~
973   
974 Bear in mind the following points:  
975   * It is recommended to display and erase interactive objects when  no local context is opened, and open a local context for local selection only.
976   * The first *Display* function among the two ones available in  *InteractiveContext* visualizes the object in its default mode (set with  help of SetDisplayMode() method of InteractiveObject prior to Display() call),  or in the default context mode, if applicable. If it has neither, the function  displays it in 0 presentation mode. The object's default selection mode is  automatically activated (0 mode by convention). 
977   * Activating the displayed object by default can be turned off with  help of *SetAutoActivateSelection()* method. This might be efficient if  you are not interested in selection immediately after displaying an object.
978   * The second *Display* function should only be used in Neutral  Point to visualize a supplementary mode for the object, which you can erase by  *EraseMode (...)*. You activate the selection mode. This is passed as an argument.  By convention, if you do not want to activate a selection mode, you must set  the *SelectionMode* argument to -1. This function is  especially interesting in open local context, as we will see below. 
979   * In Neutral Point, it is not advisable to activate other selection  modes than the default selection one. It is preferable to open a local context  in order to activate particular selection modes. 
980   * When you call *Erase(Interactive object)* function, the *PutIncollector*  argument, which is *FALSE* by default, allows you to visualize the object  directly in the Collector and makes it selectable (by activation of 0 mode).  You can nonetheless block its passage through the Collector by changing the  value of this option. In this case, the object is present in the Interactive  Context, but is not seen anywhere. 
981   * *Erase()* with *putInCollector = Standard_True*  might be slow as it recomputes the object presentation in the Collector. Set *putInCollector* to *Standard_False* if you simply want to hide the object's  presentation temporarily.
982   * Visualization attributes and graphic behavior can be modified through a set of functions similar to those for the interactive object (color, thickness of line, material, transparency,  locations, etc.) The context then manages immediate and deferred updates. 
983   * Call *Remove()* method of *InteractiveContext* as soon  as the interactive object is no longer needed and you want to destroy it..  Otherwise, references to *InteractiveObject* are kept by *InteractiveContext*,  and the *Object* is not destroyed, which results in memory leaks. In  general, if the presentation of an  interactive object can be computed quickly, it  is recommended to *Remove()* it instead of using *Erase()* method.
984
985 @subsubsection occt_visu_3_4_4 Presentation in the Local Context
986
987 In open local context, the *Display* functions presented above can be as well.  
988
989 **WARNING** 
990
991 The function *AIS_InteractiveObject::Display* automatically  activates the object's default selection mode. When you only want to visualize  an Interactive Object in open Context, you must call the function *AIS_InteractiveContext::Display*.  
992
993 You can activate or deactivate specific selection modes in the local open context in several different ways:  
994 Use the Display functions with the appropriate modes.
995    
996 ~~~~~
997   AIS_InteractiveContext::ActivateStandardMode
998   //can be used only if a  Local Context is opened.   
999   AIS_InteractiveContext::DeactivateStandardMode  
1000   AIS_InteractiveContext::ActivatedStandardModes  
1001   AIS_InteractiveContext::SetShapeDecomposition  
1002 ~~~~~
1003
1004 This activates the corresponding  selection mode for all objects in Local Context, which accept decomposition  into sub-shapes. Every new Object which has been loaded into the interactive  context and which meets the decomposition criteria is automatically  activated according to these modes.  
1005
1006 **WARNING**
1007
1008 If you have opened a local context by loading an object with  the default options <i>(AllowShapeDecomposition = Standard_True)</i>, all objects of  the "Shape" type are also activated with the same modes. You can change the  state of these "Standard" objects by using *SetShapeDecomposition(Status)*.  
1009
1010 Load an interactive object by the function *AIS_InteractiveContext::Load*.  
1011
1012 This function allows loading an Interactive Object  whether it is visualized or not with a given selection mode, and/or with the necessary decomposition option. If *AllowDecomp=TRUE* and obviously, if the  interactive object is of the "Shape" type, these "standard" selection modes  will be automatically activated as a function of the modes present in the Local  Context.  
1013
1014 Use *AIS_InteractiveContext::Activate* and *AIS_InteractiveContext::Deactivate* to directly activate/deactivate selection modes on an object.
1015
1016 @subsubsection occt_visu_3_4_5 Filters 
1017
1018 To define an environment of dynamic detection, you can use standard filter classes or create your own.
1019 A filter questions the owner of the sensitive primitive in local context to determine if it has the desired qualities. If it answers positively, it is kept. If not, it is rejected.
1020
1021 The root class of objects is *SelectMgr_Filter*.  The principle behind it is straightforward: a filter tests to see whether the  owners <i>(SelectMgr_EntityOwner)</i> detected in mouse position by the Local  context selector answer *OK*. If so, it is kept, otherwise it is rejected.  
1022
1023 You can create a custom class of filter objects by  implementing the deferred function *IsOk()*:  
1024
1025 ~~~~~
1026 class MyFilter : public SelectMgr_Filter { };  
1027 virtual Standard_Boolean MyFilter::IsOk  
1028         (const Handle(SelectMgr_EntityOwner)&  anObj) const = 0; 
1029 ~~~~~
1030
1031 In *SelectMgr*, there are also Composition filters (AND  Filters, OR Filters), which allow combining several filters. In  InteractiveContext , all filters that you add are stocked in an OR filter  (which answers *OK* if at least one filter answers *OK*).  
1032
1033 There are Standard filters, which have already been  implemented in several packages:  
1034   * *StdSelect_EdgeFilter* -- for edges, such as lines and circles;  
1035   * *StdSelect_FaceFilter* -- for faces, such as planes, cylinders and spheres;  
1036   * *StdSelect_ShapeTypeFilter* -- for shape types, such as compounds, solids, shells and wires;
1037   * *AIS_TypeFilter* -- for types  of interactive objects;  
1038   * *AIS_SignatureFilter* -- for types  and signatures of interactive objects; 
1039   * *AIS_AttributeFilter* -- for attributes of Interactive Objects, such as color and width.  
1040
1041 As there are specific behaviors on shapes, each new *Filter* class must, if necessary, redefine *AIS_LocalContext::ActsOn* function, which informs the Local Context if it acts on specific types of sub-shapes.  By default, this  function answers *FALSE*.
1042
1043 **WARNING**
1044  
1045 Only type filters are activated in Neutral Point to  make it possible to identify a specific type of visualized object. For filters to come into play, one or more object selection modes must be activated.  
1046
1047 There are several functions to manipulate filters:  
1048 * *AIS_InteractiveContext::AddFilter* adds a filter passed as an argument.  
1049 * *AIS_InteractiveContext::RemoveFilter* removes a filter passed as an argument.  
1050 * *AIS_InteractiveContext::RemoveFilters* removes all present filters.  
1051 * *AIS_InteractiveContext::Filters* gets the list of filters active in a local context.  
1052   
1053 <h4>Example </h4>
1054
1055 ~~~~~
1056 myContext->OpenLocalContext(Standard_False);  
1057 // no object in neutral point is  loaded  
1058
1059 myContext->ActivateStandardMode(TopAbs_Face);  
1060 //activates decomposition of  shapes into faces.  
1061 Handle (AIS_Shape) myAIShape = new AIS_Shape (  ATopoShape);  
1062
1063 myContext->Display(myAIShape,1,-1,Standard_True,Standard_True);  
1064
1065 //shading visualization mode,  no specific mode, authorization for decomposition into sub-shapes. At this  Stage, myAIShape is decomposed into faces...  
1066
1067 Handle(StdSelect_FaceFilter) Fil1= new  
1068         StdSelect_FaceFilter(StdSelect_Revol);   
1069 Handle(StdSelect_FaceFilter) Fil2= new 
1070       StdSelect_FaceFilter(StdSelect_Plane);  
1071
1072 myContext->AddFilter(Fil1);   
1073 myContext->AddFilter(Fil2);  
1074
1075 //only faces of revolution or  planar faces will be selected 
1076       
1077 myContext->MoveTo( xpix,ypix,Vue);  
1078 // detects the mouse position  
1079 ~~~~~
1080
1081 @subsubsection occt_visu_3_4_6 Selection in the Local Context
1082  
1083 Dynamic detection and selection are put into effect in a  straightforward way. There are only a few conventions and functions to be  familiar with. The functions are the same in neutral point and in open local context:   
1084   * *AIS_InteractiveContext::MoveTo* -- passes  mouse position to Interactive Context selectors  
1085   * *AIS_InteractiveContext::Select* -- stocks  what has been detected on the last *MoveTo*. Replaces the previously selected  object. Empties the stack if nothing has been detected at the last move  
1086   * *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.  
1087   * *AIS_InteractiveContext::Select* -- selects  everything found in the surrounding area.  
1088   * *AIS_InteractiveContext::ShiftSelect* -- selects  what was not previously in the list of selected, deselects those already present.  
1089
1090 Highlighting of detected and selected entities is  automatically managed by the Interactive Context, whether you are in neutral  point or Local Context. The Highlight colors are those dealt with above. You  can nonetheless disconnect this automatic mode if you want to manage this part yourself :  
1091 ~~~~~
1092   AIS_InteractiveContext::SetAutomaticHilight  
1093   AIS_InteractiveContext::AutomaticHilight  
1094 ~~~~~
1095
1096 If there is no open local context, the objects selected are called **current objects**. If there is a  local context, they are called **selected objects**. Iterators allow  entities to be recovered in either case. A set of functions allows manipulating the objects, which have been placed in these different lists.  
1097
1098 **WARNING**
1099
1100 When a Local Context is open, you can select entities other  than interactive objects (vertices, edges etc.) from decompositions in standard  modes, or from activation in specific modes on specific interactive objects.  Only interactive objects are stocked in the list of selected objects. 
1101
1102 You can  question the Interactive context by moving the mouse. The following functions can be used:  
1103   * *AIS_InteractiveContext::HasDetected* informs if something has been detected; 
1104   * *AIS_InteractiveContext::HasDetectedShape* informs if it is a shape; 
1105   * *AIS_InteractiveContext::DetectedShape* gets the shape if the detected entity is an object;
1106   * *AIS_InteractiveContext::DetectedInteractive* gets the interactive object if the detected entity is an object. 
1107
1108 After using the *Select* and *ShiftSelect* functions in Neutral Point, you can explore the list of selections, referred to as current objects  in this context. The following functions can be used:    
1109   * *AIS_InteractiveContext::InitCurrent* initiates a scan of this list; 
1110   * *AIS_InteractiveContext::MoreCurrent* extends the scan; 
1111   * *AIS_InteractiveContext::NextCurrent* resumes the scan; 
1112   * *AIS_InteractiveContext::Current* gets the name of the current object  detected in the scan; 
1113   * *AIS_InteractiveContext::FirstCurrentObject* gets the first current interactive object; 
1114   * *AIS_InteractiveContext::HilightCurrents* highlights current objects; 
1115   * *AIS_InteractiveContext::UnhilightCurrents* removes highlight from current objects; 
1116   * *AIS_InteractiveContext::ClearCurrents* empties the list of current objects in order to update it; 
1117   * *AIS_InteractiveContext::IsCurrent* finds the current object. 
1118
1119 In the Local Context, you can explore the list of selected  objects available. The following functions can be used:    
1120   * *AIS_InteractiveContext::InitSelected* initiates the list of objects; 
1121   * *AIS_InteractiveContext::MoreSelected* extends the list of objects; 
1122   * *AIS_InteractiveContext::NextSelected* resumes a scan;
1123   * *AIS_InteractiveContext::SelectedShape* gets the name of the selected object; 
1124   * *AIS_InteractiveContext::HasSelectedShape* checks if the selected shape is obtained; 
1125   * *AIS_InteractiveContext::Interactive* gets the picked interactive object; 
1126   * *AIS_InteractiveContext::HasApplicative* checks if the applicative object has an owner from  Interactive attributed to it; 
1127   * *AIS_InteractiveContext::Applicative* gets the owner of the detected applicative entity; 
1128   * *AIS_InteractiveContext::IsSelected* gets the name of the selected object. 
1129
1130
1131 <h4>Example </h4>
1132 ~~~~~
1133 myAISCtx->InitSelected();  
1134 while (myAISCtx->MoreSelected())  
1135         { 
1136         if  (myAISCtx->HasSelectedShape) 
1137                 { 
1138                 TopoDS_Shape  ashape = myAISCtx->SelectedShape(); 
1139                         // to be able  to use the picked shape 
1140                                     }  
1141                 else  
1142                 { 
1143                 Handle_AIS_InteractiveObject  anyobj = myAISCtx->Interactive(); 
1144                 // to be able to use the picked interactive object  
1145                 }  
1146 myAISCtx->NextSelected();  
1147 }     
1148 ~~~~~
1149
1150 You have to ask whether you have selected a shape  or an interactive object before you can recover the entity in the Local Context or in the iteration loop. If you have  selected a Shape from *TopoDS* on decomposition in standard mode, the *Interactive()* function returns the interactive object, which provided the selected  shape. Other functions allow you to manipulate the content of Selected or  Current Objects:  
1151   * *AIS_InteractiveContext::EraseSelected* erases the selected objects; 
1152   * *AIS_InteractiveContext::DisplaySelected* displays them; 
1153   * *AIS_InteractiveContext::SetSelected* puts the objects in the list of  selections;
1154   * *AIS_InteractiveContext::SetSelectedCurrent* takes the list of selected objects from a local context and puts it  into the list of current objects in Neutral Point;
1155   * *AIS_InteractiveContext::AddOrRemoveSelected* adds or removes an object from the list of selected entities; 
1156   * *AIS_InteractiveContext::HilightSelected* highlights the selected object;
1157   * *AIS_InteractiveContext::UnhilightSelected* removes highlighting from the selected object; 
1158   * *AIS_InteractiveContext::ClearSelected* empties the list of selected objects. 
1159
1160
1161 You can highlight and remove highlighting from a current  object, and empty the list of current objects using the following functions:  
1162 ~~~~~
1163   AIS_InteractiveContext::HilightCurrents  
1164   AIS_InteractiveContext::UnhilightCurrents  
1165   AIS_InteractiveContext::ClearCurrents  
1166 ~~~~~
1167 When you are in an open Local Context, you may need to keep  "temporary" interactive objects. This is possible using the following functions: 
1168   * *AIS_InteractiveContext::KeepTemporary* transfers the characteristics of the  interactive object seen in its local context (visualization mode, etc.) to the  neutral point. When the local context is closed, the object does not disappear.  
1169   * *AIS_InteractiveContext::SetSelectedCurrent* allows the selected object to become the current object when you  close the local context.  
1170
1171 You can also want to use function *AIS_InteractiveContext::ClearLocalContext* to modify in a general way the state of the local context before continuing a selection (emptying objects, removing  filters, standard activation modes). 
1172
1173 @subsubsection occt_visu_3_4_7 Recommendations 
1174
1175 The possibilities of use for local contexts are numerous  depending on the type of operation that you want to perform:  
1176   * working on all visualized interactive objects, 
1177   * working on only a few objects, 
1178   * working on a single object. 
1179
1180 When you want to work on one type of entity, you should  open a local context with the option *UseDisplayedObjects* set to FALSE. Some  functions which allow you to recover the visualized interactive objects, which  have a given Type, and Signature from the "Neutral Point" are:  
1181
1182 ~~~~~
1183 AIS_InteractiveContext::DisplayedObjects (AIS_ListOfInteractive&  aListOfIO) const;  
1184 AIS_InteractiveContext::DisplayedObjects (const AIS_KindOfInteractive  WhichKind, const Standard_Integer  WhichSignature;
1185 AIS_ListOfInteractive&  aListOfIO) const;  
1186 ~~~~~
1187
1188 At this stage, you only have to load the functions *Load, Activate,* and so on.  
1189
1190 When you open a Local Context with default options, you  must keep the following points in mind:  
1191 * The Interactive  Objects visualized at Neutral Point are activated with their default selection  mode. You must deactivate those, which you do not want to use.  
1192 * The Shape Type  Interactive Objects are automatically decomposed into sub-shapes when standard  activation modes are launched.  
1193 * The "temporary"  Interactive Objects present in the Local Contexts are not automatically taken  into account. You have to load them manually if you want to use them.  
1194
1195 The stages could be the following:
1196   1. Open  a Local Context with the right options;  
1197   2. Load/Visualize  the required complementary objects with the desired activation modes.  
1198   3. Activate  Standard modes if necessary  
1199   4. Create  its filters and add them to the Local Context  
1200   5. Detect/Select/recover  the desired entities  
1201   6. Close  the Local Context with the adequate index.  
1202
1203 It is useful to create an **interactive editor**, to which you  pass the Interactive Context. This allow setting up different  contexts of selection/presentation according to the operation, which you want  to perform. 
1204  
1205 Let us assume that you have visualized several types of interactive objects: *AIS_Points*,  *AIS_Axes*, *AIS_Trihedrons*, and *AIS_Shapes*.  
1206
1207 For your applicative function, you need an axis to create a  revolved object. You could obtain this axis by identifying:  
1208   * an axis which is already visualized,
1209   * 2 points,
1210   * a rectilinear edge on the shapes which are present,
1211   * a cylindrical face on the shapes (You will take the axis of this  face) 
1212
1213 ~~~~~
1214 myIHMEditor::myIHMEditor  
1215         (const  Handle(AIS_InteractiveContext)& Ctx, 
1216          ....) : 
1217          myCtx(Ctx),  
1218         ...  
1219
1220
1221
1222 myIHMEditor::PrepareContext() 
1223
1224 myIndex =myCtx->OpenLocalContext();  
1225
1226 //the filters  
1227
1228 Handle(AIS_SignatureFilter) F1 = new  AIS_SignatureFilter(AIS_KOI_Datum,AIS_SD_Point);   
1229 //filter on the points  
1230
1231 Handle(AIS_SignatureFilter) F2 = new AIS_SignatureFilter(AIS_KOI_Datum,AIS_SD_Axis);   
1232 //filters on the axes.  
1233
1234 Handle(StdSelect_FaceFilter) F3 = new StdSelect_FaceFilter(AIS_Cylinder);   
1235 //cylindrical face filters  
1236 //... 
1237 // activation of standard modes  on the shapes..  
1238 myCtx->ActivateStandardMode(TopAbs_FACE); 
1239 myCtx->ActivateStandardMode(TopAbs_VERTEX); 
1240 myCTX->Add(F1); 
1241 myCTX->Add(F2); 
1242 myCTX->Add(F3);  
1243
1244 // at  this point, you can call the selection/detection function  
1245
1246
1247 void myIHMEditor::MoveTo(xpix,ypix,Vue) 
1248
1249 {  myCTX->MoveTo(xpix,ypix,vue);  
1250 // the highlight of what is  detected is automatic.  
1251 }      
1252 Standard_Boolean myIHMEditor::Select()  
1253 {
1254 // returns true if you should  continue the selection      
1255                 myCTX->Select();   
1256                 myCTX->InitSelected();  
1257                 if(myCTX->MoreSelected()) 
1258                  {
1259                  if(myCTX->HasSelectedShape())     
1260                 { const  TopoDS_Shape& sh = myCTX->SelectedShape(); 
1261                 if(  vertex){  
1262                         if(myFirstV...)   
1263                         {  
1264                         //if it is the  first vertex, you stock it, then you deactivate the faces and only keep the  filter on the points: 
1265                         mypoint1 =  ....; 
1266                         myCtx->RemoveFilters(); 
1267                         myCTX->DeactivateStandardMode(TopAbs_FACE);   
1268                         myCtx->Add(F1);   
1269                         // the filter  on the AIS_Points  
1270                         myFirstV = Standard_False;  
1271                         return Standard_True;  
1272                          }
1273                         else
1274                          { 
1275                         mypoint2 =...;  
1276                         //  construction of the axis return Standard_False;  
1277                         } 
1278                  } 
1279                  else  
1280                   {  
1281                 //it is a  cylindrical face : you recover the axis; visualize it; and stock it.  
1282                 return  Standard_False;  
1283                 }  
1284                   }  
1285                 // it is not  a shape but is no doubt a point.  
1286                 else  
1287                 {  
1288                 Handle(AIS_InteractiveObject)   
1289                 SelObj =  myCTX->SelectedInteractive(); 
1290                 if(SelObj->Type()==AIS_KOI_Datum)   
1291                 { 
1292                         if(SelObj->Signature()==1)   
1293                         { 
1294                                 if  (firstPoint) 
1295                                 { 
1296                                 mypoint1  =...  
1297                                 return  Standard_True;  
1298                                 } 
1299                                 else 
1300                                 {  
1301                                 mypoint2 =  ...;  
1302                                 //construction  of the axis, visualization, stocking  
1303                                 return  Standard_False;  
1304                 } 
1305                 } 
1306
1307                 else  
1308                 {  
1309                 // you have  selected an axis; stock the axis  
1310                 return  Standard_False; 
1311                 } 
1312                 } 
1313                 } 
1314                 } 
1315                 }  
1316 void myIHMEditor::Terminate()
1317 {
1318 myCtx->CloseLocalContext(myIndex); 
1319 ...
1320 }
1321 ~~~~~
1322
1323 @subsection occt_visu_3_5 Standard Interactive Object Classes 
1324
1325 Interactive Objects are selectable and viewable objects connecting graphic representation and the underlying reference geometry.
1326
1327 They are divided into four types:
1328   * the **Datum** -- a construction geometric element;
1329   * the **Relation** -- a constraint on the interactive shape and the corresponding reference geometry;
1330   * the **Object** -- a topological shape or connection between shapes;
1331   * **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.
1332
1333 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*).
1334 If you want to give a particular type and signature to your interactive object, you must redefine the two virtual methods: <i>Type</i> and <i>Signature</i>.
1335
1336 @subsubsection occt_visu_3_5_1 Datum
1337
1338 The **Datum** groups together the construction elements such as lines, circles, points, trihedrons, plane trihedrons, planes and axes.
1339   
1340 *AIS_Point,  AIS_Axis,  AIS_Line,  AIS_Circle,  AIS_Plane* and *AIS_Trihedron* have four selection modes: 
1341   * mode 0 : selection of a trihedron; 
1342   * mode 1 : selection of the origin of the trihedron; 
1343   * mode 2 : selection of the axes; 
1344   * mode 3 : selection of the planes XOY, YOZ, XOZ. 
1345
1346 when you activate one of modes: 1 2 3 4, you pick AIS  objects of type:  
1347   * *AIS_Point* 
1348   * *AIS_Axis* (and information on the type of axis) 
1349   * *AIS_Plane* (and information on the type of plane). 
1350
1351 *AIS_PlaneTrihedron* offers three selection modes:  
1352   * mode 0 : selection of the whole trihedron; 
1353   * mode 1 : selection of the origin of the trihedron; 
1354   * mode 2 : selection of the axes -- same remarks as for the Trihedron.
1355
1356 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.  
1357
1358 @subsubsection occt_visu_3_5_2 Object
1359
1360 The **Object** type includes topological shapes, and connections between shapes.
1361
1362 *AIS_Shape* has three visualization modes :
1363   * mode 0 : Line (default mode) 
1364   * mode 1 : Shading (depending on the type of shape) 
1365   * mode 2 : Bounding Box 
1366
1367 And at maximum seven selection modes, depending on the shape complexity:
1368   * mode 0 : selection of the *AIS_Shape*; 
1369   * mode 1 : selection of the vertices; 
1370   * mode 2 : selection of the edges; 
1371   * mode 3 : selection of the wires; 
1372   * mode 4 : selection of the faces; 
1373   * mode 5 : selection of the shells; 
1374   * mode 6 : selection of the constituent solids. 
1375
1376   * *AIS_Triangulation* is a simple interactive object for displaying  triangular mesh contained in *Poly_Triangulation* container. 
1377   * *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.  
1378   * *AIS_MultipleConnectedInteractive* is an object connected to a list  of interactive objects (which can also be Connected objects. It does not  require memory hungry calculations of presentation) 
1379   * *AIS_TexturedShape* is an Interactive Object that supports texture  mapping. It is constructed as a usual AIS_Shape, but has additional methods  that allow to map a texture on it. 
1380   * *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. 
1381
1382
1383 The class *AIS_ColoredShape* allows using custom colors and line widths for *TopoDS_Shape* objects and their sub-shapes.
1384
1385 ~~~~~
1386   AIS_ColoredShape aColoredShape = new AIS_ColoredShape (theShape);
1387
1388   // setup color of entire shape
1389   aColoredShape->SetColor (Quantity_Color (Quantity_NOC_RED));
1390
1391   // setup line width of entire shape
1392   aColoredShape->SetWidth (1.0);
1393
1394   // set transparency value
1395   aColoredShape->SetTransparency (0.5);
1396
1397   // customize color of specified sub-shape
1398   aColoredShape->SetCustomColor (theSubShape, Quantity_Color (Quantity_NOC_BLUE1));
1399
1400   // customize line width of specified sub-shape
1401   aColoredShape->SetCustomWidth (theSubShape, 0.25);
1402 ~~~~~
1403
1404 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.
1405 - The type of point marker used to draw points can be specified as a presentation aspect.
1406 - The presentation provides selection by a bounding box of the visualized set of points. It supports two display / highlighting modes: points or bounding box.
1407
1408 @figure{point_cloud.png,"A random colored cloud of points",240}
1409
1410 Example:
1411 ~~~~~
1412 Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (2000, Standard_True);
1413 aPoints->AddVertex (gp_Pnt(-40.0, -40.0, -40.0), Quantity_Color (Quantity_NOC_BLUE1));
1414 aPoints->AddVertex (gp_Pnt (40.0,  40.0,  40.0), Quantity_Color (Quantity_NOC_BLUE2));
1415
1416 Handle(AIS_PointCloud) aPntCloud = new AIS_PointCloud();
1417 aPntCloud->SetPoints (aPoints);
1418 ~~~~~
1419
1420 The draw command *vpointcloud* builds a cloud of points from shape triangulation.
1421 This command can also draw a sphere surface or a volume with a large amount of points (more than one million).
1422
1423
1424 @subsubsection occt_visu_3_5_3 Relations 
1425
1426 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.
1427
1428 The following relations are provided by *AIS*:
1429   * *AIS_ConcentricRelation* 
1430   * *AIS_FixRelation*
1431   * *AIS_IdenticRelation* 
1432   * *AIS_ParallelRelation*
1433   * *AIS_PerpendicularRelation*
1434   * *AIS_Relation*
1435   * *AIS_SymmetricRelation*
1436   * *AIS_TangentRelation*
1437
1438 The list of relations is not exhaustive.    
1439
1440 @subsubsection occt_visu_3_5_4 Dimensions
1441   * *AIS_AngleDimension* 
1442   * *AIS_Chamf3dDimension* 
1443   * *AIS_DiameterDimension* 
1444   * *AIS_DimensionOwner*
1445   * *AIS_LengthDimension*
1446   * *AIS_OffsetDimension*
1447   * *AIS_RadiusDimension*
1448
1449   @subsubsection occt_visu_3_5_5 MeshVS_Mesh
1450
1451 *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.  
1452
1453 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.  
1454
1455 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. 
1456
1457 You can add/remove builders using the following methods: 
1458 ~~~~~
1459   MeshVS_Mesh::AddBuilder (const Handle (MeshVS_PrsBuilder) &Builder, Standard_Boolean TreatAsHilighter) 
1460   MeshVS_Mesh::RemoveBuilder (const Standard_Integer  Index) 
1461   MeshVS_Mesh::RemoveBuilderById (const Standard_Integer Id) 
1462 ~~~~~
1463
1464 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: 
1465 ~~~~~
1466   MeshVS_DMF_WireFrame
1467   MeshVS_DMF_Shading
1468   MeshVS_DMF_Shrink
1469 ~~~~~  
1470
1471 It is also possible to display  deformed mesh in wireframe, shading or shrink modes usung :  
1472 ~~~~~
1473         MeshVS_DMF_DeformedPrsWireFrame
1474         MeshVS_DMF_DeformedPrsShading  
1475         MeshVS_DMF_DeformedPrsShrink
1476 ~~~~~  
1477
1478 The following methods represent  different kinds of data :
1479 ~~~~~
1480   MeshVS_DMF_VectorDataPrs  
1481   MeshVS_DMF_NodalColorDataPrs
1482   MeshVS_DMF_ElementalColorDataPrs
1483   MeshVS_DMF_TextDataPrs
1484   MeshVS_DMF_EntitiesWithData
1485 ~~~~~  
1486
1487 The following methods provide selection  and highlighting :
1488 ~~~~~
1489   MeshVS_DMF_SelectionPrs
1490   MeshVS_DMF_HilightPrs
1491 ~~~~~  
1492
1493 *MeshVS_DMF_User* is a user-defined  mode.  
1494
1495 These values will be used by the  presentation builder. 
1496 There is also a set of selection modes flags that can be grouped in a combination of bits: 
1497   * *MeshVS_SMF_0D*
1498   * *MeshVS_SMF_Link*
1499   * *MeshVS_SMF_Face*
1500   * *MeshVS_SMF_Volume*
1501   * *MeshVS_SMF_Element* -- groups *0D, Link, Face* and *Volume*  as a bit mask ;
1502   * *MeshVS_SMF_Node*
1503   * *MeshVS_SMF_All* -- groups *Element* and *Node* as a bit mask; 
1504   * *MeshVS_SMF_Mesh*
1505   * *MeshVS_SMF_Group*
1506
1507 Such an object, for example, can be used for displaying the object and stored in the STL file format: 
1508
1509 ~~~~~
1510 // read the data and create a data source
1511 Handle(Poly_Triangulation) aSTLMesh = RWStl::ReadFile (aFileName);
1512 Handle(XSDRAWSTLVRML_DataSource) aDataSource = new XSDRAWSTLVRML_DataSource (aSTLMesh);
1513
1514 // create mesh 
1515 Handle  (MeshVS_Mesh) aMesh = new MeshVS(); 
1516 aMesh->SetDataSource  (aDataSource); 
1517
1518 // use default presentation builder
1519 Handle  (MeshVS_MeshPrsBuilder) aBuilder =  new  MeshVS_MeshPrsBuilder (aMesh); 
1520 aMesh->AddBuilder  (aBuilder, Standard_True); 
1521 ~~~~~
1522
1523 *MeshVS_NodalColorPrsBuilder* allows representing a mesh  with a color scaled texture mapped on it. 
1524 To do this you should define a color  map for the color scale, pass this map to the presentation builder, 
1525 and define an appropriate value in the range of 0.0 - 1.0 for every node. 
1526
1527 The following example demonstrates how you can do this (check if the view has been set up to display textures): 
1528
1529 ~~~~~
1530 // assign nodal builder to the mesh
1531 Handle  (MeshVS_NodalColorPrsBuilder) aBuilder = new MeshVS_NodalColorPrsBuilder 
1532         (aMesh,MeshVS_DMF_NodalColorDataPrs | MeshVS_DMF_OCCMask); 
1533 aBuilder->UseTexture  (Standard_True); 
1534
1535 // prepare color map
1536 Aspect_SequenceOfColor  aColorMap; 
1537 aColorMap.Append  ((Quantity_NameOfColor) Quantity_NOC_RED); 
1538 aColorMap.Append  ((Quantity_NameOfColor) Quantity_NOC_BLUE1); 
1539
1540 // assign color scale map  values (0..1) to nodes
1541 TColStd_DataMapOfIntegerReal  aScaleMap; 
1542 ...
1543 // iterate through the  nodes and add an node id and an appropriate value to the map
1544 aScaleMap.Bind  (anId, aValue); 
1545   
1546 // pass color map and color scale values to the builder
1547 aBuilder->SetColorMap  (aColorMap); 
1548 aBuilder->SetInvalidColor  (Quantity_NOC_BLACK); 
1549 aBuilder->SetTextureCoords  (aScaleMap); 
1550 aMesh->AddBuilder  (aBuilder, Standard_True); 
1551 ~~~~~
1552
1553 @subsection occt_visu_3_6 Dynamic Selection 
1554
1555 The dynamic selection represents the topological shape, which you want to select, by decomposition of <i>sensitive primitives</i> -- 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. 
1556
1557 For more details on the algorithm and examples of usage, please, refer to @ref occt_visu_2_2 "Selection" chapter.
1558
1559 @section occt_visu_4 3D Presentations
1560
1561 @subsection occt_visu_4_1 Glossary of 3D terms 
1562
1563 * **Anti-aliasing**     This mode attempts to improve the screen resolution by drawing lines and curves in a mixture of colors so that to the human eye the line or curve is smooth. The quality of the result is linked to the quality of the algorithm used by the workstation hardware.
1564 * **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.
1565 * **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.
1566 * **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.
1567 * **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. 
1568 * **View**      -- is defined by a view orientation, a view mapping, and a context view.
1569 * **Viewer** -- manages a set of views.
1570 * **View orientation** -- defines the manner in which the observer looks at the scene in terms of View Reference Coordinates.
1571 * **View mapping** -- defines the transformation from View Reference Coordinates to the Normalized Projection Coordinates. This follows the Phigs scheme.
1572 * **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.
1573
1574 @subsection occt_visu_4_2 Graphic primitives
1575
1576 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.
1577
1578 Graphic structures can be:  
1579   * Displayed, 
1580   * Highlighted, 
1581   * Erased, 
1582   * Transformed, 
1583   * Connected to form a tree hierarchy of structures, created by transformations.
1584   
1585 There are classes for: 
1586   * Visual attributes for lines, faces, markers, text, materials, 
1587   * Vectors and vertices, 
1588   * Graphic objects, groups, and structures. 
1589
1590 @subsubsection occt_visu_4_2_2 Structure hierarchies
1591
1592 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.
1593
1594 @subsubsection occt_visu_4_2_3 Graphic primitives
1595 * **Markers** 
1596   * Have one or more vertices, 
1597   * Have a type, a scale factor, and a color, 
1598   * Have a size, shape, and orientation independent of  transformations. 
1599 * **Polygons** 
1600   * Have one closed boundary, 
1601   * Have at least three vertices, 
1602   * Are planar and have a normal, 
1603   * Have interior attributes -- style, color, front and back material,  texture and reflection ratio, 
1604   * Have a boundary with the following attributes -- type, width scale  factor, color. The boundary is only drawn when the interior style is hollow. 
1605
1606 * **Polygons with holes** 
1607   * Have multiple closed boundaries, each one with at least three  vertices, 
1608   * Are planar and have a normal, 
1609   * Have interior attributes -- style, color, front and back material,  
1610   * Have a boundary with the following attributes -- type, width scale  factor, color. The boundary is only drawn when the interior style is hollow. 
1611
1612 * **Polylines** 
1613   * Have two or more vertices, 
1614   * Have the following attributes -- type, width scale factor, color. 
1615
1616 * **Text** 
1617   * Has geometric and non-geometric attributes, 
1618   * Geometric attributes -- character height, character up vector,  text path, horizontal and vertical alignment, orientation, three-dimensional  position, zoomable flag
1619   * Non-geometric attributes -- text font, character spacing,  character expansion factor, color. 
1620
1621 @subsubsection occt_visu_4_2_4 Primitive  arrays
1622
1623 Primitive arrays are a more efficient approach to describe  and display the primitives from the aspects of memory usage and graphical  performance. The key feature of the primitive arrays is that the primitive data  is not duplicated. For example, two polygons could share the same vertices, so  it is more efficient to keep the vertices in a single array and specify the  polygon vertices with indices of this array. In addition to such kind of memory  savings, the OpenGl graphics driver provides the Vertex Buffer Objects (VBO).  VBO is a sort of video memory storage that can be allocated to hold the  primitive arrays, thus making the display operations more efficient and  releasing the RAM memory. 
1624
1625 The Vertex Buffer Objects are enabled by default, but VBOs  availability depends on the implementation of OpenGl. If the VBOs are  unavailable or there is not enough video memory to store the primitive arrays,  the RAM memory will be used to store the arrays.  
1626
1627 The Vertex Buffer Objects can be disabled at the application  level. You can use the method *Graphic3d_GraphicDriver::EnableVBO (const Standard_Boolean status)* to enable/disable VBOs: 
1628   
1629 The following example shows how to disable the VBO support:  
1630
1631 ~~~~~
1632 // get the graphic  driver
1633 Handle (Graphic3d_GraphicDriver) aDriver =  
1634   myAISContext->CurrentViewer()->Driver(); 
1635
1636 // disable VBO support
1637 aDriver->EnableVBO (Standard_False); 
1638 ~~~~~
1639
1640 **Note** that the use of Vertex Buffer Objects  requires the application level primitive data provided by the  *Graphic3d_ArrayOfPrimitives* to be transferred to the video memory. *TKOpenGl* transfers the data and releases the *Graphic3d_ArrayOfPrimitives* internal  pointers to the primitive data. Thus it might be necessary to pay attention to  such kind of behaviour, as the pointers could be modified (nullified) by the *TKOpenGl*. 
1641
1642 The different types of primitives could be presented with  the following primitive arrays: 
1643   * *Graphic3d_ArrayOfPoints,*
1644   * *Graphic3d_ArrayOfPolygons,*
1645   * *Graphic3d_ArrayOfPolylines,*
1646   * *Graphic3d_ArrayOfQuadrangles,*
1647   * *Graphic3d_ArrayOfQuadrangleStrips,*
1648   * *Graphic3d_ArrayOfSegments,*
1649   * *Graphic3d_ArrayOfTriangleFans,*
1650   * *Graphic3d_ArrayOfTriangles,*
1651   * *Graphic3d_ArrayOfTriangleStrips.*
1652
1653 The *Graphic3d_ArrayOfPrimitives* is a base class for these  primitive arrays. 
1654
1655 Method *Graphic3d_ArrayOfPrimitives::AddVertex* allows adding There is a set of similar methods to add vertices to the  primitive array.
1656
1657 These methods take vertex coordinates as an argument and  allow you to define the color, the normal and the texture coordinates assigned  to the vertex. The return value is the actual number of vertices in the array. 
1658
1659 You can also modify the values assigned to the vertex or  query these values by the vertex index: 
1660   * *void Graphic3d_ArrayOfPrimitives::SetVertice*
1661   * *void  Graphic3d_ArrayOfPrimitives::SetVertexColor*
1662   * *void  Graphic3d_ArrayOfPrimitives::SetVertexNormal*
1663   * *void  Graphic3d_ArrayOfPrimitives::SetVertexTexel*
1664   * *gp_Pnt  Graphic3d_ArrayOfPrimitives::Vertices*
1665   * *gp_Dir   Graphic3d_ArrayOfPrimitives::VertexNormal*
1666   * *gp_Pnt3d  Graphic3d_ArrayOfPrimitives::VertexTexel*
1667   * *Quantity_Color  Graphic3d_ArrayOfPrimitives::VertexColor*
1668   * *void  Graphic3d_ArrayOfPrimitives::Vertices*
1669   * *void  Graphic3d_ArrayOfPrimitives::VertexNormal*
1670   * *void  Graphic3d_ArrayOfPrimitives::VertexTexel*
1671   * *void  Graphic3d_ArrayOfPrimitives::VertexColor*
1672
1673 The following example shows how to define an array of  points: 
1674
1675 ~~~~~
1676 // create an array
1677 Handle (Graphic3d_ArrayOfPoints) anArray = new Graphic3d_ArrayOfPoints (aVerticiesMaxCount); 
1678
1679 // add vertices to the array
1680 anArray->AddVertex  (10.0, 10.0, 10.0); 
1681 anArray->AddVertex  (0.0, 10.0, 10.0); 
1682
1683 // add the array to the structure
1684 Handle (Graphic3d_Group) aGroup  =  Prs3d_Root::CurrentGroup (aPrs); 
1685 aGroup->BeginPrimitives (); 
1686 aGroup->AddPrimitiveArray (anArray); 
1687 aGroup->EndPrimitives (); 
1688 ~~~~~
1689
1690 If the primitives share the same vertices (polygons,  triangles, etc.) then you can define them as indices of the vertices array. 
1691
1692 The method *Graphic3d_ArrayOfPrimitives::AddEdge* allows defining the primitives by indices. This method adds an "edge" in the range <i> [1, VertexNumber() ] </i>  in the array. 
1693
1694 It is also possible to query the vertex defined by an edge using method *Graphic3d_ArrayOfPrimitives::Edge*
1695
1696 The following example shows how to define an array of  triangles: 
1697
1698 ~~~~~
1699 // create an array
1700 Standard_Boolean  IsNormals     = Standard_False;  
1701 Standard_Boolean  IsColors      = Standard_False; 
1702 Standard_Boolean  IsTextureCrds = Standard_False; 
1703 Handle (Graphic3d_ArrayOfTriangles) anArray =  
1704           new Graphic3d_ArrayOfTriangles (aVerticesMaxCount, 
1705                                           aEdgesMaxCount, 
1706                                           IsNormals, 
1707                                           IsColors, 
1708                                           IsTextureCrds); 
1709 // add vertices to the array
1710 anArray->AddVertex  (-1.0, 0.0, 0.0);   // vertex 1
1711 anArray->AddVertex  ( 1.0, 0.0, 0.0);   // vertex 2
1712 anArray->AddVertex  ( 0.0, 1.0, 0.0);   // vertex 3 
1713 anArray->AddVertex  ( 0.0,-1.0, 0.0);   // vertex 4 
1714
1715 // add edges to the array
1716 anArray->AddEdge  (1);  // first triangle
1717 anArray->AddEdge  (2); 
1718 anArray->AddEdge  (3); 
1719 anArray->AddEdge  (1);  // second triangle
1720 anArray->AddEdge  (2); 
1721 anArray->AddEdge  (4); 
1722
1723 // add the array to the structure
1724 Handle  (Graphic3d_Group) aGroup =  Prs3d_Root::CurrentGroup (aPrs); 
1725 aGroup->BeginPrimitives  (); 
1726 aGroup->AddPrimitiveArray  (anArray); 
1727 aGroup->EndPrimitives  (); 
1728 ~~~~~
1729
1730 If the primitive array presents primitives built from  sequential sets of vertices, for example polygons, then you can specify the  bounds, or the number of vertices for each primitive. You can use the method *Graphic3d_ArrayOfPrimitives::AddBound* to define the bounds and the color for each bound. This method returns the actual number of bounds. 
1731
1732 It is also possible to set the color and query the number of  edges in the bound and bound color. 
1733 ~~~~~
1734   Standard_Integer  Graphic3d_ArrayOfPrimitives::Bound
1735   Quantity_Color  Graphic3d_ArrayOfPrimitives::BoundColor
1736   void  Graphic3d_ArrayOfPrimitives::BoundColor
1737 ~~~~~
1738
1739 The following example shows how to define an array of  polygons: 
1740
1741 ~~~~~
1742 // create an array
1743 Standard_Boolean  IsNormals      = Standard_False;  
1744 Standard_Boolean  IsVertexColors = Standard_False; 
1745 Standard_Boolean  IsFaceColors   = Standard_False; 
1746 Standard_Boolean  IsTextureCrds  = Standard_False; 
1747 Handle (Graphic3d_ArrayOfPolygons) anArray =  
1748           new Graphic3d_ArrayOfPolygons (aVerticesMaxCount, 
1749                                          aBoundsMaxCount, 
1750                                          aEdgesMaxCount, 
1751                                          IsNormals, 
1752                                          IsVertexColors, 
1753                                          IsFaceColors, 
1754                                          IsTextureCrds); 
1755
1756 // add bounds to the array, first polygon
1757 anArray->AddBound (3);  
1758 anArray->AddVertex (-1.0,  0.0, 0.0);    
1759 anArray->AddVertex  ( 1.0, 0.0, 0.0);    
1760 anArray->AddVertex  ( 0.0, 1.0, 0.0);    
1761
1762 // add bounds to the array, second polygon
1763 anArray->AddBound (4); 
1764 anArray->AddVertex (-1.0,  0.0, 0.0);    
1765 anArray->AddVertex  ( 1.0, 0.0, 0.0);    
1766 anArray->AddVertex  ( 1.0,-1.0, 0.0);    
1767 anArray->AddVertex  (-1.0,-1.0, 0.0);    
1768
1769 // add the array to the structure 
1770 Handle  (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup  (aPrs); 
1771 aGroup->BeginPrimitives  (); 
1772 aGroup->AddPrimitiveArray  (anArray); 
1773 aGroup->EndPrimitives  (); 
1774 ~~~~~
1775
1776 There are also several helper methods. You can get the type  of the primitive array: 
1777 ~~~~~
1778   Graphic3d_TypeOfPrimitiveArray 
1779   Graphic3d_ArrayOfPrimitives::Type
1780   Standard_CString  Graphic3d_ArrayOfPrimitives::StringType
1781 ~~~~~
1782
1783 and check if the primitive array provides normals, vertex colors and vertex texels (texture coordinates): 
1784
1785 ~~~~~
1786   Standard_Boolean Graphic3d_ArrayOfPrimitives::HasVertexNormals
1787   Standard_Boolean Graphic3d_ArrayOfPrimitives::HasVertexColors
1788   Standard_Boolean Graphic3d_ArrayOfPrimitives::HasVertexTexels
1789 ~~~~~
1790 or get the number of vertices, edges and bounds: 
1791 ~~~~~
1792   Standard_Integer Graphic3d_ArrayOfPrimitives::VertexNumber
1793   Standard_Integer Graphic3d_ArrayOfPrimitives::EdgeNumber
1794   Standard_Integer Graphic3d_ArrayOfPrimitives::BoundNumber
1795 ~~~~~
1796   
1797 @subsubsection occt_visu_4_2_5 Text primitive
1798
1799 The OpenGl graphics driver uses advanced text rendering  powered by FTGL library. This library provides vector text rendering, as a  result the text can be rotated and zoomed without quality loss.  
1800 *Graphic3d* text primitives have the following features: 
1801   * fixed size (non-zoomable) or zoomable, 
1802   * can be rotated to any angle in the view plane,
1803   * support unicode charset.
1804
1805 The text attributes for the group could be defined with the *Graphic3d_AspectText3d* attributes group. 
1806 To add any text to the graphic structure you can use the  following methods: 
1807 ~~~~~
1808  void Graphic3d_Group::Text
1809                         (const Standard_CString AText, 
1810                          const Graphic3d_Vertex& APoint, 
1811                          const Standard_Real AHeight, 
1812                          const Quantity_PlaneAngle AAngle, 
1813                          const Graphic3d_TextPath ATp, 
1814                          const Graphic3d_HorizontalTextAlignment  AHta, 
1815                          const Graphic3d_VerticalTextAlignment  AVta, 
1816                          const Standard_Boolean EvalMinMax), 
1817 ~~~~~                   
1818 *AText*  parameter is the text string, *APoint* is the three-dimensional position of the  text, *AHeight* is the text height, *AAngle* is the orientation of the text (at the  moment, this parameter has no effect, but you can specify the text orientation through  the *Graphic3d_AspectText3d* attributes). 
1819
1820 *ATp* parameter defines the text path, *AHta* is the horizontal alignment of the text,  *AVta* is the vertical alignment of the text. 
1821
1822 You can  pass *Standard_False* as *EvalMinMax* if you do not want the graphic3d structure  boundaries to be affected by the text position.  
1823
1824 **Note** that the text orientation angle can be defined by *Graphic3d_AspectText3d* attributes. 
1825 ~~~~~
1826   void  Graphic3d_Group::Text
1827                         (const Standard_CString AText, 
1828                          const Graphic3d_Vertex& APoint, 
1829                          const Standard_Real AHeight, 
1830                          const Standard_Boolean EvalMinMax) 
1831   void  Graphic3d_Group::Text
1832                         (const TCcollection_ExtendedString  &AText,  
1833                          const Graphic3d_Vertex& APoint, 
1834                          const Standard_Real AHeight, 
1835                          const Quantity_PlaneAngle AAngle, 
1836                          const Graphic3d_TextPath ATp, 
1837                          const Graphic3d_HorizontalTextAlignment  AHta, 
1838                          const Graphic3d_VerticalTextAlignment  AVta, 
1839                          const Standard_Boolean EvalMinMax) 
1840   void  Graphic3d_Group::Text
1841                         (const TCcollection_ExtendedString  &AText,  
1842                          const Graphic3d_Vertex& APoint, 
1843                          const Standard_Real AHeight, 
1844                          const Standard_Boolean EvalMinMax) 
1845 ~~~~~
1846
1847 See the example:
1848 ~~~~~
1849 // get the group
1850 Handle (Graphic3d_Group) aGroup =  Prs3d_Root::CurrentGroup  (aPrs);  
1851
1852 // change the text  aspect
1853 Handle(Graphic3d_AspectText3d) aTextAspect =  new Graphic3d_AspectText3d (); 
1854 aTextAspect->SetTextZoomable  (Standard_True); 
1855 aTextAspect->SetTextAngle  (45.0); 
1856 aGroup->SetPrimitivesAspect (aTextAspect);   
1857
1858 // add a text primitive  to the structure
1859 Graphic3d_Vertex aPoint (1, 1, 1); 
1860 aGroup->Text (Standard_CString ("Text"), aPoint, 16.0); 
1861 ~~~~~
1862
1863 @subsubsection occt_visu_4_2_6 Materials
1864
1865 A *Graphic3d_MaterialAspect* is defined by:
1866   * Transparency;
1867   * Diffuse reflection -- a component of the object color;
1868   * Ambient reflection;
1869   * Specular reflection -- a component of the color of the light source;
1870   * Refraction index.
1871
1872 The following items are required to determine the three colors of reflection:
1873   * Color;
1874   * Coefficient of diffuse reflection;
1875   * Coefficient of ambient reflection;
1876   * Coefficient of specular reflection.
1877
1878 @subsubsection occt_visu_4_2_7 Textures
1879
1880 A *texture* is defined by a name.
1881 Three types of texture are available:
1882   * 1D;
1883   * 2D;
1884   * Environment mapping.
1885
1886 @subsubsection occt_visu_4_2_8 Shaders
1887
1888 OCCT visualization core supports GLSL shaders. Currently OCCT supports only vertex and fragment GLSL shader. Shaders can be assigned to a generic presentation by its drawer attributes (Graphic3d aspects). To enable custom shader for a specific AISShape in your application, the following API functions are used:
1889
1890 ~~~~~
1891 // Create shader program
1892 Handle(Graphic3d_ShaderProgram) aProgram = new Graphic3d_ShaderProgram();
1893
1894 // Attach vertex shader
1895 aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile(
1896                                Graphic3d_TOS_VERTEX, "<Path to VS>"));
1897
1898 // Attach fragment shader
1899 aProgram->AttachShader (Graphic3d_ShaderObject::CreateFromFile(
1900                                Graphic3d_TOS_FRAGMENT, "<Path to FS>"));
1901
1902 // Set values for custom uniform variables (if they are)
1903 aProgram->PushVariable ("MyColor", Graphic3d_Vec3(0.0f, 1.0f, 0.0f));
1904
1905 // Set aspect property for specific AISShape
1906 theAISShape->Attributes()->ShadingAspect()->Aspect()->SetShaderProgram (aProgram);
1907 ~~~~~
1908
1909 @subsection occt_visu_4_3 Graphic attributes
1910
1911 @subsubsection occt_visu_4_3_1 Aspect package overview
1912
1913 The *Aspect* package provides classes for the graphic elements in the viewer:
1914   * Groups of graphic attributes;
1915   * Edges, lines, background;
1916   * Window;
1917   * Driver;
1918   * Enumerations for many of the above.
1919
1920 @subsection occt_visu_4_4 3D view facilities
1921
1922 @subsubsection occt_visu_4_4_1 Overview
1923
1924 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.  
1925
1926 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.  
1927
1928 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:  
1929   * Default parameters of the viewer, 
1930   * Views (orthographic, perspective), 
1931   * Lighting (positional, directional, ambient, spot, headlight), 
1932   * Clipping planes,
1933   * Instantiated sequences of views, planes, light sources, graphic  structures, and picks, 
1934   * Various package methods. 
1935
1936 @subsubsection occt_visu_4_4_2 A programming example
1937
1938 This sample TEST program for the *V3d* Package uses primary packages *Xw* and *Graphic3d* and secondary packages *Visual3d, Aspect, Quantity* and *math*.
1939
1940 ~~~~~
1941 // Create a default display connection
1942 Handle(Aspect_DisplayConnection) aDispConnection = new Aspect_DisplayConnection();
1943
1944 // Create a Graphic Driver from the default Aspect_DisplayConnection
1945 Handle(OpenGl_GraphicDriver) aGraphicDriver = new OpenGl_GraphicDriver (aDispConnection);
1946
1947 // Create a Viewer to this Driver
1948 Handle(V3d_Viewer) VM = new V3d_Viewer (aGraphicDriver);
1949 VM->SetDefaultBackgroundColor (Quantity_NOC_DARKVIOLET);
1950 VM->SetDefaultViewProj (V3d_Xpos);
1951 // Create a structure in this Viewer
1952 Handle(Graphic3d_Structure) aStruct = new Graphic3d_Structure (VM->Viewer());
1953
1954 // Type of structure
1955 aStruct->SetVisual (Graphic3d_TOS_SHADING);
1956
1957 // Create a group of primitives  in this structure
1958 Handle(Graphic3d_Group) aPrsGroup = new Graphic3d_Group (aStruct);
1959
1960 // Fill this group with one quad of size 100
1961 Handle(Graphic3d_ArrayOfTriangleStrips) aTriangles = new Graphic3d_ArrayOfTriangleStrips (4);
1962 aTriangles->AddVertex (-100./2., -100./2., 0.0);
1963 aTriangles->AddVertex (-100./2.,  100./2., 0.0);
1964 aTriangles->AddVertex ( 100./2., -100./2., 0.0);
1965 aTriangles->AddVertex ( 100./2.,  100./2., 0.0);
1966 aPrsGroup->Polygon (aTriangles);
1967
1968 //  Create Ambient and Infinite Lights in this Viewer
1969 Handle(V3d_AmbientLight) aLight1 = new V3d_AmbientLight (VM, Quantity_NOC_GRAY50);
1970 Handle(V3d_DirectionalLight) aLight2 = new V3d_DirectionalLight (VM, V3d_XnegYnegZneg, Quantity_NOC_WHITE);
1971
1972 // Create a 3D quality  Window with the same DisplayConnection
1973 Handle(Xw_Window) aWindow = new Xw_Window (aDispConnection, "Test V3d", 0.5, 0.5, 0.5, 0.5);
1974
1975 // Map this Window to this screen
1976 aWindow->Map();
1977
1978 // Create a Perspective  View in this Viewer
1979 Handle(V3d_View) aView = new V3d_View (VM);
1980 aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
1981 // Associate this View with the Window
1982 aView ->SetWindow (aWindow);
1983 // Display ALL structures in this View
1984 VM->Viewer()->Display();
1985 // Finally update the Visualization in this View
1986 aView->Update();
1987 ~~~~~
1988
1989 As an alternative to manual setting of perspective parameters the *V3d_View::ZfitAll()* and *V3d_View::FitAll()* functions can be used:
1990
1991 ~~~~~
1992 // Display shape in Viewer VM
1993 Handle(AIS_InteractiveContext) aContext = new AIS_InteractiveContext (VM);
1994 aContext->Display(shape);
1995 // Create a Perspective View in Viewer VM
1996 Handle(V3d_View) V = new V3d_View (VM);
1997 aview->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
1998 // Change Z-min and Z-max planes of projection volume to match the displayed objects
1999 V->ZFitAll();
2000 // Fit view to object size
2001 V->FitAll();
2002 ~~~~~
2003
2004 @subsubsection occt_visu_4_4_3 Define viewing parameters
2005
2006 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:
2007
2008 * **Eye** -- defines the observer (camera) position. Make sure the Eye point never gets between the Front and Back clipping planes.
2009
2010 * **Center** -- defines the origin of View Reference Coordinates (where camera is aimed at).
2011
2012 * **Direction** -- defines the direction of camera view (from the Eye to the Center).
2013
2014 * **Distance** -- defines the distance between the Eye and the Center.
2015
2016 * **Front** Plane -- defines the position of the front clipping plane in View Reference Coordinates system.
2017
2018 * **Back** Plane -- defines the position of the back clipping plane in View Reference Coordinates system.
2019
2020 * **ZNear** -- defines the distance between the Eye and the Front plane.
2021
2022 * **ZFar** -- defines the distance between the Eye and the Back plane.
2023
2024 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:
2025
2026 Example:
2027 ~~~~~
2028 // rotate camera by X axis on 30.0 degrees
2029 gp_Trsf aTrsf;
2030 aTrsf.SetRotation (gp_Ax1 (gp_Pnt (0.0, 0.0, 0.0), gp_Dir (1.0, 0.0, 0.0)), 30.0);
2031 aView->Camera()->Transform (aTrsf);
2032 ~~~~~
2033
2034 @subsubsection occt_visu_4_4_4 Orthographic Projection
2035
2036 @figure{view_frustum.png,"Perspective and orthographic projection",420}
2037
2038 The following code configures the camera for orthographic rendering:
2039
2040 ~~~~~
2041 // Create an orthographic View in this Viewer
2042 Handle(V3d_View) aView = new V3d_View (VM);
2043 aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Orthographic);
2044 // update the Visualization in this View
2045 aView->Update();
2046 ~~~~~
2047
2048 @subsubsection occt_visu_4_4_5 Perspective Projection
2049
2050 **Field of view (FOVy)** -- defines the field of camera view by y axis in degrees (45° is default).
2051
2052 @figure{camera_perspective.png,"Perspective frustum",420}
2053
2054 The following code configures the camera for perspective rendering:
2055
2056 ~~~~~
2057 // Create a perspective View in this Viewer
2058 Handle(V3d_View) aView = new V3d_View(VM);
2059 aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Perspective);
2060 aView->Update();
2061 ~~~~~
2062
2063
2064 @subsubsection occt_visu_4_4_6 Stereographic Projection
2065
2066 **IOD** -- defines the intraocular distance (in world space units).
2067
2068 There are two types of IOD:
2069 * _IODType_Absolute_ : Intraocular distance is defined as an absolute value.
2070 * _IODType_Relative_ : Intraocular distance is defined relative to the camera focal length (as its coefficient).
2071
2072 **Field of view (FOV)** -- defines the field of camera view by y axis in degrees (45° is default).
2073
2074 **ZFocus** -- defines the distance to the point of stereographic focus.
2075
2076 @figure{stereo.png,"Stereographic projection",420}
2077
2078 To enable stereo projection, your workstation should meet the following requirements:
2079
2080 * The graphic card should support quad buffering.
2081 * You need active 3D glasses (LCD shutter glasses).
2082 * 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.
2083
2084 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.
2085
2086 To enable quad buffering support you should provide the following settings to the graphic driver *opengl_caps*:
2087
2088 ~~~~~
2089 Handle(OpenGl_GraphicDriver) aDriver = new OpenGl_GraphicDriver();
2090 OpenGl_Caps& aCaps = aDriver->ChangeOptions();
2091 aCaps.contextStereo = Standard_True;
2092 ~~~~~
2093
2094 The following code configures the camera for stereographic rendering:
2095
2096 ~~~~~
2097 // Create a Stereographic View in this Viewer
2098 Handle(V3d_View) aView = new V3d_View(VM);
2099 aView->Camera()->SetProjectionType (Graphic3d_Camera::Projection_Stereo);
2100 // Change stereo parameters
2101 aView->Camera()->SetIOD (IODType_Absolute, 5.0);
2102 // Finally update the Visualization in this View
2103 aView->Update();
2104 ~~~~~
2105
2106 @subsubsection occt_visu_4_4_7 View frustum culling
2107
2108 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:
2109 * *Graphic3d_Structure::CalculateBoundBox()* is used to calculate axis-aligned bounding box of a presentation considering its transformation.
2110 * *V3d_View::SetFrustumCulling* enables or disables frustum culling for the specified view.
2111 * Classes *OpenGl_BVHClipPrimitiveSet* and *OpenGl_BVHTreeSelector* handle the detection of outer objects and usage of acceleration structure for frustum culling.
2112 * *BVH_BinnedBuilder* class splits several objects with null bounding box.
2113
2114 @subsubsection occt_visu_4_4_8 Underlay and overlay layers management
2115
2116 In addition to interactive 3d graphics displayed in the view  you can display underlying and overlying graphics: text, color scales and drawings.
2117
2118 All *V3d* view graphical objects in the overlay are  managed by the default layer manager (*V3d_LayerMgr*). The *V3d* view has a  basic layer manager capable of displaying the color scale, but you can redefine  this class to provide your own overlay and underlay graphics.  
2119
2120 The method *V3d_View::SetLayerMgr(const Handle (V3d_LayerMgr)& aMgr)* allows assigning a custom layer manager to the *V3d* view.
2121
2122 There are three virtual methods to prepare graphics in the  manager for further drawing: setting up layer dimensions and drawing static graphics. These methods can be redefined:
2123
2124 ~~~~~
2125    void  V3d_LayerMgr::Begin ()
2126    void  V3d_LayerMgr::Redraw ()
2127    void V3d_LayerMgr::End  ()
2128 ~~~~~
2129
2130 The layer manager controls layers (*Visual3d_Layer*)  and layer items (*Visual3d_LayerItem*). Both the overlay and  underlay layers can be created by the layer manager.  
2131
2132 The layer entity is presented by the *Visual3d_Layer* class. This entity provides drawing services in the layer, for example:
2133 ~~~~~ 
2134    void  Visual3d_Layer::DrawText
2135    void Visual3d_Layer::DrawRectangle
2136    void  Visual3d_Layer::SetColor
2137    void  Visual3d_Layer::SetViewport
2138 ~~~~~
2139
2140 The following example demonstrates how to draw overlay graphics by the *V3d_LayerMgr*:
2141
2142 ~~~~~
2143 // redefined method of  V3d_LayerMgr
2144 void  MyLayerMgr::Redraw () 
2145
2146    Quantity_Color aRed (Quantity_NOC_RED); 
2147    myOverlayLayer->SetColor (aRed); 
2148    myOverlayLayer->DrawRectangle (0, 0, 100, 100); 
2149
2150 ~~~~~
2151
2152 The layer contains layer items that will be displayed on  view redraw. Such items are *Visual3d_LayerItem* entities. To manipulate *Visual3d_LayerItem* entities assigned to the layer's internal list you can use the following methods: 
2153
2154 ~~~~~
2155    void  Visual3d_Layer::AddLayerItem (const Handle (Visual3d_LayerItem)&  Item)  
2156    void  Visual3d_Layer::RemoveLayerItem (const Handle (Visual3d_LayerItem)&  Item)   
2157    void  Visual3d_Layer::RemoveAllLayerItems ()
2158    const  Visual3d_NListOfLayerItem& Visual3d_Layer::GetLayerItemList ()    
2159 ~~~~~
2160 The layer's items are rendered when the method *void  Visual3d_Layer::RenderLayerItems()* is  called by the graphical driver.
2161
2162 The *Visual3d_LayerItem* has virtual methods that are  used to render the item: 
2163 ~~~~~
2164    void  Visual3d_LayerItem::RedrawLayerPrs () 
2165    void  Visual3d_LayerItem::ComputeLayerPrs () 
2166 ~~~~~
2167
2168 The item presentation can be computed before drawing by the *ComputeLayerPrs* method to save time on redraw. It also has an additional  flag that is used to tell that the presentation should be recomputed: 
2169 ~~~~~
2170    void  Visual3d_LayerItem::SetNeedToRecompute (const Standard_Boolean NeedToRecompute)  
2171    Standard_Boolean  Visual3d_LayerItem::IsNeedToRecompute 
2172 ~~~~~
2173
2174 An example of *Visual3d_LayerItem* is *V3d_ColorScaleLayerItem*  that represents the color scale entity as the layer's item.  
2175 The *V3d_ColorScaleLayerItem* sends render requests to  the color scale entity represented by it. As this entity (*V3d_ColorScale*)  is assigned to the *V3d_LayerMgr* it uses its overlay layer's services for  drawing: 
2176
2177 <h4>Example </h4>
2178
2179 ~~~~~
2180 // tell V3d_ColorScale to draw itself
2181 void  V3d_ColorScaleLayerItem::RedrawLayerPrs () 
2182
2183    Visual3d_LayerItem::RedrawLayerPrs () 
2184   if  (!MyColorScale.IsNull ()) 
2185     MyColorScale->DrawScale  (); 
2186
2187
2188 // V3d_ColorScale has a reference to a LayerMgr
2189 void  V3d_ColorScale::DrawScale () 
2190
2191     // calls V3d_ColorScale::PaintRect,  V3d_ColorScale::PaintText, etc. 
2192
2193
2194 // PaintRect method uses overlay layer of LayerMgr to  draw a rectangle 
2195 void V3d_ColorScale::PaintRect   
2196        (const  Standard_Integer X, const Standard_Integer Y, 
2197         const  Standard_Integer W, const Standard_Integer H, 
2198         const  Quantity_Color aColor, 
2199         const  Standard_Boolean aFilled) 
2200
2201   const Handle  (Visual3d_Layer)& theLayer = myLayerMgr->Overlay (); 
2202    ...
2203    theLayer->SetColor (aColor); 
2204    theLayer->DrawRectangle (X, Y, W, H); 
2205    ... 
2206
2207 ~~~~~
2208
2209 @subsubsection occt_visu_4_4_9 View background styles
2210 There are three types of  background styles available for *V3d_view*: solid color, gradient color and  image.  
2211
2212 To set solid color for  the background you can use the following methods: 
2213 ~~~~~
2214    void  V3d_View::SetBackgroundColor
2215                 (const Quantity_TypeOfColor Type,  
2216                  const Quantity_Parameter V1, 
2217                  const Quantity_Parameter V2, 
2218                  const Quantity_Parameter V3) 
2219 ~~~~~
2220
2221 This method allows you to specify the background color in RGB (red,  green, blue) or HLS (hue, lightness, saturation) color spaces, so the  appropriate values of the Type parameter are *Quantity_TOC_RGB* and  *Quantity_TOC_HLS*. 
2222
2223 **Note** that the color  value parameters *V1,V2,V3* should be in the range between *0.0-1.0.* 
2224
2225 ~~~~~
2226   void  V3d_View::SetBackgroundColor(const Quantity_Color &Color)  
2227   void  V3d_View::SetBackgroundColor(const Quantity_NameOfColor Name)  
2228 ~~~~~
2229
2230 The gradient background  style could be set up with the following methods: 
2231 ~~~~~
2232   void  V3d_View::SetBgGradientColors
2233                 (const Quantity_Color& Color1,  
2234                  const Quantity_Color& Color2, 
2235                  const Aspect_GradientFillMethod  FillStyle, 
2236                  const Standard_Boolean update) 
2237                 
2238    void  V3d_View::SetBgGradientColors
2239                 (const Quantity_NameOfColor Color1,  
2240                  const Quantity_NameOfColor Color2, 
2241                  const Aspect_GradientFillMethod  FillStyle, 
2242                  const Standard_Boolean update) 
2243 ~~~~~
2244
2245 The *Color1* and *Color2* parameters define the boundary colors of  interpolation, the *FillStyle* parameter defines the direction of interpolation.  You can pass *Standard_True* as the last parameter to update the view.  
2246
2247 The fill style can be also set with the method *void  V3d_View::SetBgGradientStyle(const Aspect_GradientFillMethod AMethod, const Standard_Boolean update)*. 
2248
2249 To get the current  background color you can use the following methods: 
2250 ~~~~~
2251    void  V3d_View::BackgroundColor
2252                 (const Quantity_TypeOfColor Type,  
2253                  Quantity_Parameter &V1, 
2254                  Quantity_Parameter &V2, 
2255                  Quantity_Parameter &V3) 
2256    Quantity_Color  V3d_View::BackgroundColor()
2257    void V3d_View::GradientBackgroundColors(Quantity_Color& Color1, Quantity_Color& Color2) 
2258    Aspect_GradientBackground  GradientBackground()
2259 ~~~~~
2260    
2261 To set the image as a  background and change the background image style you can use the following  methods: 
2262 ~~~~~  
2263   void V3d_View::SetBackgroundImage
2264                 (const Standard_CString FileName,  
2265                  const Aspect_FillMethod FillStyle, 
2266                  const Standard_Boolean update) 
2267   void  V3d_View::SetBgImageStyle
2268                 (const Aspect_FillMethod FillStyle,  
2269                  const Standard_Boolean update) 
2270 ~~~~~
2271
2272 The *FileName* parameter defines the image file name and the path to it,  the *FillStyle* parameter defines the method of filling the background with the  image. The methods are:  
2273   * *Aspect_FM_NONE* --  draws the image in the default position;
2274   * *Aspect_FM_CENTERED* -- draws the image at the center of the view;
2275   * *Aspect_FM_TILED* -- tiles the view with the image;
2276   * *Aspect_FM_STRETCH* -- stretches the image over the view.
2277
2278
2279 @subsubsection occt_visu_4_4_10 Dumping a 3D scene into an image file
2280
2281 The 3D scene displayed in the view can be dumped in high resolution into an image file. The high resolution (8192x8192 on some implementations) is achieved using the Frame Buffer Objects (FBO) provided by the graphic driver. Frame Buffer Objects enable off-screen rendering into a virtual view to produce images in the background mode (without displaying any graphics on the screen).
2282
2283 The *V3d_View* has the following methods for  dumping the 3D scene: 
2284 ~~~~
2285 Standard_Boolean  V3d_View::Dump 
2286         (const Standard_CString theFile, 
2287          const Image_TypeOfImage theBufferType)
2288 ~~~~
2289 Dumps the scene into an image file with the view  dimensions.
2290
2291 ~~~~
2292 Standard_Boolean  V3d_View::Dump 
2293         (const Standard_CString theFile, 
2294          const Aspect_FormatOfSheetPaper  theFormat, 
2295          const Image_TypeOfImage theBufferType)
2296 ~~~~
2297 Makes the dimensions of the output image compatible to a certain format of printing paper passed by *theFormat* argument.  
2298   
2299 These methods dump the 3D scene into an image file passed by its name  and path as theFile.  
2300
2301 The raster image data handling algorithm is based on the *Image_PixMap* class. The supported extensions are ".png", ".bmp", ".png", ".png".
2302
2303 The value passed as *theBufferType* argument defines the type of the  buffer for an output image <i>(RGB, RGBA, floating-point, RGBF, RGBAF)</i>. Both  methods return *Standard_True* if the scene has been successfully dumped.  
2304
2305 There is also class *Image_AlienPixMap* providing import / export from / to external image files in formats supported by **FreeImage** library.
2306
2307 **Note** that dumping the image for a paper format with  large dimensions is a memory consuming operation, it might be necessary to take  care of preparing enough free memory to perform this operation. 
2308
2309 ~~~~
2310 Handle_Image_PixMap  V3d_View::ToPixMap 
2311         (const Standard_Integer theWidth, 
2312         const Standard_Integer theHeight, 
2313         const Image_TypeOfImage theBufferType, 
2314         const Standard_Boolean theForceCentered) 
2315 ~~~~
2316 Dumps the displayed 3d scene into a pixmap  with a width and height passed as *theWidth* and theHeight arguments.  
2317
2318 The value passed as *theBufferType* argument defines the type of the  buffer for a pixmap <i>(RGB, RGBA, floating-point, RGBF, RGBAF)</i>.  The last parameter allows centering the 3D scene on dumping. 
2319
2320 All these methods assume that you have  created a view and displayed a 3d scene in it. However, the window used for  such a view could be virtual, so you can dump the 3d scene in the background  mode without displaying it on the screen. To use such an opportunity you can  perform the following steps: 
2321 * Create display connection; 
2322 * Initialize graphic driver; 
2323 * Create a window; 
2324 * Set up the window as virtual, *Aspect_Window::SetVirtual()* ; 
2325 * Create a view and an interactive context; 
2326 * Assign the virtual window to the view; 
2327 * Display a 3D scene; 
2328 *  Use one of the functions described above to dump the 3D scene. 
2329
2330 The following example demonstrates this  procedure for *WNT_Window* : 
2331
2332 ~~~~~
2333 // create a dummy display  connection
2334 Handle(Aspect_DisplayConnection)  aDisplayConnection;
2335
2336 // create a graphic driver
2337 Handle  (Graphic3d_GraphicDriver) aDriver = Graphic3d::InitGraphicDriver (aDisplayConnection); 
2338
2339 // create a window
2340 Standard_Integer  aDefWidth  = 800; 
2341 Standard_Integer  aDefHeight = 600; 
2342 Handle  (WNT_WClass) aWClass =  new WNT_WClass ("Virtual Class",DefWindowProc, 
2343                               CS_VREDRAW | CS_HREDRAW, 0, 0,  
2344                               ::LoadCursor (NULL, IDC_ARROW)); 
2345 Handle  (WNT_Window) aWindow =  new WNT_Window ("VirtualWnd",  aWClass,  
2346                               WS_OVERLAPPEDWINDOW, 0, 0,  
2347                               aDefWidth, aDefHeight); 
2348
2349 // set up the window as  virtual
2350 aWindow->SetVirtual  (Standard_True); 
2351
2352 // create a view and an  interactive context
2353 Handle  (V3d_Viewer) aViewer =  new V3d_Viewer (aDriver, 
2354                               Standard_ExtString ("Virtual")); 
2355 Handle  (AIS_InteractiveContext) aContext = new AIS_InteractiveContext (aViewer); 
2356 Handle  (V3d_View) aView = aViewer->CreateView (); 
2357
2358 // assign the virtual window  to the view
2359 aView->SetWindow  (aWindow); 
2360
2361 // display a 3D scene
2362 Handle (AIS_Shape) aBox = new AIS_Shape (BRepPrimAPI_MakeBox (5, 5, 5)); 
2363 aContext->Display  (aBox); 
2364 aView->FitAll(); 
2365
2366 // dump the 3D scene into an  image file
2367 aView->Dump  ("3dscene.png"); 
2368 ~~~~~
2369
2370 @subsubsection occt_visu_4_4_11 Printing a 3D scene
2371
2372 The contents of a view can be printed out. Moreover, the OpenGl graphic driver used by the v3d view supports printing in high  resolution. The print method uses the OpenGl frame buffer (Frame Buffer Object)  for rendering the view contents and advanced print algorithms that allow  printing in, theoretically, any resolution.  
2373
2374 The method *void V3d_View::Print(const Aspect_Handle hPrnDC, const Standard_Boolean showDialog, const Standard_Boolean showBackground, const Standard_CString  filename, const Aspect_PrintAlgo printAlgorithm)* prints the view  contents: 
2375
2376 *hPrnDC* is the printer device handle. You can pass your own printer handle  or *NULL* to select the printer by the default dialog. In that case you can use  the default dialog or pass *Standard_False* as the *showDialog* argument to  select the default printer automatically.  
2377
2378 You can define  the filename for the printer driver if you want to print out the result into a  file.  
2379 If you do not want to print the  background, you can pass *Standard_False* as the *showBackground* argument. 
2380 The *printAlgorithm* argument allows choosing between two print algorithms that  define how the 3d scene is mapped to the print area when the maximum dimensions of the frame buffer are smaller than the dimensions of the print area by choosing *Aspect_PA_STRETCH* or *Aspect_PA_TILE*
2381
2382 The first value  defines the stretch algorithm: the scene is drawn with the maximum possible  frame buffer dimensions and then is stretched to the whole printing area. The  second value defines *TileSplit* algorithm: covering the whole printing area by  rendering multiple parts of the viewer. 
2383
2384 **Note** that at the moment the printing is implemented only for Windows.
2385
2386 @subsubsection occt_visu_4_4_12 Vector image export
2387
2388 The 3D content of a view can be exported to  the vector image file format. The vector image export is powered by the *GL2PS*  library. You can export 3D scenes into a file format supported by the  GL2PS library: PostScript (PS), Encapsulated PostScript (EPS), Portable  Document Format (PDF), Scalable Vector Graphics (SVG), LaTeX file format and  Portable LaTeX Graphics (PGF).  
2389
2390 The method   *void  Visual3d_View::Export (const Standard_CString FileName, const Graphic3d_ExportFormat Format, const Graphic3d_SortType aSortType, const Standard_Real Precision, const Standard_Address ProgressBarFunc, const Standard_Address ProgressObject)* of *Visual3d_View* class  allows exporting a 3D scene: 
2391
2392 The *FileName*  defines the output image file name and the *Format* argument defines the output  file format:  
2393   * *Graphic3d_EF_PostScript  (PS)*,
2394   * *Graphic3d_EF_EhnPostScript  (EPS)*,
2395   * *Graphic3d_EF_TEX  (TEX)*,
2396   * *Graphic3d_EF_PDF  (PDF)*,
2397   * *Graphic3d_EF_SVG  (SVG)*,
2398   * *Graphic3d_EF_PGF  (PGF)*.
2399
2400 The *aSortType* parameter defines *GL2PS* sorting algorithm for the  primitives. The *Precision, ProgressBarFunc* and *ProgressObject* parameters are  implemented for future uses and at the moment have no effect. 
2401
2402 The *Export* method supports only basic 3d  graphics and has several limitations: 
2403   * Rendering large scenes could be slow and  can lead to large output files;
2404   * Transparency is only supported for PDF and  SVG output;
2405   * Textures and some effects are not supported by the *GL2PS* library.
2406
2407 @subsubsection occt_visu_4_4_13 Ray tracing support
2408
2409 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:
2410 * Hard shadows
2411 * Refractions
2412 * Reflection
2413 * Transparency
2414 * Texturing
2415 * Support of non-polygon objects, such as lines, text, highlighting, selection.
2416 * Performance optimization using 2-level bounding volume hierarchy (BVH).
2417
2418 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.
2419 To make the BVH reusable it has been added into an individual reusable OCCT package *TKMath/BVH*.
2420
2421 There are several ray-tracing options that user can switch on/off:
2422 * Maximum ray tracing depth
2423 * Shadows rendering
2424 * Specular reflections
2425 * Adaptive anti aliasing
2426 * Transparency shadow effects
2427
2428 Example:
2429 ~~~~~
2430 Graphic3d_RenderingParams& aParams = aView->ChangeRenderingParams();
2431 // specifies rendering mode
2432 aParams.Method = Graphic3d_RM_RAYTRACING;
2433 // maximum ray-tracing depth
2434 aParams.RaytracingDepth = 3;
2435 // enable shadows rendering
2436 aParams.IsShadowEnabled = Standard_True;
2437 // enable specular reflections.
2438 aParams.IsReflectionEnabled = Standard_True;
2439 // enable adaptive anti-aliasing
2440 aParams.IsAntialiasingEnabled = Standard_True;
2441 // enable light propagation through transparent media.
2442 aParams.IsTransparentShadowEnabled = Standard_True;
2443 // update the view
2444 aView->Update();
2445 ~~~~~
2446
2447 @subsubsection occt_visu_4_4_14 Display priorities
2448
2449 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.
2450
2451 @subsubsection occt_visu_4_4_15 Z-layer support
2452
2453 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.
2454
2455 Example:
2456
2457 ~~~~~
2458 // set z-layer to an interactive object
2459 Handle(AIS_InteractiveContext) aContext = ...
2460 Handle(AIS_InteractiveObject) anInterObj = ...
2461 Standard_Integer anId = 3;
2462 aViewer->AddZLayer (anId);
2463 aContext->SetZLayer (anInterObj, anId);
2464 ~~~~~
2465
2466 For each z-layer, it is allowed to:
2467 * Enable / disable depth test for layer.
2468 * Enable / disable depth write for layer.
2469 * Enable / disable depth buffer clearing.
2470 * Enable / disable polygon offset.
2471
2472 You can get the options using getter from *Visual3d_ViewManager* and *V3d_Viewer*. It returns *Graphic3d_ZLayerSettings* for a given *LayerId*.
2473
2474 Example:
2475 ~~~~~
2476 // change z-layer settings
2477 Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
2478 aSettings.SetEnableDepthTest (Standard_True);
2479 aSettings.SetEnableDepthWrite(Standard_True);
2480 aSettings.SetClearDepth      (Standard_True);
2481 aSettings.SetPolygonOffset   (Graphic3d_PolygonOffset());
2482 aViewer->SetZLayerSettings (anId, aSettings);
2483 ~~~~~
2484
2485 Another application for Z-Layer feature is treating visual precision issues when displaying objects far from the World Center.
2486 The key problem with such objects is that visualization data is stored and manipulated with single precision floating-point numbers (32-bit).
2487 Single precision 32-bit floating-point numbers give only 6-9 significant decimal digits precision,
2488 while double precision 64-bit numbers give 15-17 significant decimal digits precision, which is sufficient enough for most applications.
2489
2490 When moving an Object far from the World Center, float number steadily eats precision.
2491 The camera Eye position adds leading decimal digits to the overall Object transformation, which discards smaller digits due to floating point number nature.
2492 For example, the object of size 0.0000123 moved to position 1000 has result transformation 1000.0000123,
2493 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.
2494
2495 This imprecision results in visual artifacts of two kinds in the 3D Viewer:
2496
2497 * Overall per-vertex Object distortion.
2498   This happens when each vertex position has been defined within World Coordinate system.
2499 * The object itself is not distorted, but its position in the World is unstable and imprecise - the object jumps during camera manipulations.
2500   This happens when vertices have been defined within Local Coordinate system at the distance small enough to keep precision within single precision float,
2501   however Local Transformation applied to the Object is corrupted due to single precision float.
2502
2503 The first issue cannot be handled without switching the entire presentation into double precision (for each vertex position).
2504 However, visualization hardware is much faster using single precision float number rather than double precision - so this is not an option in most cases.
2505 The second issue, however, can be negated by applying special rendering tricks.
2506
2507 So, to apply this feature in OCCT, the application :
2508
2509 * Defines Local Transformation for each object to fit the presentation data into single precision float without distortion.
2510 * Spatially splits the world into smaller areas/cells where single precision float will be sufficient.
2511   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).
2512 * Defines a Z-Layer for each spatial cell containing any object.
2513 * Defines the Local Origin property of the Z-Layer according to the center of the cell.
2514   
2515 ~~~~~  
2516     Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (anId);
2517     aSettings.SetLocalOrigin (400.0, 0.0, 0.0);
2518 ~~~~~   
2519 * Assigns a presentable object to the nearest Z-Layer.
2520
2521 Note that Local Origin of the Layer is used only for rendering - everything outside will be still defined in the World Coordinate System,
2522 including Local Transformation of the Object and Detection results.
2523 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.
2524
2525 @subsubsection occt_visu_4_4_16 Clipping planes
2526
2527 The ability to define custom clipping planes could be very useful for some tasks. OCCT provides such an opportunity.
2528
2529 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:
2530
2531 ~~~~~
2532 Graphic3d_ClipPlane::Graphic3d_ClipPlane(const gp_Pln& thePlane)
2533 void Graphic3d_ClipPlane::SetEquation (const gp_Pln& thePlane)
2534 Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Equation& theEquation)
2535 void Graphic3d_ClipPlane::SetEquation (const Equation& theEquation)
2536 gp_Pln Graphic3d_ClipPlane::ToPlane() const
2537 ~~~~~
2538
2539 The clipping planes can be activated with the following method:
2540 ~~~~~
2541 void Graphic3d_ClipPlane::SetOn (const Standard_Boolean theIsOn)
2542 ~~~~~
2543
2544 The number of clipping planes is limited. You can check the limit value via method *Graphic3d_GraphicDriver::InquirePlaneLimit()*;
2545
2546 ~~~~~
2547 // get the limit of clipping planes for the current view
2548 Standard_Integer aMaxClipPlanes = aView->Viewer()->Driver()->InquirePlaneLimit();
2549 ~~~~~
2550
2551 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:
2552 ~~~~~
2553 // create a new clipping plane
2554 const Handle(Graphic3d_ClipPlane)& aClipPlane = new Graphic3d_ClipPlane();
2555 // change equation of the clipping plane
2556 Standard_Real aCoeffA = ...
2557 Standard_Real aCoeffB = ...
2558 Standard_Real aCoeffC = ...
2559 Standard_Real aCoeffD = ...
2560 aClipPlane->SetEquation (gp_Pln (aCoeffA, aCoeffB, aCoeffC, aCoeffD));
2561 // set capping
2562 aClipPlane->SetCapping (aCappingArg == "on");
2563 // set the material with red color of clipping plane
2564 Graphic3d_MaterialAspect aMat = aClipPlane->CappingMaterial();
2565 Quantity_Color aColor (1.0, 0.0, 0.0, Quantity_TOC_RGB);
2566 aMat.SetAmbientColor (aColor);
2567 aMat.SetDiffuseColor (aColor);
2568 aClipPlane->SetCappingMaterial (aMat);
2569 // set the texture of clipping plane
2570 Handle(Graphic3d_Texture2Dmanual) aTexture = ...
2571 aTexture->EnableModulate();
2572 aTexture->EnableRepeat();
2573 aClipPlane->SetCappingTexture (aTexture);
2574 // add the clipping plane to an interactive object
2575 Handle(AIS_InteractiveObject) aIObj = ...
2576 aIObj->AddClipPlane (aClipPlane);
2577 // or to the whole view
2578 aView->AddClipPlane (aClipPlane);
2579 // activate the clipping plane
2580 aClipPlane->SetOn(Standard_True);
2581 // update the view
2582 aView->Update();
2583 ~~~~~
2584
2585
2586 @subsubsection occt_visu_4_4_17 Automatic back face culling
2587
2588 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()*.
2589
2590 The following features are applied in *StdPrs_ToolShadedShape::IsClosed()*, which is used for definition of back face culling in *ShadingAspect*:
2591 * disable culling for free closed Shells (not inside the Solid) since reversed orientation of a free Shell is a valid case;
2592 * enable culling for Solids packed into a compound;
2593 * ignore Solids with incomplete triangulation.
2594
2595 Back face culling is turned off at TKOpenGl level in the following cases:
2596 * clipping/capping planes are in effect;
2597 * for translucent objects;
2598 * with hatching presentation style.
2599
2600 @subsection occt_visu_4_5 Examples: creating a 3D scene
2601
2602 To create 3D graphic objects and display them in the screen,  follow the procedure below:
2603 1. Create attributes.
2604 2. Create a 3D viewer.
2605 3. Create a view.
2606 4. Create an interactive context.
2607 5. Create interactive objects.
2608 6. Create primitives in the interactive  object.
2609 7. Display the interactive object.
2610
2611 @subsubsection occt_visu_4_5_1 Create attributes
2612
2613 Create colors.
2614
2615 ~~~~~
2616 Quantity_Color aBlack (Quantity_NOC_BLACK);
2617 Quantity_Color aBlue (Quantity_NOC_MATRABLUE);
2618 Quantity_Color aBrown (Quantity_NOC_BROWN4);
2619 Quantity_Color aFirebrick (Quantity_NOC_FIREBRICK);
2620 Quantity_Color aForest (Quantity_NOC_FORESTGREEN);
2621 Quantity_Color aGray (Quantity_NOC_GRAY70);
2622 Quantity_Color aMyColor (0.99, 0.65, 0.31, Quantity_TOC_RGB);
2623 Quantity_Color aBeet (Quantity_NOC_BEET);
2624 Quantity_Color aWhite (Quantity_NOC_WHITE);
2625 ~~~~~
2626
2627 Create line attributes.
2628
2629 ~~~~~
2630 Handle(Graphic3d_AspectLine3d) anAspectBrown = new Graphic3d_AspectLine3d();
2631 Handle(Graphic3d_AspectLine3d) anAspectBlue = new Graphic3d_AspectLine3d();
2632 Handle(Graphic3d_AspectLine3d) anAspectWhite = new Graphic3d_AspectLine3d();
2633 anAspectBrown->SetColor (aBrown);
2634 anAspectBlue ->SetColor (aBlue);
2635 anAspectWhite->SetColor (aWhite);
2636 ~~~~~
2637
2638 Create marker attributes.
2639 ~~~~~
2640 Handle(Graphic3d_AspectMarker3d aFirebrickMarker = new Graphic3d_AspectMarker3d();
2641 // marker attributes
2642 aFirebrickMarker->SetColor (Firebrick);
2643 aFirebrickMarker->SetScale (1.0);
2644 aFirebrickMarker->SetType (Aspect_TOM_BALL);
2645 // or this
2646 // it is a preferred way (supports full-color images on modern hardware).
2647 aFirebrickMarker->SetMarkerImage (theImage)
2648 ~~~~~
2649
2650 Create facet attributes.
2651 ~~~~~
2652 Handle(Graphic3d_AspectFillArea3d) aFaceAspect =  new Graphic3d_AspectFillArea3d();
2653 Graphic3d_MaterialAspect aBrassMaterial (Graphic3d_NOM_BRASS);
2654 Graphic3d_MaterialAspect aGoldMaterial  (Graphic3d_NOM_GOLD);
2655 aFaceAspect->SetInteriorStyle (Aspect_IS_SOLID);
2656 aFaceAspect->SetInteriorColor (aMyColor);
2657 aFaceAspect->SetDistinguishOn ();
2658 aFaceAspect->SetFrontMaterial (aGoldMaterial);
2659 aFaceAspect->SetBackMaterial  (aBrassMaterial);
2660 aFaceAspect->SetEdgeOn();
2661 ~~~~~
2662
2663 Create text attributes.
2664 ~~~~~
2665 Handle(Graphic3d_AspectText3d) aTextAspect = new Graphic3d_AspectText3d (aForest, Graphic3d_NOF_ASCII_MONO, 1.0, 0.0);
2666 ~~~~~
2667
2668 @subsubsection occt_visu_4_5_2 Create a 3D Viewer (a Windows example)
2669
2670 ~~~~~
2671 // create a default connection
2672 Handle(Aspect_DisplayConnection) aDisplayConnection;
2673 // create a graphic driver from default connection
2674 Handle(OpenGl_GraphicDriver) aGraphicDriver = new OpenGl_GraphicDriver (GetDisplayConnection());
2675 // create a viewer
2676 TCollection_ExtendedString aName ("3DV");
2677 myViewer = new V3d_Viewer (aGraphicDriver,aName.ToExtString(), "");
2678 // set parameters for V3d_Viewer
2679 // defines default lights -
2680 //   positional-light 0.3 0.0 0.0
2681 //   directional-light V3d_XnegYposZpos
2682 //   directional-light V3d_XnegYneg
2683 //   ambient-light
2684 a3DViewer->SetDefaultLights();
2685 // activates all the lights defined in this viewer
2686 a3DViewer->SetLightOn();
2687 // set background color to black
2688 a3DViewer->SetDefaultBackgroundColor (Quantity_NOC_BLACK);
2689 ~~~~~
2690
2691
2692 @subsubsection occt_visu_4_5_3 Create a 3D view (a Windows example)
2693
2694 It is assumed that a valid Windows window may already be  accessed via the method *GetSafeHwnd()*.
2695 ~~~~~
2696 Handle (WNT_Window) aWNTWindow = new WNT_Window (GetSafeHwnd());
2697 myView = myViewer->CreateView();
2698 myView->SetWindow (aWNTWindow);
2699 ~~~~~
2700
2701 @subsubsection occt_visu_4_5_4 Create an interactive context
2702
2703 ~~~~~
2704 myAISContext = new AIS_InteractiveContext (myViewer);
2705 ~~~~~
2706
2707 You are now able to display interactive objects such as an *AIS_Shape*.
2708
2709 ~~~~~
2710 TopoDS_Shape aShape = BRepAPI_MakeBox (10, 20, 30).Solid();
2711 Handle(AIS_Shape) anAISShape = new AIS_Shape(aShape);
2712 myAISContext->Display (anAISShape);
2713 ~~~~~
2714
2715 @subsubsection occt_visu_4_5_5 Create your own interactive object
2716
2717 Follow the procedure below to compute the presentable object:
2718
2719 1. Build a presentable object inheriting from *AIS_InteractiveObject* (refer to the Chapter on @ref occt_visu_2_1 "Presentable Objects").
2720 2. Reuse the *Prs3d_Presentation* provided as an argument of the compute methods.
2721
2722 **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.
2723
2724
2725 Let us look at the example of compute methods
2726
2727 ~~~~~
2728 Void
2729 myPresentableObject::Compute
2730   (const Handle(PrsMgr_PresentationManager3d)& thePrsManager,
2731    const Handle(Prs3d_Presentation)& thePrs,
2732    const Standard_Integer theMode)
2733 (
2734   //...
2735 )
2736
2737 void
2738 myPresentableObject::Compute (const Handle(Prs3d_Projector)& ,
2739                               const Handle(Prs3d_Presentation)& thePrs)
2740 (
2741   //...
2742 )
2743 ~~~~~
2744
2745 @subsubsection occt_visu_4_5_6 Create primitives in the interactive object
2746
2747 Get the group used in *Prs3d_Presentation*.
2748
2749 ~~~~~
2750 Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs);
2751 ~~~~~
2752
2753 Update the group attributes.
2754
2755 ~~~~~
2756 aGroup->SetPrimitivesAspect (anAspectBlue);
2757 ~~~~~
2758
2759 Create two triangles in *aGroup*.
2760
2761 ~~~~~
2762 Standard_Integer aNbTria = 2;
2763 Handle(Graphic3d_ArrayOfTriangles) aTriangles = new Graphic3d_ArrayOfTriangles (3 * aNbTria, 0, Standard_True);
2764 Standard_Integer anIndex;
2765 for (anIndex = 1; anIndex <= aNbTria; nt++)
2766 {
2767   aTriangles->AddVertex (anIndex * 5.,      0., 0., 1., 1., 1.);
2768   aTriangles->AddVertex (anIndex * 5 + 5,   0., 0., 1., 1., 1.);
2769   aTriangles->AddVertex (anIndex * 5 + 2.5, 5., 0., 1., 1., 1.);
2770 }
2771 aGroup->BeginPrimitives();
2772 aGroup->AddPrimitiveArray (aTriangles);
2773 aGroup->EndPrimitives();
2774 ~~~~~
2775
2776 The methods *BeginPrimitives()* and *EndPrimitives()* are used  when creating a set of various primitives in the same group.
2777 Use the polyline function to create a boundary box for the *thePrs* structure in group *aGroup*.
2778
2779 ~~~~~
2780 Standard_Real Xm, Ym, Zm, XM, YM, ZM;
2781 thePrs->MinMaxValues (Xm, Ym, Zm, XM, YM, ZM);
2782
2783 Handle(Graphic3d_ArrayOfPolylines) aPolylines = new Graphic3d_ArrayOfPolylines (16, 4);
2784 aPolylines->AddBound (4);
2785 aPolylines->AddVertex (Xm,  Ym, Zm);
2786 aPolylines->AddVertex (Xm,  Ym, ZM);
2787 aPolylines->AddVertex (Xm,  YM, ZM);
2788 aPolylines->AddVertex (Xm,  YM, Zm);
2789 aPolylines->AddBound (4);
2790 aPolylines->AddVertex (Xm,  Ym, Zm);
2791 aPolylines->AddVertex (XM,  Ym, Zm);
2792 aPolylines->AddVertex (XM,  Ym, ZM);
2793 aPolylines->AddVertex (XM,  YM, ZM);
2794 aPolylines->AddBound (4);
2795 aPolylines->AddVertex (XM,  YM, Zm);
2796 aPolylines->AddVertex (XM,  Ym, Zm);
2797 aPolylines->AddVertex (XM,  YM, Zm);
2798 aPolylines->AddVertex (Xm,  YM, Zm);
2799 aPolylines->AddBound (4);
2800 aPolylines->AddVertex (Xm,  YM, ZM);
2801 aPolylines->AddVertex (XM,  YM, ZM);
2802 aPolylines->AddVertex (XM,  Ym, ZM);
2803 aPolylines->AddVertex (Xm,  Ym, ZM);
2804
2805 aGroup->BeginPrimitives();
2806 aGroup->AddPrimitiveArray(aPolylines);
2807 aGroup->EndPrimitives();
2808 ~~~~~
2809
2810 Create text and markers in group *aGroup*.
2811
2812 ~~~~~
2813 static char* texte[3] =
2814 {
2815   "Application title",
2816   "My company",
2817   "My company address."
2818 };
2819 Handle(Graphic3d_ArrayOfPoints) aPtsArr = new Graphic3d_ArrayOfPoints (2, 1);
2820 aPtsArr->AddVertex (-40.0, -40.0, -40.0);
2821 aPtsArr->AddVertex (40.0, 40.0, 40.0);
2822 aGroup->BeginPrimitives();
2823 aGroup->AddPrimitiveArray (aPtsArr);
2824 aGroup->EndPrimitives();
2825
2826 Graphic3d_Vertex aMarker (0.0, 0.0, 0.0);
2827 for (i=0; i <= 2; i++)
2828 {
2829   aMarker.SetCoord (-(Standard_Real )i * 4 + 30,
2830                      (Standard_Real )i * 4,
2831                     -(Standard_Real )i * 4);
2832   aGroup->Text (texte[i], Marker, 20.);
2833 }
2834
2835 ~~~~~
2836
2837 @section occt_visu_5 Mesh Visualization Services
2838
2839 <i>MeshVS</i> (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.
2840
2841 From a developer's point of view, it is easy to integrate the *MeshVS* component into any mesh-related application with the following guidelines:
2842
2843 * Derive a data source class from the *MeshVS_DataSource* class.
2844 * Re-implement its virtual methods, so as to give the <i>MeshVS</i> 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.
2845 * Create an instance of <i>MeshVS_Mesh</i> class.
2846 * Create an instance of your data source class and pass it to a <i>MeshVS_Mesh</i> object through the <i>SetDataSource()</i> method.
2847 * Create one or several objects of <i>MeshVS_PrsBuilder</i>-derived classes (standard, included in the <i>MeshVS</i> package, or your custom ones).
2848 * Each <i>PrsBuilder</i> is responsible for drawing a <i> MeshVS_Mesh</i> presentation in a certain display mode(s) specified as a <i>PrsBuilder</i> constructor's argument. Display mode is treated by <i>MeshVS</i> classes as a combination of bit flags (two least significant bits are used to encode standard display modes: wireframe, shading and shrink).
2849 * Pass these objects to the <i>MeshVS_Mesh::AddBuilder()</i> method. <i>MeshVS_Mesh</i> 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 <i>PrsBuilder</i> objects to act as a highlighter with the help of a corresponding argument of the <i>AddBuilder()</i> method.
2850
2851 Visual attributes of the <i>MeshVS_Mesh</i> object (such as shading color, shrink coefficient and so on)  are controlled through <i>MeshVS_Drawer</i> object. It maintains a map "Attribute ID --> attribute value" and can be easily extended with any number of custom attributes.
2852
2853 In all other respects, <i>MeshVS_Mesh</i> is very similar to any other class derived from <i>AIS_InteractiveObject</i> and it should be used accordingly (refer to the description of <i>AIS package</i> in the documentation).
2854