0031650: Visualization - invalid picking of object with local transformation and...
[occt.git] / src / SelectMgr / SelectMgr_ViewerSelector.cxx
1 // Created on: 1995-02-15
2 // Created by: Roberc Coublanc
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <SelectMgr_ViewerSelector.hxx>
18
19 #include <BVH_Tree.hxx>
20 #include <gp_GTrsf.hxx>
21 #include <gp_Pnt.hxx>
22 #include <OSD_Environment.hxx>
23 #include <Precision.hxx>
24 #include <Select3D_SensitiveEntity.hxx>
25 #include <SelectBasics_PickResult.hxx>
26 #include <SelectMgr_EntityOwner.hxx>
27 #include <SelectMgr_SortCriterion.hxx>
28 #include <SelectMgr_SensitiveEntitySet.hxx>
29 #include <TColStd_Array1OfInteger.hxx>
30 #include <TCollection_AsciiString.hxx>
31 #include <TColStd_HArray1OfInteger.hxx>
32 #include <TColStd_ListOfInteger.hxx>
33
34 #include <algorithm>
35
36 IMPLEMENT_STANDARD_RTTIEXT(SelectMgr_ViewerSelector, Standard_Transient)
37
38 namespace {
39   // Comparison operator for sorting selection results
40   class CompareResults
41   {
42   public:
43    
44     CompareResults (const SelectMgr_IndexedDataMapOfOwnerCriterion& aMapOfCriterion)
45       : myMapOfCriterion (aMapOfCriterion)
46     {
47     }
48
49     Standard_Boolean operator() (Standard_Integer theLeft, Standard_Integer theRight) const
50     {
51       return myMapOfCriterion.FindFromIndex(theLeft) > myMapOfCriterion.FindFromIndex(theRight);
52     }
53
54   private:
55     void operator = (const CompareResults&);
56
57   private:
58     const SelectMgr_IndexedDataMapOfOwnerCriterion&  myMapOfCriterion;
59   };
60
61   static const Graphic3d_Mat4d SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
62 }
63
64 //=======================================================================
65 // function : updatePoint3d
66 // purpose  :
67 //=======================================================================
68 void SelectMgr_ViewerSelector::updatePoint3d (SelectMgr_SortCriterion& theCriterion,
69                                               const SelectBasics_PickResult& thePickResult,
70                                               const Handle(Select3D_SensitiveEntity)& theEntity,
71                                               const gp_GTrsf& theInversedTrsf,
72                                               const SelectMgr_SelectingVolumeManager& theMgr) const
73 {
74   if (theMgr.GetActiveSelectionType() != SelectMgr_SelectingVolumeManager::Point)
75   {
76     return;
77   }
78
79   bool hasNormal = false;
80   if (thePickResult.HasPickedPoint())
81   {
82     theCriterion.Point  = thePickResult.PickedPoint();
83     theCriterion.Normal = thePickResult.SurfaceNormal();
84     const float aNormLen2 = theCriterion.Normal.SquareModulus();
85     if (aNormLen2 > ShortRealEpsilon())
86     {
87       hasNormal = true;
88       theCriterion.Normal *= 1.0f / sqrtf (aNormLen2);
89     }
90   }
91   else if (!thePickResult.IsValid())
92   {
93     theCriterion.Point = thePickResult.PickedPoint();
94     return;
95   }
96   else
97   {
98     theCriterion.Point = theMgr.DetectedPoint (theCriterion.Depth);
99   }
100
101   gp_GTrsf anInvTrsf = theInversedTrsf;
102   if (theCriterion.Entity->HasInitLocation())
103   {
104     anInvTrsf = theCriterion.Entity->InvInitLocation() * anInvTrsf;
105   }
106   if (anInvTrsf.Form() != gp_Identity)
107   {
108     const gp_GTrsf anInvInvTrsd = anInvTrsf.Inverted();
109     anInvInvTrsd.Transforms (theCriterion.Point.ChangeCoord());
110     if (hasNormal)
111     {
112       Graphic3d_Mat4d aMat4;
113       anInvInvTrsd.GetMat4 (aMat4);
114       const Graphic3d_Vec4d aNormRes = aMat4 * Graphic3d_Vec4d (Graphic3d_Vec3d (theCriterion.Normal), 0.0);
115       theCriterion.Normal = Graphic3d_Vec3 (aNormRes.xyz());
116     }
117   }
118
119   if (mySelectingVolumeMgr.Camera().IsNull())
120   {
121     theCriterion.Tolerance = theEntity->SensitivityFactor() / 33.0;
122   }
123   else if (mySelectingVolumeMgr.Camera()->IsOrthographic())
124   {
125     theCriterion.Tolerance = myCameraScale * theEntity->SensitivityFactor();
126   }
127   else
128   {
129     const Standard_Real aDistFromEye = Abs ((theCriterion.Point.XYZ() - myCameraEye.XYZ()).Dot (myCameraDir.XYZ()));
130     theCriterion.Tolerance = aDistFromEye * myCameraScale * theEntity->SensitivityFactor();
131   }
132 }
133
134 //==================================================
135 // Function: Initialize
136 // Purpose :
137 //==================================================
138 SelectMgr_ViewerSelector::SelectMgr_ViewerSelector():
139 preferclosest(Standard_True),
140 myToUpdateTolerance (Standard_True),
141 myCameraScale (1.0),
142 myCurRank (0),
143 myIsLeftChildQueuedFirst (Standard_False),
144 myEntityIdx (0)
145 {
146   myEntitySetBuilder = new BVH_BinnedBuilder<Standard_Real, 3, 4> (BVH_Constants_LeafNodeSizeSingle, BVH_Constants_MaxTreeDepth, Standard_True);
147 }
148
149 //=======================================================================
150 // Function: SetPixelTolerance
151 // Purpose :
152 //=======================================================================
153 void SelectMgr_ViewerSelector::SetPixelTolerance (const Standard_Integer theTolerance)
154 {
155   if (myTolerances.Tolerance() == theTolerance)
156   {
157     return;
158   }
159
160   myToUpdateTolerance = Standard_True;
161   if (theTolerance < 0)
162   {
163     myTolerances.ResetDefaults();
164   }
165   else
166   {
167     myTolerances.SetCustomTolerance (theTolerance);
168   }
169 }
170
171 //==================================================
172 // Function: Activate
173 // Purpose :
174 //==================================================
175 void SelectMgr_ViewerSelector::Activate (const Handle(SelectMgr_Selection)& theSelection)
176 {
177   for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
178   {
179     aSelEntIter.Value()->SetActiveForSelection();
180   }
181
182   if (theSelection->GetSelectionState() != SelectMgr_SOS_Activated)
183   {
184     theSelection->SetSelectionState (SelectMgr_SOS_Activated);
185
186     myTolerances.Add (theSelection->Sensitivity());
187     myToUpdateTolerance = Standard_True;
188   }
189 }
190
191 //==================================================
192 // Function: Deactivate
193 // Purpose :
194 //==================================================
195 void SelectMgr_ViewerSelector::Deactivate (const Handle(SelectMgr_Selection)& theSelection)
196 {
197   for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (theSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
198   {
199     aSelEntIter.Value()->ResetSelectionActiveStatus();
200   }
201
202   if (theSelection->GetSelectionState() == SelectMgr_SOS_Activated)
203   {
204     theSelection->SetSelectionState (SelectMgr_SOS_Deactivated);
205
206     myTolerances.Decrement (theSelection->Sensitivity());
207     myToUpdateTolerance = Standard_True;
208   }
209 }
210
211 //==================================================
212 // Function: Clear
213 // Purpose :
214 //==================================================
215 void SelectMgr_ViewerSelector::Clear()
216 {
217   mystored.Clear();
218 }
219
220 //=======================================================================
221 // function: isToScaleFrustum
222 // purpose : Checks if the entity given requires to scale current selecting frustum
223 //=======================================================================
224 Standard_Boolean SelectMgr_ViewerSelector::isToScaleFrustum (const Handle(Select3D_SensitiveEntity)& theEntity)
225 {
226   return mySelectingVolumeMgr.GetActiveSelectionType() == SelectMgr_SelectingVolumeManager::Point
227     && sensitivity (theEntity) < myTolerances.Tolerance();
228 }
229
230 //=======================================================================
231 // function: sensitivity
232 // purpose : In case if custom tolerance is set, this method will return sum of entity
233 //           sensitivity and custom tolerance.
234 //=======================================================================
235 Standard_Integer SelectMgr_ViewerSelector::sensitivity (const Handle(Select3D_SensitiveEntity)& theEntity) const
236 {
237   return myTolerances.IsCustomTolSet() ?
238     theEntity->SensitivityFactor() + myTolerances.CustomTolerance() : theEntity->SensitivityFactor();
239 }
240
241 //=======================================================================
242 // function: checkOverlap
243 // purpose : Internal function that checks if a particular sensitive
244 //           entity theEntity overlaps current selecting volume precisely
245 //=======================================================================
246 void SelectMgr_ViewerSelector::checkOverlap (const Handle(Select3D_SensitiveEntity)& theEntity,
247                                              const gp_GTrsf& theInversedTrsf,
248                                              SelectMgr_SelectingVolumeManager& theMgr)
249 {
250   const Handle(SelectMgr_EntityOwner)& anOwner = theEntity->OwnerId();
251   Handle(SelectMgr_SelectableObject) aSelectable = !anOwner.IsNull() ? anOwner->Selectable() : Handle(SelectMgr_SelectableObject)();
252   SelectBasics_PickResult aPickResult;
253   const Standard_Boolean isMatched = theEntity->Matches(theMgr, aPickResult);
254   if (!isMatched
255     || anOwner.IsNull())
256   {
257     return;
258   }
259
260   SelectMgr_SortCriterion aCriterion;
261   myZLayerOrderMap.Find (!aSelectable.IsNull() ? aSelectable->ZLayer() : Graphic3d_ZLayerId_Default, aCriterion.ZLayerPosition);
262   aCriterion.Entity    = theEntity;
263   aCriterion.Priority  = anOwner->Priority();
264   aCriterion.Depth     = aPickResult.Depth();
265   aCriterion.MinDist   = aPickResult.DistToGeomCenter();
266   aCriterion.ToPreferClosest = preferclosest;
267
268   if (SelectMgr_SortCriterion* aPrevCriterion = mystored.ChangeSeek (anOwner))
269   {
270     ++aPrevCriterion->NbOwnerMatches;
271     aCriterion.NbOwnerMatches = aPrevCriterion->NbOwnerMatches;
272     if (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box)
273     {
274       if (aCriterion > *aPrevCriterion)
275       {
276         updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
277         *aPrevCriterion = aCriterion;
278       }
279     }
280   }
281   else
282   {
283     aCriterion.NbOwnerMatches = 1;
284     updatePoint3d (aCriterion, aPickResult, theEntity, theInversedTrsf, theMgr);
285     mystored.Add (anOwner, aCriterion);
286   }
287 }
288
289 //=======================================================================
290 // function: computeFrustum
291 // purpose :
292 //=======================================================================
293 void SelectMgr_ViewerSelector::computeFrustum (const Handle(Select3D_SensitiveEntity)& theEnt,
294                                                const SelectMgr_SelectingVolumeManager& theMgrGlobal,
295                                                const SelectMgr_SelectingVolumeManager& theMgrObject,
296                                                const gp_GTrsf& theInvTrsf,
297                                                SelectMgr_FrustumCache& theCachedMgrs,
298                                                SelectMgr_SelectingVolumeManager& theResMgr)
299 {
300   Standard_Integer aScale = isToScaleFrustum (theEnt) ? sensitivity (theEnt) : 1;
301   const gp_GTrsf aTrsfMtr = theEnt->HasInitLocation() ? theEnt->InvInitLocation() * theInvTrsf : theInvTrsf;
302   const Standard_Boolean toScale = aScale != 1;
303   const Standard_Boolean toTransform = aTrsfMtr.Form() != gp_Identity;
304   if (toScale && toTransform)
305   {
306     theResMgr = theMgrGlobal.ScaleAndTransform (aScale, aTrsfMtr, NULL);
307     theResMgr.SetViewClipping (theMgrObject);
308   }
309   else if (toScale)
310   {
311     if (!theCachedMgrs.Find (aScale, theResMgr))
312     {
313       theResMgr = theMgrGlobal.ScaleAndTransform (aScale, gp_Trsf(), NULL);
314       theCachedMgrs.Bind (aScale, theResMgr);
315     }
316     theResMgr.SetViewClipping (theMgrObject);
317   }
318   else if (toTransform)
319   {
320     theResMgr = theMgrGlobal.ScaleAndTransform (1, aTrsfMtr, NULL);
321     theResMgr.SetViewClipping (theMgrObject);
322   }
323   else
324   {
325     theResMgr = theMgrObject;
326   }
327 }
328
329 //=======================================================================
330 // function: traverseObject
331 // purpose : Internal function that checks if there is possible overlap
332 //           between some entity of selectable object theObject and
333 //           current selecting volume
334 //=======================================================================
335 void SelectMgr_ViewerSelector::traverseObject (const Handle(SelectMgr_SelectableObject)& theObject,
336                                                const SelectMgr_SelectingVolumeManager& theMgr,
337                                                const Handle(Graphic3d_Camera)& theCamera,
338                                                const Graphic3d_Mat4d& theProjectionMat,
339                                                const Graphic3d_Mat4d& theWorldViewMat,
340                                                const Standard_Integer theViewportWidth,
341                                                const Standard_Integer theViewportHeight)
342 {
343   Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
344   if (anEntitySet->Size() == 0)
345   {
346     return;
347   }
348
349   const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aSensitivesTree = anEntitySet->BVH();
350   gp_GTrsf aInversedTrsf;
351   if (theObject->HasTransformation() || !theObject->TransformPersistence().IsNull())
352   {
353     if (theObject->TransformPersistence().IsNull())
354     {
355       aInversedTrsf = theObject->InversedTransformation();
356     }
357     else
358     {
359       gp_GTrsf aTPers;
360       Graphic3d_Mat4d aMat = theObject->TransformPersistence()->Compute (theCamera, theProjectionMat, theWorldViewMat, theViewportWidth, theViewportHeight);
361
362       aTPers.SetValue (1, 1, aMat.GetValue (0, 0));
363       aTPers.SetValue (1, 2, aMat.GetValue (0, 1));
364       aTPers.SetValue (1, 3, aMat.GetValue (0, 2));
365       aTPers.SetValue (2, 1, aMat.GetValue (1, 0));
366       aTPers.SetValue (2, 2, aMat.GetValue (1, 1));
367       aTPers.SetValue (2, 3, aMat.GetValue (1, 2));
368       aTPers.SetValue (3, 1, aMat.GetValue (2, 0));
369       aTPers.SetValue (3, 2, aMat.GetValue (2, 1));
370       aTPers.SetValue (3, 3, aMat.GetValue (2, 2));
371       aTPers.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3)));
372
373       aInversedTrsf = (aTPers * gp_GTrsf (theObject->Transformation())).Inverted();
374     }
375   }
376
377   SelectMgr_SelectingVolumeManager aMgr = aInversedTrsf.Form() != gp_Identity
378                                         ? theMgr.ScaleAndTransform (1, aInversedTrsf, NULL)
379                                         : theMgr;
380   if (!aMgr.Overlaps (aSensitivesTree->MinPoint (0),
381                       aSensitivesTree->MaxPoint (0)))
382   {
383     return;
384   }
385
386   if (!theObject->ClipPlanes().IsNull()
387     && theObject->ClipPlanes()->ToOverrideGlobal())
388   {
389     aMgr.SetViewClipping (Handle(Graphic3d_SequenceOfHClipPlane)(), theObject->ClipPlanes(), &theMgr);
390   }
391   else if (!theObject->TransformPersistence().IsNull())
392   {
393     if (theObject->TransformPersistence()->IsZoomOrRotate()
394     && !theMgr.ViewClipping().IsNull())
395     {
396       // Zoom/rotate persistence object lives in two worlds at the same time.
397       // Global clipping planes can not be trivially applied without being converted
398       // into local space of transformation persistence object.
399       // As more simple alternative - just clip entire object by its anchor point defined in the world space.
400       const gp_Pnt anAnchor = theObject->TransformPersistence()->AnchorPoint();
401       for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*theMgr.ViewClipping()); aPlaneIt.More(); aPlaneIt.Next())
402       {
403         const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
404         if (!aPlane->IsOn())
405         {
406           continue;
407         }
408
409         const Graphic3d_Vec4d aCheckPnt (anAnchor.X(), anAnchor.Y(), anAnchor.Z(), 1.0);
410         if (aPlane->ProbePoint (aCheckPnt) == Graphic3d_ClipState_Out)
411         {
412           return;
413         }
414       }
415     }
416
417     aMgr.SetViewClipping (Handle(Graphic3d_SequenceOfHClipPlane)(), theObject->ClipPlanes(), &theMgr);
418   }
419   else if (!theObject->ClipPlanes().IsNull()
420         && !theObject->ClipPlanes()->IsEmpty())
421   {
422     aMgr.SetViewClipping (theMgr.ViewClipping(), theObject->ClipPlanes(), &theMgr);
423   }
424
425   if (!theMgr.ViewClipping().IsNull() &&
426       theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Box)
427   {
428     Graphic3d_BndBox3d aBBox (aSensitivesTree->MinPoint (0), aSensitivesTree->MaxPoint (0));
429     // If box selection is active, and the whole sensitive tree is out of the clip planes
430     // selection is empty for this object
431     const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping();
432
433     for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next())
434     {
435       const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
436       if (!aPlane->IsOn())
437       {
438         continue;
439       }
440
441       Graphic3d_ClipState aState = aPlane->ProbeBox (aBBox);
442       if (aState == Graphic3d_ClipState_Out) // do not process only whole trees, next check on the tree node
443       {
444         return;
445       }
446     }
447   }
448
449   const Standard_Integer aFirstStored = mystored.Extent() + 1;
450
451   Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
452   Standard_Integer aHead = -1;
453   Standard_Integer aNode = 0; // a root node
454   SelectMgr_FrustumCache aScaledTrnsfFrustums;
455   SelectMgr_SelectingVolumeManager aTmpMgr (false);
456   for (;;)
457   {
458     if (!aSensitivesTree->IsOuter (aNode))
459     {
460       const Standard_Integer aLeftChildIdx  = aSensitivesTree->Child<0> (aNode);
461       const Standard_Integer aRightChildIdx = aSensitivesTree->Child<1> (aNode);
462       const Standard_Boolean isLeftChildIn  =  aMgr.Overlaps (aSensitivesTree->MinPoint (aLeftChildIdx),
463                                                               aSensitivesTree->MaxPoint (aLeftChildIdx));
464       const Standard_Boolean isRightChildIn = aMgr.Overlaps (aSensitivesTree->MinPoint (aRightChildIdx),
465                                                              aSensitivesTree->MaxPoint (aRightChildIdx));
466       if (isLeftChildIn
467           && isRightChildIn)
468       {
469         aNode = aLeftChildIdx;
470         ++aHead;
471         aStack[aHead] = aRightChildIdx;
472       }
473       else if (isLeftChildIn
474         || isRightChildIn)
475       {
476         aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
477       }
478       else
479       {
480         if (aHead < 0)
481         {
482           break;
483         }
484
485         aNode = aStack[aHead];
486         --aHead;
487       }
488     }
489     else
490     {
491       bool aClipped = false;
492       if (!theMgr.ViewClipping().IsNull() &&
493           theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Box)
494       {
495         Graphic3d_BndBox3d aBBox (aSensitivesTree->MinPoint (aNode), aSensitivesTree->MaxPoint (aNode));
496         // If box selection is active, and the whole sensitive tree is out of the clip planes
497         // selection is empty for this object
498         const Handle(Graphic3d_SequenceOfHClipPlane)& aViewPlanes = theMgr.ViewClipping();
499
500         for (Graphic3d_SequenceOfHClipPlane::Iterator aPlaneIt (*aViewPlanes); aPlaneIt.More(); aPlaneIt.Next())
501         {
502           const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
503           if (!aPlane->IsOn())
504           {
505             continue;
506           }
507           Graphic3d_ClipState aState = aPlane->ProbeBox (aBBox);
508           if (aState == Graphic3d_ClipState_Out)
509           {
510             aClipped = true;
511             break;
512           }
513           if (aState == Graphic3d_ClipState_On && !mySelectingVolumeMgr.IsOverlapAllowed()) // partially clipped
514           {
515             if (aPlane->ProbeBoxTouch (aBBox))
516               continue;
517             aClipped = true;
518             break;
519           }
520         }
521       }
522       if (!aClipped)
523       {
524         Standard_Integer aStartIdx = aSensitivesTree->BegPrimitive (aNode);
525         Standard_Integer anEndIdx = aSensitivesTree->EndPrimitive (aNode);
526         for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
527         {
528           const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
529           if (aSensitive->IsActiveForSelection())
530           {
531             const Handle(Select3D_SensitiveEntity)& anEnt = aSensitive->BaseSensitive();
532             computeFrustum (anEnt, theMgr, aMgr, aInversedTrsf, aScaledTrnsfFrustums, aTmpMgr);
533             checkOverlap (anEnt, aInversedTrsf, aTmpMgr);
534           }
535         }
536       }
537       if (aHead < 0)
538       {
539         break;
540       }
541
542       aNode = aStack[aHead];
543       --aHead;
544     }
545   }
546
547   // in case of Box/Polyline selection - keep only Owners having all Entities detected
548   if (mySelectingVolumeMgr.IsOverlapAllowed()
549   || (theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Box
550    && theMgr.GetActiveSelectionType() != SelectBasics_SelectingVolumeManager::Polyline))
551   {
552     return;
553   }
554
555   for (Standard_Integer aStoredIter = mystored.Extent(); aStoredIter >= aFirstStored; --aStoredIter)
556   {
557     const SelectMgr_SortCriterion& aCriterion = mystored.FindFromIndex (aStoredIter);
558     const Handle(SelectMgr_EntityOwner)& anOwner = aCriterion.Entity->OwnerId();
559     Standard_Integer aNbOwnerEntities = 0;
560     for (SelectMgr_IndexedMapOfHSensitive::Iterator aSensIter (anEntitySet->Sensitives()); aSensIter.More(); aSensIter.Next())
561     {
562       if (aSensIter.Value()->BaseSensitive()->OwnerId() == anOwner)
563       {
564         if (++aNbOwnerEntities > aCriterion.NbOwnerMatches)
565         {
566           // Remove from index map.
567           // Considering NCollection_IndexedDataMap implementation, the values for lower indexes will not be modified.
568           // Hence, just keep iterating in backward direction.
569           mystored.RemoveFromIndex (aStoredIter);
570           break;
571         }
572       }
573     }
574   }
575 }
576
577 //=======================================================================
578 // function: TraverseSensitives
579 // purpose : Traverses BVH containing all added selectable objects and
580 //           finds candidates for further search of overlap
581 //=======================================================================
582 void SelectMgr_ViewerSelector::TraverseSensitives()
583 {
584   mystored.Clear();
585
586   Standard_Integer aWidth;
587   Standard_Integer aHeight;
588   mySelectingVolumeMgr.WindowSize (aWidth, aHeight);
589   mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(),
590                                  mySelectingVolumeMgr.ProjectionMatrix(),
591                                  mySelectingVolumeMgr.WorldViewMatrix(),
592                                  mySelectingVolumeMgr.WorldViewProjState(),
593                                  aWidth, aHeight);
594   const Handle(Graphic3d_Camera)& aCamera = mySelectingVolumeMgr.Camera();
595   if (!aCamera.IsNull())
596   {
597     myCameraEye = aCamera->Eye().XYZ();
598     myCameraDir = aCamera->Direction().XYZ();
599     myCameraScale = aCamera->IsOrthographic()
600                   ? aCamera->Scale()
601                   : 2.0 * Tan (aCamera->FOVy() * M_PI / 360.0);
602     const double aPixelSize = Max (1.0 / aWidth, 1.0 / aHeight);
603     myCameraScale *= aPixelSize;
604   }
605
606   for (Standard_Integer aBVHSetIt = 0; aBVHSetIt < SelectMgr_SelectableObjectSet::BVHSubsetNb; ++aBVHSetIt)
607   {
608     SelectMgr_SelectableObjectSet::BVHSubset aBVHSubset =
609       static_cast<SelectMgr_SelectableObjectSet::BVHSubset> (aBVHSetIt);
610
611     if (mySelectableObjects.IsEmpty (aBVHSubset))
612     {
613       continue;
614     }
615
616     gp_GTrsf aTFrustum;
617
618     SelectMgr_SelectingVolumeManager aMgr (Standard_False);
619
620     // for 2D space selection transform selecting volumes to perform overap testing
621     // directly in camera's eye space omitting the camera position, which is not
622     // needed there at all
623     if (aBVHSubset == SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent)
624     {
625       const Graphic3d_Mat4d& aMat = mySelectingVolumeMgr.WorldViewMatrix();
626       aTFrustum.SetValue (1, 1, aMat.GetValue (0, 0));
627       aTFrustum.SetValue (1, 2, aMat.GetValue (0, 1));
628       aTFrustum.SetValue (1, 3, aMat.GetValue (0, 2));
629       aTFrustum.SetValue (2, 1, aMat.GetValue (1, 0));
630       aTFrustum.SetValue (2, 2, aMat.GetValue (1, 1));
631       aTFrustum.SetValue (2, 3, aMat.GetValue (1, 2));
632       aTFrustum.SetValue (3, 1, aMat.GetValue (2, 0));
633       aTFrustum.SetValue (3, 2, aMat.GetValue (2, 1));
634       aTFrustum.SetValue (3, 3, aMat.GetValue (2, 2));
635       aTFrustum.SetTranslationPart (gp_XYZ (aMat.GetValue (0, 3), aMat.GetValue (1, 3), aMat.GetValue (2, 3)));
636
637       // define corresponding frustum builder parameters
638       Handle(SelectMgr_FrustumBuilder) aBuilder = new SelectMgr_FrustumBuilder();
639       aBuilder->SetProjectionMatrix (mySelectingVolumeMgr.ProjectionMatrix());
640       aBuilder->SetWorldViewMatrix (SelectMgr_ViewerSelector_THE_IDENTITY_MAT);
641       aBuilder->SetWindowSize (aWidth, aHeight);
642       aMgr = mySelectingVolumeMgr.ScaleAndTransform (1, aTFrustum, aBuilder);
643     }
644     else
645     {
646       aMgr = mySelectingVolumeMgr;
647     }
648
649     const Graphic3d_Mat4d& aProjectionMat   = mySelectingVolumeMgr.ProjectionMatrix();
650     const Graphic3d_Mat4d& aWorldViewMat    = aBVHSubset != SelectMgr_SelectableObjectSet::BVHSubset_2dPersistent
651                                             ? mySelectingVolumeMgr.WorldViewMatrix()
652                                             : SelectMgr_ViewerSelector_THE_IDENTITY_MAT;
653
654     const opencascade::handle<BVH_Tree<Standard_Real, 3> >& aBVHTree = mySelectableObjects.BVH (aBVHSubset);
655
656     Standard_Integer aNode = 0;
657     if (!aMgr.Overlaps (aBVHTree->MinPoint (0), aBVHTree->MaxPoint (0)))
658     {
659       continue;
660     }
661
662     Standard_Integer aStack[BVH_Constants_MaxTreeDepth];
663     Standard_Integer aHead = -1;
664     for (;;)
665     {
666       if (!aBVHTree->IsOuter (aNode))
667       {
668         const Standard_Integer aLeftChildIdx  = aBVHTree->Child<0> (aNode);
669         const Standard_Integer aRightChildIdx = aBVHTree->Child<1> (aNode);
670         const Standard_Boolean isLeftChildIn  =
671           aMgr.Overlaps (aBVHTree->MinPoint (aLeftChildIdx), aBVHTree->MaxPoint (aLeftChildIdx));
672         const Standard_Boolean isRightChildIn =
673           aMgr.Overlaps (aBVHTree->MinPoint (aRightChildIdx), aBVHTree->MaxPoint (aRightChildIdx));
674         if (isLeftChildIn
675           && isRightChildIn)
676         {
677           aNode = aLeftChildIdx;
678           ++aHead;
679           aStack[aHead] = aRightChildIdx;
680         }
681         else if (isLeftChildIn
682           || isRightChildIn)
683         {
684           aNode = isLeftChildIn ? aLeftChildIdx : aRightChildIdx;
685         }
686         else
687         {
688           if (aHead < 0)
689           {
690             break;
691           }
692
693           aNode = aStack[aHead];
694           --aHead;
695         }
696       }
697       else
698       {
699         Standard_Integer aStartIdx = aBVHTree->BegPrimitive (aNode);
700         Standard_Integer anEndIdx  = aBVHTree->EndPrimitive (aNode);
701         for (Standard_Integer anIdx = aStartIdx; anIdx <= anEndIdx; ++anIdx)
702         {
703           const Handle(SelectMgr_SelectableObject)& aSelectableObject =
704             mySelectableObjects.GetObjectById (aBVHSubset, anIdx);
705
706           traverseObject (aSelectableObject, aMgr, aCamera, aProjectionMat, aWorldViewMat, aWidth, aHeight);
707         }
708         if (aHead < 0)
709         {
710           break;
711         }
712
713         aNode = aStack[aHead];
714         --aHead;
715       }
716     }
717   }
718
719   SortResult();
720 }
721
722 //==================================================
723 // Function: ClearPicked
724 // Purpose :
725 //==================================================
726 void SelectMgr_ViewerSelector::ClearPicked()
727 {
728   mystored.Clear();
729 }
730
731 //==================================================
732 // Function: Picked
733 // Purpose :
734 //==================================================
735 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked() const
736 {
737   const Standard_Integer aRankInMap = myIndexes->Value (myCurRank);
738   const Handle(SelectMgr_EntityOwner)& anOwner = mystored.FindKey (aRankInMap);
739   return anOwner;
740 }
741
742 //=======================================================================
743 //function : Picked
744 //purpose  :
745 //=======================================================================
746 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked (const Standard_Integer theRank) const
747 {
748   if (theRank < 1 || theRank > NbPicked())
749   {
750     return Handle(SelectMgr_EntityOwner)();
751   }
752
753   const Standard_Integer anOwnerIdx = myIndexes->Value (theRank);
754   const Handle(SelectMgr_EntityOwner)& aStoredOwner = mystored.FindKey (anOwnerIdx);
755   return aStoredOwner;
756 }
757
758 //=======================================================================
759 //function : PickedData
760 //purpose  :
761 //=======================================================================
762 const SelectMgr_SortCriterion& SelectMgr_ViewerSelector::PickedData(const Standard_Integer theRank) const
763 {
764   Standard_OutOfRange_Raise_if (theRank < 1 || theRank > NbPicked(), "SelectMgr_ViewerSelector::PickedData() out of range index");
765   const Standard_Integer anOwnerIdx = myIndexes->Value (theRank);
766   return mystored.FindFromIndex (anOwnerIdx);
767 }
768
769 //===================================================
770 //
771 //       INTERNAL METHODS ....
772 //
773 //==================================================
774
775 //==================================================
776 // Function: SetEntitySetBuilder
777 // Purpose :
778 //==================================================
779 void SelectMgr_ViewerSelector::SetEntitySetBuilder (const Handle(Select3D_BVHBuilder3d)& theBuilder)
780 {
781   myEntitySetBuilder = theBuilder;
782   for (SelectMgr_MapOfObjectSensitives::Iterator aSetIter (myMapOfObjectSensitives); aSetIter.More(); aSetIter.Next())
783   {
784     aSetIter.ChangeValue()->SetBuilder (myEntitySetBuilder);
785   }
786 }
787
788 //==================================================
789 // Function: Contains
790 // Purpose :
791 //==================================================
792 Standard_Boolean SelectMgr_ViewerSelector::Contains (const Handle(SelectMgr_SelectableObject)& theObject) const
793 {
794   return mySelectableObjects.Contains (theObject);
795 }
796
797 //==================================================
798 // Function: ActiveModes
799 // Purpose : return all the  modes with a given state for an object
800 //==================================================
801 Standard_Boolean SelectMgr_ViewerSelector::Modes (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
802                                                   TColStd_ListOfInteger& theModeList,
803                                                   const SelectMgr_StateOfSelection theWantedState) const
804 {
805   Standard_Boolean hasActivatedStates = Contains (theSelectableObject);
806   for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theSelectableObject->Selections()); aSelIter.More(); aSelIter.Next())
807   {
808     if (theWantedState == SelectMgr_SOS_Any)
809     {
810       theModeList.Append (aSelIter.Value()->Mode());
811     }
812     else if (theWantedState == aSelIter.Value()->GetSelectionState())
813     {
814       theModeList.Append (aSelIter.Value()->Mode());
815     }
816   }
817
818   return hasActivatedStates;
819 }
820
821 //==================================================
822 // Function: IsActive
823 // Purpose :
824 //==================================================
825 Standard_Boolean SelectMgr_ViewerSelector::IsActive (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
826                                                      const Standard_Integer theMode) const
827 {
828   if (!Contains (theSelectableObject))
829     return Standard_False;
830
831   const Handle(SelectMgr_Selection)& aSel = theSelectableObject->Selection (theMode);
832   return !aSel.IsNull()
833        && aSel->GetSelectionState() == SelectMgr_SOS_Activated;
834 }
835
836 //==================================================
837 // Function: IsInside
838 // Purpose :
839 //==================================================
840 Standard_Boolean SelectMgr_ViewerSelector::IsInside (const Handle(SelectMgr_SelectableObject)& theSelectableObject,
841                                                      const Standard_Integer theMode) const
842 {
843   if (!Contains (theSelectableObject))
844     return Standard_False;
845
846   const Handle(SelectMgr_Selection)& aSel = theSelectableObject->Selection (theMode);
847   return !aSel.IsNull()
848        && aSel->GetSelectionState() != SelectMgr_SOS_Unknown;
849 }
850
851
852 //=======================================================================
853 //function : Status
854 //purpose  :
855 //=======================================================================
856
857 SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_Selection)& theSelection) const
858 {
859   return theSelection->GetSelectionState();
860 }
861
862 //==================================================
863 // Function: Status
864 // Purpose : gives Information about selectors
865 //==================================================
866
867 TCollection_AsciiString SelectMgr_ViewerSelector::Status (const Handle(SelectMgr_SelectableObject)& theSelectableObject) const
868 {
869   TCollection_AsciiString aStatus ("Status Object :\n\t");
870   for (SelectMgr_SequenceOfSelection::Iterator aSelIter (theSelectableObject->Selections()); aSelIter.More(); aSelIter.Next())
871   {
872     if (aSelIter.Value()->GetSelectionState() != SelectMgr_SOS_Unknown)
873     {
874       aStatus = aStatus + "Mode " + TCollection_AsciiString (aSelIter.Value()->Mode()) + " present - "
875               + (aSelIter.Value()->GetSelectionState() == SelectMgr_SOS_Activated ? " Active \n\t" : " Inactive \n\t");
876     }
877   }
878
879   if (!Contains (theSelectableObject))
880   {
881     aStatus = aStatus + "Not Present in the selector\n\n";
882   }
883
884   return aStatus;
885 }
886
887 //=======================================================================
888 //function : SortResult
889 //purpose  :  there is a certain number of entities ranged by criteria
890 //            (depth, size, priority, mouse distance from borders or
891 //            CDG of the detected primitive. Parsing :
892 //             maximum priorities .
893 //             then a reasonable compromise between depth and distance...
894 // finally the ranges are stored in myindexes depending on the parsing.
895 // so, it is possible to only read
896 //=======================================================================
897 void SelectMgr_ViewerSelector::SortResult()
898 {
899   if(mystored.IsEmpty()) return;
900
901   const Standard_Integer anExtent = mystored.Extent();
902   if(myIndexes.IsNull() || anExtent != myIndexes->Length())
903     myIndexes = new TColStd_HArray1OfInteger (1, anExtent);
904
905   TColStd_Array1OfInteger& anIndexArray = myIndexes->ChangeArray1();
906   for (Standard_Integer anIndexIter = 1; anIndexIter <= anExtent; ++anIndexIter)
907   {
908     anIndexArray.SetValue (anIndexIter, anIndexIter);
909   }
910   std::sort (anIndexArray.begin(), anIndexArray.end(), CompareResults (mystored));
911 }
912
913 //=======================================================================
914 // function : AddSelectableObject
915 // purpose  : Adds new object to the map of selectable objects
916 //=======================================================================
917 void SelectMgr_ViewerSelector::AddSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
918 {
919   if (!myMapOfObjectSensitives.IsBound (theObject))
920   {
921     mySelectableObjects.Append (theObject);
922     Handle(SelectMgr_SensitiveEntitySet) anEntitySet = new SelectMgr_SensitiveEntitySet (myEntitySetBuilder);
923     myMapOfObjectSensitives.Bind (theObject, anEntitySet);
924   }
925 }
926
927 //=======================================================================
928 // function : AddSelectionToObject
929 // purpose  : Adds new selection to the object and builds its BVH tree
930 //=======================================================================
931 void SelectMgr_ViewerSelector::AddSelectionToObject (const Handle(SelectMgr_SelectableObject)& theObject,
932                                                      const Handle(SelectMgr_Selection)& theSelection)
933 {
934   if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject))
935   {
936     (*anEntitySet)->Append (theSelection);
937     (*anEntitySet)->BVH();
938   }
939   else
940   {
941     AddSelectableObject (theObject);
942     AddSelectionToObject (theObject, theSelection);
943   }
944 }
945
946 //=======================================================================
947 // function : MoveSelectableObject
948 // purpose  :
949 //=======================================================================
950 void SelectMgr_ViewerSelector::MoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
951 {
952   mySelectableObjects.ChangeSubset (theObject);
953 }
954
955 //=======================================================================
956 // function : RemoveSelectableObject
957 // purpose  : Removes selectable object from map of selectable ones
958 //=======================================================================
959 void SelectMgr_ViewerSelector::RemoveSelectableObject (const Handle(SelectMgr_SelectableObject)& theObject)
960 {
961   Handle(SelectMgr_SelectableObject) anObj = theObject;
962   if (myMapOfObjectSensitives.UnBind (theObject))
963   {
964     mySelectableObjects.Remove (theObject);
965   }
966 }
967
968 //=======================================================================
969 // function : RemoveSelectionOfObject
970 // purpose  : Removes selection of the object and marks its BVH tree
971 //            for rebuild
972 //=======================================================================
973 void SelectMgr_ViewerSelector::RemoveSelectionOfObject (const Handle(SelectMgr_SelectableObject)& theObject,
974                                                         const Handle(SelectMgr_Selection)& theSelection)
975 {
976   if (Handle(SelectMgr_SensitiveEntitySet)* anEntitySet = myMapOfObjectSensitives.ChangeSeek (theObject))
977   {
978     (*anEntitySet)->Remove (theSelection);
979   }
980 }
981
982 //=======================================================================
983 // function : RebuildObjectsTree
984 // purpose  : Marks BVH of selectable objects for rebuild
985 //=======================================================================
986 void SelectMgr_ViewerSelector::RebuildObjectsTree (const Standard_Boolean theIsForce)
987 {
988   mySelectableObjects.MarkDirty();
989
990   if (theIsForce)
991   {
992     Standard_Integer aViewportWidth, aViewportHeight;
993     mySelectingVolumeMgr.WindowSize (aViewportWidth, aViewportHeight);
994
995     Standard_Integer aWidth;
996     Standard_Integer aHeight;
997     mySelectingVolumeMgr.WindowSize (aWidth, aHeight);
998     mySelectableObjects.UpdateBVH (mySelectingVolumeMgr.Camera(),
999                                    mySelectingVolumeMgr.ProjectionMatrix(),
1000                                    mySelectingVolumeMgr.WorldViewMatrix(),
1001                                    mySelectingVolumeMgr.WorldViewProjState(),
1002                                    aWidth, aHeight);
1003   }
1004 }
1005
1006 //=======================================================================
1007 // function : RebuildSensitivesTree
1008 // purpose  : Marks BVH of sensitive entities of particular selectable
1009 //            object for rebuild
1010 //=======================================================================
1011 void SelectMgr_ViewerSelector::RebuildSensitivesTree (const Handle(SelectMgr_SelectableObject)& theObject,
1012                                                       const Standard_Boolean theIsForce)
1013 {
1014   if (!Contains (theObject))
1015     return;
1016
1017   Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = myMapOfObjectSensitives.ChangeFind (theObject);
1018   anEntitySet->MarkDirty();
1019
1020   if (theIsForce)
1021   {
1022     anEntitySet->BVH();
1023   }
1024 }
1025
1026 //=======================================================================
1027 // function : resetSelectionActivationStatus
1028 // purpose  : Marks all added sensitive entities of all objects as
1029 //            non-selectable
1030 //=======================================================================
1031 void SelectMgr_ViewerSelector::ResetSelectionActivationStatus()
1032 {
1033   for (SelectMgr_MapOfObjectSensitivesIterator aSensitivesIter (myMapOfObjectSensitives); aSensitivesIter.More(); aSensitivesIter.Next())
1034   {
1035     Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = aSensitivesIter.ChangeValue();
1036     const Standard_Integer anEntitiesNb = anEntitySet->Size();
1037     for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
1038     {
1039       anEntitySet->GetSensitiveById (anIdx)->ResetSelectionActiveStatus();
1040     }
1041   }
1042 }
1043
1044 //=======================================================================
1045 // function : DetectedEntity
1046 // purpose  : Returns sensitive entity that was detected during the
1047 //            previous run of selection algorithm
1048 //=======================================================================
1049 const Handle(Select3D_SensitiveEntity)& SelectMgr_ViewerSelector::DetectedEntity() const
1050 {
1051   const Standard_Integer aRankInMap = myIndexes->Value(myCurRank);
1052   return mystored.FindFromIndex (aRankInMap).Entity;
1053 }
1054
1055 //=======================================================================
1056 // function : ActiveOwners
1057 // purpose  : Returns the list of active entity owners
1058 //=======================================================================
1059 void SelectMgr_ViewerSelector::ActiveOwners (NCollection_List<Handle(SelectMgr_EntityOwner)>& theOwners) const
1060 {
1061   for (SelectMgr_MapOfObjectSensitivesIterator anIter (myMapOfObjectSensitives); anIter.More(); anIter.Next())
1062   {
1063     const Handle(SelectMgr_SensitiveEntitySet)& anEntitySet = anIter.Value();
1064     const Standard_Integer anEntitiesNb = anEntitySet->Size();
1065     for (Standard_Integer anIdx = 0; anIdx < anEntitiesNb; ++anIdx)
1066     {
1067       const Handle(SelectMgr_SensitiveEntity)& aSensitive = anEntitySet->GetSensitiveById (anIdx);
1068       if (aSensitive->IsActiveForSelection())
1069       {
1070         theOwners.Append (aSensitive->BaseSensitive()->OwnerId());
1071       }
1072     }
1073   }
1074 }
1075
1076 //=======================================================================
1077 //function : AllowOverlapDetection
1078 //purpose  : Sets the detection type: if theIsToAllow is false,
1079 //           only fully included sensitives will be detected, otherwise
1080 //           the algorithm will mark both included and overlapped entities
1081 //           as matched
1082 //=======================================================================
1083 void SelectMgr_ViewerSelector::AllowOverlapDetection (const Standard_Boolean theIsToAllow)
1084 {
1085   mySelectingVolumeMgr.AllowOverlapDetection (theIsToAllow);
1086 }
1087
1088 //=======================================================================
1089 //function : DumpJson
1090 //purpose  : 
1091 //=======================================================================
1092 void SelectMgr_ViewerSelector::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const 
1093 {
1094   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
1095
1096   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, preferclosest)
1097   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myToUpdateTolerance)
1098   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, mystored.Extent())
1099
1100   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, &mySelectingVolumeMgr)
1101   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, &mySelectableObjects)
1102
1103   Standard_Integer aNbOfSelectableObjects = 0;
1104   for (SelectMgr_SelectableObjectSet::Iterator aSelectableIt (mySelectableObjects); aSelectableIt.More(); aSelectableIt.Next())
1105   {
1106     aNbOfSelectableObjects++;
1107   }
1108   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, aNbOfSelectableObjects)
1109
1110   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myTolerances.Tolerance())
1111   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myTolerances.CustomTolerance())
1112   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myZLayerOrderMap.Extent())
1113
1114   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myEntitySetBuilder.get())
1115   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCameraEye)
1116   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myCameraDir)
1117   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myCameraScale)
1118
1119   if (!myIndexes.IsNull())
1120     OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIndexes->Size())
1121
1122   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myCurRank)
1123   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsLeftChildQueuedFirst)
1124   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myEntityIdx)
1125   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myMapOfObjectSensitives.Extent())
1126 }