0029938: Visualization - SelectMgr_ViewerSelector::PickedPoint() should return point...
[occt.git] / src / MeshVS / MeshVS_Mesh.cxx
1 // Created on: 2003-09-09
2 // Created by: Alexander SOLOVYOV
3 // Copyright (c) 2003-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <AIS_InteractiveContext.hxx>
18 #include <Aspect_InteriorStyle.hxx>
19 #include <Bnd_Box.hxx>
20 #include <gp_Pnt.hxx>
21 #include <Graphic3d_AspectFillArea3d.hxx>
22 #include <Graphic3d_MaterialAspect.hxx>
23 #include <Graphic3d_NameOfMaterial.hxx>
24 #include <MeshVS_Buffer.hxx>
25 #include <MeshVS_CommonSensitiveEntity.hxx>
26 #include <MeshVS_DataMapIteratorOfDataMapOfIntegerOwner.hxx>
27 #include <MeshVS_DataSource.hxx>
28 #include <MeshVS_Drawer.hxx>
29 #include <MeshVS_DrawerAttribute.hxx>
30 #include <MeshVS_DummySensitiveEntity.hxx>
31 #include <MeshVS_Mesh.hxx>
32 #include <MeshVS_MeshEntityOwner.hxx>
33 #include <MeshVS_MeshOwner.hxx>
34 #include <MeshVS_PrsBuilder.hxx>
35 #include <MeshVS_SelectionModeFlags.hxx>
36 #include <MeshVS_SensitiveFace.hxx>
37 #include <MeshVS_SensitiveMesh.hxx>
38 #include <MeshVS_SensitivePolyhedron.hxx>
39 #include <MeshVS_SensitiveSegment.hxx>
40 #include <MeshVS_SensitiveQuad.hxx>
41 #include <OSD_Timer.hxx>
42 #include <Prs3d_LineAspect.hxx>
43 #include <Prs3d_PointAspect.hxx>
44 #include <Prs3d_Presentation.hxx>
45 #include <Prs3d_Root.hxx>
46 #include <Prs3d_ShadingAspect.hxx>
47 #include <PrsMgr_ModedPresentation.hxx>
48 #include <PrsMgr_PresentationManager3d.hxx>
49 #include <Select3D_SensitiveBox.hxx>
50 #include <Select3D_SensitiveGroup.hxx>
51 #include <Select3D_SensitivePoint.hxx>
52 #include <Select3D_SensitiveTriangle.hxx>
53 #include <SelectBasics_SensitiveEntity.hxx>
54 #include <SelectMgr_EntityOwner.hxx>
55 #include <SelectMgr_Selection.hxx>
56 #include <SelectMgr_SequenceOfOwner.hxx>
57 #include <Standard_Type.hxx>
58 #include <StdSelect_BRepSelectionTool.hxx>
59 #include <TColgp_Array1OfPnt.hxx>
60 #include <TColStd_Array1OfInteger.hxx>
61 #include <TColStd_Array1OfReal.hxx>
62 #include <TColStd_HPackedMapOfInteger.hxx>
63 #include <TColStd_ListIteratorOfListOfInteger.hxx>
64 #include <TColStd_ListIteratorOfListOfReal.hxx>
65 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
66 #include <TColStd_SequenceOfInteger.hxx>
67
68 IMPLEMENT_STANDARD_RTTIEXT(MeshVS_Mesh,AIS_InteractiveObject)
69
70 //================================================================
71 // Function : Constructor MeshVS_Mesh
72 // Purpose  :
73 //================================================================
74 MeshVS_Mesh::MeshVS_Mesh (const Standard_Boolean theIsAllowOverlapped )
75 {
76   myDataSource.Nullify();
77   myHilighter.Nullify();
78   myWholeMeshOwner.Nullify();
79   mySelectionMethod = MeshVS_MSM_NODES;
80
81   SetAutoHilight ( Standard_False );
82
83   SetDisplayMode( MeshVS_DMF_WireFrame ); // Mode as defaut
84   SetHilightMode( MeshVS_DMF_WireFrame ); // Wireframe as default hilight mode
85
86   SetColor ( Quantity_NOC_WHITE );
87   SetMaterial ( Graphic3d_NOM_PLASTIC );
88
89   myCurrentDrawer = new MeshVS_Drawer();
90   myCurrentDrawer->SetColor   ( MeshVS_DA_InteriorColor, Quantity_NOC_BLUE4 );
91   myCurrentDrawer->SetInteger ( MeshVS_DA_InteriorStyle, Aspect_IS_SOLID );
92   myCurrentDrawer->SetInteger ( MeshVS_DA_MaxFaceNodes, 10 );
93   myCurrentDrawer->SetBoolean ( MeshVS_DA_IsAllowOverlapped, theIsAllowOverlapped );
94   myCurrentDrawer->SetBoolean ( MeshVS_DA_Reflection, Standard_True );
95   myCurrentDrawer->SetDouble  ( MeshVS_DA_ShrinkCoeff, 0.8 );
96   myCurrentDrawer->SetBoolean ( MeshVS_DA_ComputeTime, Standard_False );
97   myCurrentDrawer->SetBoolean ( MeshVS_DA_ComputeSelectionTime, Standard_False );
98   myCurrentDrawer->SetBoolean ( MeshVS_DA_DisplayNodes, Standard_True );
99   myCurrentDrawer->SetDouble  ( MeshVS_DA_EdgeWidth, 1.0 );
100   myCurrentDrawer->SetInteger ( MeshVS_DA_EdgeType, Aspect_TOL_SOLID );
101   myCurrentDrawer->SetInteger ( MeshVS_DA_MarkerType,  Aspect_TOM_O );
102   myCurrentDrawer->SetColor   ( MeshVS_DA_MarkerColor, Quantity_NOC_WHITE );
103   myCurrentDrawer->SetDouble  ( MeshVS_DA_MarkerScale, 1.0 );
104   myCurrentDrawer->SetInteger ( MeshVS_DA_BeamType, Aspect_TOL_SOLID );
105   myCurrentDrawer->SetDouble  ( MeshVS_DA_BeamWidth, 1.0 );
106   myCurrentDrawer->SetBoolean ( MeshVS_DA_SmoothShading, Standard_False );
107   myCurrentDrawer->SetBoolean ( MeshVS_DA_SupressBackFaces, Standard_False );
108
109   mySelectionDrawer = new MeshVS_Drawer();
110   mySelectionDrawer->Assign ( myCurrentDrawer );
111   mySelectionDrawer->SetInteger ( MeshVS_DA_MarkerType,  Aspect_TOM_STAR );
112   mySelectionDrawer->SetColor   ( MeshVS_DA_MarkerColor, Quantity_NOC_GRAY80 );
113   mySelectionDrawer->SetDouble  ( MeshVS_DA_MarkerScale, 2.0 );
114
115   mySelectionDrawer->SetColor   ( MeshVS_DA_BeamColor, Quantity_NOC_GRAY80 );
116   mySelectionDrawer->SetInteger ( MeshVS_DA_BeamType,  Aspect_TOL_SOLID );
117   mySelectionDrawer->SetDouble  ( MeshVS_DA_BeamWidth, 3.0 );
118
119   myHilightDrawer = new MeshVS_Drawer ();
120   myHilightDrawer->Assign ( myCurrentDrawer );
121   myHilightDrawer->SetDouble   ( MeshVS_DA_ShrinkCoeff, 0.7 );
122   myHilightDrawer->SetInteger  ( MeshVS_DA_InteriorStyle, Aspect_IS_SOLID );
123   myHilightDrawer->SetColor    ( MeshVS_DA_InteriorColor, Quantity_NOC_YELLOW );
124   myHilightDrawer->SetColor    ( MeshVS_DA_BackInteriorColor, Quantity_NOC_YELLOW );
125   myHilightDrawer->SetColor    ( MeshVS_DA_EdgeColor, Quantity_NOC_GREEN );
126   myHilightDrawer->SetInteger  ( MeshVS_DA_EdgeType, Aspect_TOL_SOLID );
127   myHilightDrawer->SetDouble   ( MeshVS_DA_EdgeWidth, 1.0 );
128   myHilightDrawer->SetMaterial ( MeshVS_DA_FrontMaterial, Graphic3d_NOM_PLASTIC );
129   myHilightDrawer->SetMaterial ( MeshVS_DA_BackMaterial, Graphic3d_NOM_PLASTIC );
130
131   myHilightDrawer->SetColor   ( MeshVS_DA_BeamColor, Quantity_NOC_GRAY80 );
132   myHilightDrawer->SetInteger ( MeshVS_DA_BeamType,  Aspect_TOL_SOLID );
133   myHilightDrawer->SetDouble  ( MeshVS_DA_BeamWidth, 3.0 );
134
135   myHilightDrawer->SetInteger ( MeshVS_DA_MarkerType,  Aspect_TOM_STAR );
136   myHilightDrawer->SetColor   ( MeshVS_DA_MarkerColor, Quantity_NOC_GRAY80 );
137   myHilightDrawer->SetDouble  ( MeshVS_DA_MarkerScale, 2.0 );
138 }
139
140 //================================================================
141 // Function : AcceptDisplayMode
142 // Purpose  :
143 //================================================================
144 Standard_Boolean MeshVS_Mesh::AcceptDisplayMode (const Standard_Integer theMode) const
145 {
146   if (theMode <= 0)
147   {
148     return Standard_False;
149   }
150   else if (myBuilders.IsEmpty())
151   {
152     return Standard_True;
153   }
154
155   for (MeshVS_SequenceOfPrsBuilder::Iterator aBuilderIter (myBuilders); aBuilderIter.More(); aBuilderIter.Next())
156   {
157     Handle(MeshVS_PrsBuilder) aBuilder = aBuilderIter.Value();
158     if (!aBuilder.IsNull()
159       && aBuilder->TestFlags (theMode))
160     {
161       return Standard_True;
162     }
163   }
164   return Standard_False;
165 }
166
167 //================================================================
168 // Function : Compute
169 // Purpose  :
170 //================================================================
171 void MeshVS_Mesh::Compute ( const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
172                             const Handle(Prs3d_Presentation)& thePresentation,
173                             const Standard_Integer theMode )
174 {
175   Standard_Boolean toShowComputeTime = Standard_True;
176   myCurrentDrawer->GetBoolean (MeshVS_DA_ComputeTime, toShowComputeTime);
177   OSD_Timer aTimer;
178   if (toShowComputeTime)
179   {
180     aTimer.Reset();
181     aTimer.Start();
182   }
183
184   // Repair Ids in map if necessary
185   Handle( MeshVS_DataSource ) aDS = GetDataSource();
186   if (aDS.IsNull()
187    || theMode <= 0)
188   {
189     return;
190   }
191
192   const TColStd_PackedMapOfInteger& aNodes = aDS->GetAllNodes();
193   const TColStd_PackedMapOfInteger& aElems = aDS->GetAllElements();
194   const Standard_Boolean hasNodes    = !aNodes.IsEmpty();
195   const Standard_Boolean hasElements = !aElems.IsEmpty();
196
197   TColStd_PackedMapOfInteger aNodesToExclude, aElemsToExclude;
198   for (MeshVS_SequenceOfPrsBuilder::Iterator aBuilderIter (myBuilders); aBuilderIter.More(); aBuilderIter.Next())
199   {
200     const Handle(MeshVS_PrsBuilder)& aBuilder = aBuilderIter.Value();
201     if (!aBuilder.IsNull()
202       && aBuilder->TestFlags (theMode))
203     {
204       aBuilder->SetPresentationManager (thePrsMgr);
205       if (hasNodes)
206       {
207         aBuilder->Build (thePresentation, aNodes, aNodesToExclude, Standard_False, theMode);
208       }
209       if (hasElements)
210       {
211         aBuilder->Build (thePresentation, aElems, aElemsToExclude, Standard_True,  theMode);
212       }
213     }
214   }
215
216   if (toShowComputeTime)
217   {
218     Standard_Real aSec, aCpu;
219     Standard_Integer aMin, anHour;
220     aTimer.Show (aSec, aMin, anHour, aCpu);
221     std::cout << "DisplayMode : " << theMode << "\n";
222     std::cout << "Compute : " << aSec << " sec\n";
223     std::cout << "Compute CPU : " << aCpu << " sec\n\n";
224   }
225 }
226
227 //================================================================
228 // Function : scanFacesForSharedNodes
229 // Purpose  :
230 //================================================================
231 void MeshVS_Mesh::scanFacesForSharedNodes (const TColStd_PackedMapOfInteger& theAllElements,
232                                            const Standard_Integer theNbMaxFaceNodes,
233                                            TColStd_PackedMapOfInteger& theSharedNodes) const
234 {
235   theSharedNodes.Clear();
236   MeshVS_EntityType aType;
237   Standard_Integer aNbNodes;
238   MeshVS_Buffer aCoordsBuf (3 * theNbMaxFaceNodes * sizeof (Standard_Real));
239   TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * theNbMaxFaceNodes);
240   for (TColStd_MapIteratorOfPackedMapOfInteger aFaceIter (theAllElements); aFaceIter.More(); aFaceIter.Next())
241   {
242     const Standard_Integer aFaceIdx = aFaceIter.Key();
243
244     if (IsSelectableElem (aFaceIdx) &&
245       myDataSource->GetGeomType (aFaceIdx, Standard_True, aType) &&
246       aType == MeshVS_ET_Face)
247     {
248       myDataSource->GetGeom (aFaceIdx, Standard_True, aCoords, aNbNodes, aType );
249       if (aNbNodes == 0)
250         continue;
251
252       MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
253       TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
254       if (!myDataSource->GetNodesByElement (aFaceIdx, aElemNodes, aNbNodes))
255         continue;
256
257       MeshVS_Buffer aFacePntsBuf (aNbNodes * 3 * sizeof (Standard_Real));
258       TColgp_Array1OfPnt aFacePnts (aFacePntsBuf, 1, aNbNodes);
259       for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; ++aNodeIdx)
260       {
261         theSharedNodes.Add (aElemNodes (aNodeIdx));
262       }
263     }
264   }
265 }
266
267 //================================================================
268 // Function : ComputeSelection
269 // Purpose  :
270 //================================================================
271 void MeshVS_Mesh::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
272                                     const Standard_Integer theMode)
273 {
274   OSD_Timer gTimer;
275   Standard_Boolean toShowComputeSelectionTime = Standard_True;
276   myCurrentDrawer->GetBoolean( MeshVS_DA_ComputeSelectionTime, toShowComputeSelectionTime);
277   if (toShowComputeSelectionTime)
278   {
279     gTimer.Reset();
280     gTimer.Start();
281   }
282
283   Standard_Integer aMaxFaceNodes = 0;
284   Handle(MeshVS_DataSource) aSource = GetDataSource();
285   if (aSource.IsNull()
286   ||  myCurrentDrawer.IsNull()
287   || !myCurrentDrawer->GetInteger (MeshVS_DA_MaxFaceNodes, aMaxFaceNodes)
288   ||  aMaxFaceNodes <= 0)
289   {
290     return;
291   }
292
293   const Standard_Integer aMode = HasDisplayMode() ? DisplayMode() : DefaultDisplayMode();
294   if (myHilighter.IsNull()
295    || (aMode & MeshVS_DMF_OCCMask) == 0)
296   {
297     return;
298   }
299
300   // Make two array aliases pointing to the same memory:
301   // - TColStd_Array1OfReal for getting values from MeshVS_DataSource interface
302   // - array of gp_Pnt for convenient work with array of points
303   MeshVS_Buffer aCoordsBuf (3 * aMaxFaceNodes * sizeof(Standard_Real));
304   NCollection_Array1<gp_Pnt> aPntArray (aCoordsBuf, 1, aMaxFaceNodes);
305   TColStd_Array1OfReal aPntArrayAsCoordArray (aCoordsBuf, 1, 3 * aMaxFaceNodes);
306
307   const TColStd_PackedMapOfInteger& anAllNodesMap    = aSource->GetAllNodes();
308   const TColStd_PackedMapOfInteger& anAllElementsMap = aSource->GetAllElements();
309   if (aSource->IsAdvancedSelectionEnabled())
310   {
311     Handle(MeshVS_MeshOwner) anOwner;    
312     for (MeshVS_DataMapIteratorOfDataMapOfIntegerOwner anIt (GetOwnerMaps (Standard_False)); anIt.More(); anIt.Next())
313     {
314       anOwner = Handle(MeshVS_MeshOwner)::DownCast (anIt.Value());
315       if (!anOwner.IsNull())
316       {
317         // get the owner if it is already created
318         break;
319       }
320     }
321     if (anOwner.IsNull())
322     {
323       // create one owner for the whole mesh and for all selection modes
324       anOwner = new MeshVS_MeshOwner (this, aSource, 5);
325     }
326
327     // Save the owner. It will be available via GetOwnerMaps method
328     if (!myMeshOwners.IsBound (1))
329     {
330       myMeshOwners.Bind (1, anOwner);
331     }
332     // Create one sensitive entity. It should detect mesh entities correspondingly to selection mode
333     Handle(MeshVS_SensitiveMesh) aSensMesh = new MeshVS_SensitiveMesh (anOwner, theMode);
334     theSelection->Add (aSensMesh);
335   }
336   else
337   {
338     switch (theMode)
339     {
340       case MeshVS_SMF_Node:
341       {
342         myNodeOwners.Clear();
343         for (TColStd_MapIteratorOfPackedMapOfInteger anIter (anAllNodesMap); anIter.More(); anIter.Next())
344         {
345           const Standard_Integer aKey = anIter.Key();
346           Standard_Integer aNbNodes = 0;
347           MeshVS_EntityType aType = MeshVS_ET_NONE;
348           if (!myDataSource->GetGeom (aKey, Standard_False, aPntArrayAsCoordArray, aNbNodes, aType))
349           {
350             continue;
351           }
352
353           Standard_Address anAddr = myDataSource->GetAddr (aKey, Standard_False);
354           Handle(MeshVS_MeshEntityOwner) anOwner = new MeshVS_MeshEntityOwner (this, aKey, anAddr, aType, 5);
355           myNodeOwners.Bind (aKey, anOwner);
356           if (IsSelectableNode (aKey))
357           {
358             Handle(Select3D_SensitivePoint) aPoint = new Select3D_SensitivePoint (anOwner, aPntArray.First());
359             theSelection->Add (aPoint);
360           }
361           else
362           {
363             theSelection->Add (new MeshVS_DummySensitiveEntity (anOwner));
364           }
365         }
366         break;
367       }
368       case MeshVS_SMF_Mesh:
369       {
370         if (myWholeMeshOwner.IsNull())
371         {
372           myWholeMeshOwner = new SelectMgr_EntityOwner (this);
373         }
374
375         switch (mySelectionMethod)
376         {
377           case MeshVS_MSM_BOX:
378           {
379             Bnd_Box aBndBox;
380             BoundingBox (aBndBox);
381             if (!aBndBox.IsVoid())
382             {
383               theSelection->Add (new Select3D_SensitiveBox (myWholeMeshOwner, aBndBox));
384             }
385             break;
386           }
387           case MeshVS_MSM_NODES:
388           {
389             theSelection->Add (new MeshVS_CommonSensitiveEntity (myWholeMeshOwner, this, MeshVS_MSM_NODES));
390             break;
391           }
392           case MeshVS_MSM_PRECISE:
393           {
394             theSelection->Add (new MeshVS_CommonSensitiveEntity (myWholeMeshOwner, this, MeshVS_MSM_PRECISE));
395
396             // since MeshVS_Mesh objects can contain free edges and vertices, it is necessary to create
397             // separate sensitive entity for each of them
398             TColStd_PackedMapOfInteger aSharedNodes;
399             scanFacesForSharedNodes (anAllElementsMap, aMaxFaceNodes, aSharedNodes);
400
401             // create sensitive entities for free edges, if there are any
402             Standard_Integer aNbNodes = 0;
403             MeshVS_EntityType aType = MeshVS_ET_NONE;
404             for (TColStd_MapIteratorOfPackedMapOfInteger anElemIter (anAllElementsMap); anElemIter.More(); anElemIter.Next())
405             {
406               const Standard_Integer anElemIdx = anElemIter.Key();
407               if (IsSelectableElem (anElemIdx)
408                && myDataSource->GetGeomType (anElemIdx, Standard_True, aType)
409                && aType == MeshVS_ET_Link)
410               {
411                 myDataSource->GetGeom (anElemIdx, Standard_True, aPntArrayAsCoordArray, aNbNodes, aType);
412                 if (aNbNodes == 0)
413                 {
414                   continue;
415                 }
416
417                 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof(Standard_Integer));
418                 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
419                 if (!myDataSource->GetNodesByElement (anElemIdx, aElemNodes, aNbNodes))
420                 {
421                   continue;
422                 }
423
424                 MeshVS_Buffer aPntsBuf (aNbNodes * 3 * sizeof(Standard_Real));
425                 TColgp_Array1OfPnt aLinkPnts (aPntsBuf, 1, aNbNodes);
426                 Standard_Boolean isVertsShared = Standard_True;
427                 for (Standard_Integer aPntIdx = 1; aPntIdx <= aNbNodes; ++aPntIdx)
428                 {
429                   aLinkPnts (aPntIdx) = aPntArray.Value (aPntIdx);
430                   isVertsShared = isVertsShared && aSharedNodes.Contains (aElemNodes (aPntIdx));
431                   aSharedNodes.Add (aElemNodes (aPntIdx));
432                 }
433
434                 if (!isVertsShared)
435                 {
436                   Handle(Select3D_SensitiveEntity) aLinkEnt = new Select3D_SensitiveSegment (myWholeMeshOwner, aLinkPnts.Value (1), aLinkPnts.Value (2));
437                   theSelection->Add (aLinkEnt);
438                 }
439               }
440             }
441
442             // create sensitive entities for free nodes, if there are any
443             for (TColStd_MapIteratorOfPackedMapOfInteger aNodesIter (anAllNodesMap); aNodesIter.More(); aNodesIter.Next())
444             {
445               const Standard_Integer aNodeIdx = aNodesIter.Key();
446               if (IsSelectableNode (aNodeIdx)
447               &&  myDataSource->GetGeom (aNodeIdx, Standard_False, aPntArrayAsCoordArray, aNbNodes, aType)
448               && !aSharedNodes.Contains (aNodeIdx))
449               {
450                 Handle(Select3D_SensitiveEntity) aNodeEnt = new Select3D_SensitivePoint (myWholeMeshOwner, aPntArray.First());
451                 theSelection->Add (aNodeEnt);
452               }
453             }
454           }
455           break;
456         }
457         break;
458       }
459       case MeshVS_SMF_Group:
460       {
461         myGroupOwners.Clear();
462
463         TColStd_PackedMapOfInteger anAllGroupsMap;
464         aSource->GetAllGroups (anAllGroupsMap);
465
466         Handle(MeshVS_HArray1OfSequenceOfInteger) aTopo;
467         for (TColStd_MapIteratorOfPackedMapOfInteger anIter (anAllGroupsMap); anIter.More(); anIter.Next())
468         {
469           const Standard_Integer aKeyGroup = anIter.Key();
470           MeshVS_EntityType aGroupType = MeshVS_ET_NONE;
471           TColStd_PackedMapOfInteger aGroupMap;
472           if (!myDataSource->GetGroup (aKeyGroup, aGroupType, aGroupMap))
473           {
474             continue;
475           }
476
477           Standard_Address anAddr = myDataSource->GetGroupAddr (aKeyGroup);
478           Standard_Integer aPrior = 0;
479           switch (aGroupType)
480           {
481             case MeshVS_ET_Volume: aPrior = 1; break;
482             case MeshVS_ET_Face:   aPrior = 2; break;
483             case MeshVS_ET_Link:   aPrior = 3; break;
484             case MeshVS_ET_0D:     aPrior = 4; break;
485             case MeshVS_ET_Node:   aPrior = 5; break;
486             default: break;
487           }
488
489           Handle(MeshVS_MeshEntityOwner) anOwner = new MeshVS_MeshEntityOwner (this, aKeyGroup, anAddr, aGroupType, aPrior, Standard_True);
490           myGroupOwners.Bind (aKeyGroup, anOwner);
491
492           Standard_Boolean added = Standard_False;
493           Standard_Integer aNbNodes = 0;
494           MeshVS_EntityType aType = MeshVS_ET_NONE;
495           for (TColStd_MapIteratorOfPackedMapOfInteger anIterMG (aGroupMap); anIterMG.More(); anIterMG.Next())
496           {
497             Standard_Integer aKey = anIterMG.Key();
498             if (aGroupType == MeshVS_ET_Node)
499             {
500               if (myDataSource->GetGeom (aKey, Standard_False, aPntArrayAsCoordArray, aNbNodes, aType)
501                && IsSelectableNode/*!IsHiddenNode*/(aKey))
502               {
503                 theSelection->Add (new Select3D_SensitivePoint (anOwner, aPntArray.First ()));
504                 added = Standard_True;
505               }
506             }
507             else if (myDataSource->GetGeomType (aKey, Standard_True, aType)
508                   && IsSelectableElem/*!IsHiddenElem*/(aKey))
509             {
510               myDataSource->GetGeom (aKey, Standard_True, aPntArrayAsCoordArray, aNbNodes, aType);
511               if (aType == MeshVS_ET_Face && aNbNodes > 0) // Faces: 2D-elements
512               {
513                 Handle(Select3D_SensitiveEntity) aSensFace;
514                 if (aNbNodes == 3)
515                 {
516                   aSensFace = new Select3D_SensitiveTriangle (anOwner,
517                                                               aPntArray.Value (1), aPntArray.Value (2), aPntArray.Value (3),
518                                                               Select3D_TOS_INTERIOR);
519                 }
520                 else if (aNbNodes == 4)
521                 {
522                   aSensFace = new MeshVS_SensitiveQuad (anOwner, aPntArray);
523                 }
524                 else
525                 {
526                   aSensFace = new MeshVS_SensitiveFace (anOwner, aPntArray);
527                 }
528                 theSelection->Add (aSensFace);
529                 added = Standard_True;
530               }
531               else if (aType == MeshVS_ET_Link && aNbNodes > 0) // Links: 1D-elements
532               {
533                 Handle (MeshVS_SensitiveSegment) aSeg = new MeshVS_SensitiveSegment (anOwner, aPntArray (1), aPntArray (2));
534                 theSelection->Add (aSeg);
535                 added = Standard_True;
536               }
537               else if (aType == MeshVS_ET_Volume
538                     && aSource->Get3DGeom (aKey, aNbNodes, aTopo))
539               {
540                 Handle(MeshVS_SensitivePolyhedron) aPolyhedron = new MeshVS_SensitivePolyhedron (anOwner, aPntArray, aTopo);
541                 theSelection->Add (aPolyhedron);
542                 added = Standard_True;
543               }
544               else //if ( aType == MeshVS_ET_0D )   // Custom : not only 0D-elements !!!
545               {
546                 Handle(SelectBasics_SensitiveEntity) anEnt = myHilighter->CustomSensitiveEntity (anOwner, aKey);
547                 if (!anEnt.IsNull())
548                 {
549                   theSelection->Add (anEnt);
550                   added = Standard_True;
551                 }
552               }
553             }
554           }
555           if (!added)
556           {
557             theSelection->Add (new MeshVS_DummySensitiveEntity (anOwner));
558           }
559         }
560         break;
561       }
562       default: // all residuary modes
563       {
564         Handle(MeshVS_HArray1OfSequenceOfInteger) aTopo;
565         myElementOwners.Clear();
566
567         MeshVS_DataMapOfIntegerOwner* aCurMap = &my0DOwners;
568         if (theMode == MeshVS_ET_Link)
569         {
570           aCurMap = &myLinkOwners;
571         }
572         else if (theMode == MeshVS_ET_Face)
573         {
574           aCurMap = &myFaceOwners;
575         }
576         else if (theMode == MeshVS_ET_Volume)
577         {
578           aCurMap = &myVolumeOwners;
579         }
580         aCurMap->Clear();
581
582         Standard_Integer aNbNodes = 0;
583         MeshVS_EntityType aType = MeshVS_ET_NONE;
584         for (TColStd_MapIteratorOfPackedMapOfInteger anIterMV (anAllElementsMap); anIterMV.More(); anIterMV.Next())
585         {
586           Standard_Integer aKey = anIterMV.Key();
587           if (myDataSource->GetGeomType (aKey, Standard_True, aType)
588            && theMode == aType)
589           {
590             myDataSource->GetGeom (aKey, Standard_True, aPntArrayAsCoordArray, aNbNodes, aType);
591             Standard_Address anAddr = myDataSource->GetAddr (aKey, Standard_True);
592
593             Standard_Integer aPrior = 0;
594             switch (aType)
595             {
596               case MeshVS_ET_Volume: aPrior = 1; break;
597               case MeshVS_ET_Face:   aPrior = 2; break;
598               case MeshVS_ET_Link:   aPrior = 3; break;
599               case MeshVS_ET_0D:     aPrior = 4; break;
600               default: break;
601             }
602
603             Handle(MeshVS_MeshEntityOwner) anOwner = new MeshVS_MeshEntityOwner (this, aKey, anAddr, aType, aPrior);
604             aCurMap->Bind (aKey, anOwner);
605             if (IsSelectableElem (aKey)) // The element is selectable
606             {
607               if (aType == MeshVS_ET_Face && aNbNodes > 0) // Faces: 2D-elements
608               {
609                 Handle(Select3D_SensitiveEntity) aSensFace;
610                 if (aNbNodes == 3)
611                 {
612                   aSensFace = new Select3D_SensitiveTriangle (anOwner,
613                                                               aPntArray.Value (1), aPntArray.Value (2), aPntArray.Value (3),
614                                                               Select3D_TOS_INTERIOR);
615                 }
616                 else if (aNbNodes == 4)
617                 {
618                   aSensFace = new MeshVS_SensitiveQuad (anOwner, aPntArray);
619                 }
620                 else
621                 {
622                   aSensFace = new MeshVS_SensitiveFace (anOwner, aPntArray);
623                 }
624                 theSelection->Add (aSensFace);
625               }
626               else if (aType == MeshVS_ET_Link && aNbNodes > 0) // Links: 1D-elements
627               {
628                 Handle(MeshVS_SensitiveSegment) aSeg = new MeshVS_SensitiveSegment (anOwner, aPntArray (1), aPntArray (2));
629                 theSelection->Add (aSeg);
630               }
631               else if (aType == MeshVS_ET_Volume
632                     && aSource->Get3DGeom (aKey, aNbNodes, aTopo))
633               {
634                 Handle(MeshVS_SensitivePolyhedron) aPolyhedron = new MeshVS_SensitivePolyhedron (anOwner, aPntArray, aTopo);
635                 theSelection->Add (aPolyhedron);
636               }
637               else //if ( aType == MeshVS_ET_0D )   // Custom : not only 0D-elements !!!
638               {
639                 Handle(SelectBasics_SensitiveEntity) anEnt = myHilighter->CustomSensitiveEntity (anOwner, aKey);
640                 if (!anEnt.IsNull())
641                 {
642                   theSelection->Add (anEnt);
643                 }
644               }
645             }
646             else
647             {
648               theSelection->Add (new MeshVS_DummySensitiveEntity (anOwner));
649             }
650           }
651         }
652         break;
653       }
654     }
655   }
656
657   StdSelect_BRepSelectionTool::PreBuildBVH (theSelection);
658
659   if (toShowComputeSelectionTime)
660   {
661     Standard_Real sec, cpu;
662     Standard_Integer min, hour;
663     gTimer.Show (sec, min, hour, cpu);
664     std::cout << "SelectionMode : " << theMode << "\n";
665     std::cout << "Compute selection: " << sec << " sec\n";
666     std::cout << "Compute selection CPU : " << cpu << " sec\n\n";
667     gTimer.Stop();
668   }
669 }
670
671 //================================================================
672 // Function : GetBuildersCount
673 // Purpose  :
674 //================================================================
675 Standard_Integer MeshVS_Mesh::GetBuildersCount () const
676 {
677   return myBuilders.Length();
678 }
679
680 //================================================================
681 // Function : GetFreeId
682 // Purpose  :
683 //================================================================
684 Standard_Integer MeshVS_Mesh::GetFreeId () const
685 {
686   TColStd_PackedMapOfInteger Ids;
687   Standard_Integer i, len = myBuilders.Length(), curId;
688
689   for ( i=1; i<=len; i++ )
690     Ids.Add( myBuilders.Value(i)->GetId () );
691
692   curId = 0;
693   while ( Ids.Contains( curId ) )
694     curId++;
695
696   return curId;
697 }
698
699 //================================================================
700 // Function : GetBuilder
701 // Purpose  :
702 //================================================================
703 Handle (MeshVS_PrsBuilder) MeshVS_Mesh::GetBuilder ( const Standard_Integer Index ) const
704 {
705   if ( Index>=1 && Index<=myBuilders.Length() )
706     return myBuilders.Value( Index );
707   else
708     return 0;
709 }
710
711 //================================================================
712 // Function : GetBuilderById
713 // Purpose  :
714 //================================================================
715 Handle (MeshVS_PrsBuilder) MeshVS_Mesh::GetBuilderById ( const Standard_Integer Id ) const
716 {
717   Handle (MeshVS_PrsBuilder) Result;
718
719   Standard_Integer i, len = myBuilders.Length();
720   for ( i=1; i<=len; i++ )
721     if ( myBuilders.Value(i)->GetId () == Id )
722     {
723       Result = myBuilders.Value(i);
724       break;
725     }
726   return Result;
727 }
728
729 //================================================================
730 // Function : AddBuilder
731 // Purpose  :
732 //================================================================
733 void MeshVS_Mesh::AddBuilder ( const Handle (MeshVS_PrsBuilder)& theBuilder,
734                                const Standard_Boolean TreatAsHilighter )
735 {
736   if ( theBuilder.IsNull() )
737     return;
738
739   Standard_Integer i, n = myBuilders.Length();
740   for ( i = 1; i<=n; i++ )
741     if ( myBuilders(i)->GetPriority() < theBuilder->GetPriority() )
742       break;
743
744   if ( i>n )
745     myBuilders.Append ( theBuilder );
746   else
747     myBuilders.InsertBefore ( i, theBuilder );
748
749   if( TreatAsHilighter )
750     myHilighter = theBuilder;
751 }
752
753 //================================================================
754 // Function : RemoveBuilder
755 // Purpose  :
756 //================================================================
757 void MeshVS_Mesh::RemoveBuilder ( const Standard_Integer theIndex )
758 {
759   Handle( MeshVS_PrsBuilder ) aBuild = GetBuilder( theIndex );
760   if ( !aBuild.IsNull() )
761   {
762     if ( aBuild == myHilighter )
763       myHilighter.Nullify();
764     myBuilders.Remove ( theIndex );
765   }
766 }
767
768 //================================================================
769 // Function : RemoveBuilderById
770 // Purpose  :
771 //================================================================
772 void MeshVS_Mesh::RemoveBuilderById ( const Standard_Integer Id )
773 {
774   Standard_Integer i, n = myBuilders.Length();
775   for ( i=1; i<=n; i++ )
776   {
777     Handle( MeshVS_PrsBuilder ) aCur = myBuilders(i);
778     if ( !aCur.IsNull() && aCur->GetId()==Id )
779       break;
780   }
781   if ( i>=1 && i<=n )
782   {
783     if ( GetBuilder( i )==myHilighter )
784       myHilighter.Nullify();
785     RemoveBuilder ( i );
786   }
787 }
788
789 //================================================================
790 // Function : SetHiddenElems
791 // Purpose  :
792 //================================================================
793 void MeshVS_Mesh::SetHiddenElems ( const Handle(TColStd_HPackedMapOfInteger)& theMap )
794 {
795   myHiddenElements = theMap;
796
797   // Note: update of list of selectable nodes -- this is not optimal!
798   Standard_Boolean AutoSelUpdate = Standard_False;
799   if ( !GetDrawer().IsNull() && GetDrawer()->GetBoolean( MeshVS_DA_SelectableAuto, AutoSelUpdate ) &&
800        AutoSelUpdate )
801     UpdateSelectableNodes();
802 }
803
804 //================================================================
805 // Function : SetHiddenNodes
806 // Purpose  :
807 //================================================================
808 void MeshVS_Mesh::SetHiddenNodes ( const Handle(TColStd_HPackedMapOfInteger)& theMap )
809 {
810   myHiddenNodes = theMap;
811
812   // Note: update of list of selectable nodes -- this is not optimal!
813   Standard_Boolean AutoSelUpdate = Standard_False;
814   if ( !GetDrawer().IsNull() && GetDrawer()->GetBoolean( MeshVS_DA_SelectableAuto, AutoSelUpdate ) &&
815        AutoSelUpdate )
816     UpdateSelectableNodes();
817 }
818
819 //================================================================
820 // Function : GetHiddenElems
821 // Purpose  :
822 //================================================================
823 const Handle(TColStd_HPackedMapOfInteger)& MeshVS_Mesh::GetHiddenElems () const
824 {
825   return myHiddenElements;
826 }
827
828 //================================================================
829 // Function : GetHiddenNodes
830 // Purpose  :
831 //================================================================
832 const Handle(TColStd_HPackedMapOfInteger)& MeshVS_Mesh::GetHiddenNodes () const
833 {
834   return myHiddenNodes;
835 }
836
837 //================================================================
838 // Function : AddToMap
839 // Purpose  :
840 //================================================================
841 void AddToMap ( MeshVS_DataMapOfIntegerOwner& Result, const MeshVS_DataMapOfIntegerOwner& Addition )
842 {
843   MeshVS_DataMapIteratorOfDataMapOfIntegerOwner anIt ( Addition );
844   for ( ; anIt.More(); anIt.Next() )
845     if ( Result.IsBound ( anIt.Key() ) )
846       Result.ChangeFind ( anIt.Key() ) = anIt.Value();
847     else
848       Result.Bind( anIt.Key(), anIt.Value() );
849 }
850
851 //================================================================
852 // Function : GetOwnerMaps
853 // Purpose  :
854 //================================================================
855 const MeshVS_DataMapOfIntegerOwner& MeshVS_Mesh::GetOwnerMaps ( const Standard_Boolean IsElements )
856 {
857   Handle(MeshVS_DataSource) aDS = GetDataSource();
858   if( !aDS.IsNull() && aDS->IsAdvancedSelectionEnabled() )
859     return myMeshOwners;
860   if ( IsElements )
861   {
862     if ( myElementOwners.IsEmpty() )
863     {
864       AddToMap ( myElementOwners, my0DOwners );
865       AddToMap ( myElementOwners, myLinkOwners );
866       AddToMap ( myElementOwners, myFaceOwners );
867       AddToMap ( myElementOwners, myVolumeOwners );
868     }
869     return myElementOwners;
870   }
871   else
872     return myNodeOwners;
873 }
874
875 //================================================================
876 // Function : IsHiddenElem
877 // Purpose  :
878 //================================================================
879 Standard_Boolean MeshVS_Mesh::IsHiddenElem ( const Standard_Integer theID ) const
880 {
881   return ! myHiddenElements.IsNull() && myHiddenElements->Map().Contains( theID );
882 }
883
884 //================================================================
885 // Function : IsHiddenNode
886 // Purpose  :
887 //================================================================
888 Standard_Boolean MeshVS_Mesh::IsHiddenNode ( const Standard_Integer theID ) const
889 {
890   // note that by default all nodes are hidden
891   return myHiddenNodes.IsNull() || myHiddenNodes->Map().Contains( theID );
892 }
893
894 //================================================================
895 // Function : GetDrawer
896 // Purpose  :
897 //================================================================
898 Handle( MeshVS_Drawer ) MeshVS_Mesh::GetDrawer() const
899 {
900   return myCurrentDrawer;
901 }
902
903 //================================================================
904 // Function : SetDrawer
905 // Purpose  :
906 //================================================================
907 void MeshVS_Mesh::SetDrawer(const Handle(MeshVS_Drawer)& aDrawer)
908 {
909   myCurrentDrawer = aDrawer;
910 }
911
912 //================================================================
913 // Function : GetDataSource
914 // Purpose  :
915 //================================================================
916 Handle(MeshVS_DataSource) MeshVS_Mesh::GetDataSource() const
917 {
918   return myDataSource;
919 }
920
921 //================================================================
922 // Function : SetDataSource
923 // Purpose  :
924 //================================================================
925 void MeshVS_Mesh::SetDataSource( const Handle(MeshVS_DataSource)& theDataSource )
926 {
927   myDataSource = theDataSource;
928 }
929
930 //================================================================
931 // Function : HilightSelected
932 // Purpose  :
933 //================================================================
934 void MeshVS_Mesh::HilightSelected ( const Handle(PrsMgr_PresentationManager3d)& thePM,
935                                     const SelectMgr_SequenceOfOwner& theOwners )
936 {
937   if ( myHilighter.IsNull() )
938     return;
939
940 //  if ( mySelectionPrs.IsNull() )
941 //    mySelectionPrs = new Prs3d_Presentation ( thePM->StructureManager() );
942
943   //new functionality
944
945   Handle( Prs3d_Presentation ) aSelectionPrs;
946
947   aSelectionPrs = GetSelectPresentation( thePM );
948
949   if( HasPresentation() )
950     aSelectionPrs->SetTransformPersistence (Presentation()->TransformPersistence());
951   //----------------
952
953   //   It is very important to call this parent method, because it check whether
954   // mySelectionPrs is created and if not, create it.
955
956 #ifdef OCCT_DEBUG
957   OSD_Timer gTimer;
958   gTimer.Reset();
959   gTimer.Start();
960 #endif
961
962   Standard_Integer len = theOwners.Length(), i;
963
964   Handle (MeshVS_MeshEntityOwner) anOwner;
965   TColStd_PackedMapOfInteger aSelNodes, aSelElements;
966
967   for( i=1; i<=len; i++ )
968   {
969     if (theOwners.Value (i) == GlobalSelOwner())
970     {
971       const Standard_Integer aHiMode = HasHilightMode() ? HilightMode() : 0;
972       const Handle(Prs3d_Drawer)& aSelStyle = !HilightAttributes().IsNull() ? HilightAttributes() : GetContext()->SelectionStyle();
973       thePM->Color (this, aSelStyle, aHiMode);
974       continue;
975     }
976     anOwner = Handle (MeshVS_MeshEntityOwner)::DownCast ( theOwners.Value ( i ) );
977     if ( !anOwner.IsNull() )
978     {
979       // nkv: add support of mesh groups
980       if ( anOwner->IsGroup() ) {
981         MeshVS_EntityType aGroupType;
982         TColStd_PackedMapOfInteger aGroupMap;
983         if ( GetDataSource()->GetGroup( anOwner->ID(), aGroupType, aGroupMap ) ) {
984           if ( aGroupType == MeshVS_ET_Node ) {
985             for( TColStd_MapIteratorOfPackedMapOfInteger anIt(aGroupMap); anIt.More(); anIt.Next() )
986               if( IsSelectableNode/*!IsHiddenNode*/( anIt.Key() ) )
987                 aSelNodes.Add( anIt.Key() );
988           }
989           else {
990             for( TColStd_MapIteratorOfPackedMapOfInteger anIt(aGroupMap); anIt.More(); anIt.Next() )
991               if( IsSelectableElem/*!IsHiddenElem*/( anIt.Key() ) )
992                 aSelElements.Add( anIt.Key() );
993           }
994         }
995       }
996       else {
997         if( anOwner->Type() == MeshVS_ET_Node )
998           aSelNodes.Add( anOwner->ID() );
999         else
1000           aSelElements.Add( anOwner->ID() );
1001       }
1002     }
1003     else if( GetDataSource()->IsAdvancedSelectionEnabled() )
1004     {
1005       Handle(MeshVS_MeshOwner) aMeshOwner = Handle(MeshVS_MeshOwner)::DownCast ( theOwners.Value ( i ) );
1006       if( !aMeshOwner.IsNull() )
1007       {
1008         Handle(TColStd_HPackedMapOfInteger) aNodes = aMeshOwner->GetSelectedNodes();
1009         Handle(TColStd_HPackedMapOfInteger) aElems = aMeshOwner->GetSelectedElements();
1010         if( !aNodes.IsNull() )
1011           aSelNodes.Assign( aNodes->Map() );
1012         if( !aElems.IsNull() )
1013           aSelElements.Assign( aElems->Map() );
1014       }
1015     }
1016 //agv    else if( theOwners.Value ( i )==myWholeMeshOwner )
1017     else if (IsWholeMeshOwner (theOwners.Value ( i )))
1018     {
1019       TColStd_MapIteratorOfPackedMapOfInteger anIt(GetDataSource()->GetAllNodes());
1020       for( ; anIt.More(); anIt.Next() )
1021         if( !IsHiddenNode( anIt.Key() ) )
1022           aSelNodes.Add( anIt.Key() );
1023
1024       anIt = TColStd_MapIteratorOfPackedMapOfInteger( GetDataSource()->GetAllElements() );
1025       for( ; anIt.More(); anIt.Next() )
1026         if( !IsHiddenElem( anIt.Key() ) )
1027           aSelElements.Add( anIt.Key() );
1028
1029       break;
1030     }
1031   }
1032
1033   Standard_Boolean IsNeedToRedisplay = Standard_False;
1034
1035   aSelectionPrs->Clear();
1036
1037   myHilighter->SetDrawer ( mySelectionDrawer );
1038
1039   if( aSelNodes.Extent()>0 )
1040   {
1041     TColStd_PackedMapOfInteger tmp;
1042     myHilighter->Build ( aSelectionPrs, aSelNodes, tmp, Standard_False, MeshVS_DMF_SelectionPrs );
1043   }
1044   if( aSelElements.Extent()>0 )
1045   {
1046     TColStd_PackedMapOfInteger tmp;
1047     myHilighter->Build( aSelectionPrs, aSelElements, tmp, Standard_True, MeshVS_DMF_SelectionPrs );
1048   }
1049
1050   myHilighter->SetDrawer ( 0 );
1051
1052   IsNeedToRedisplay = Standard_True;
1053
1054   aSelectionPrs->SetZLayer (Graphic3d_ZLayerId_Top);
1055
1056   if ( IsNeedToRedisplay )
1057   {
1058     aSelectionPrs->SetDisplayPriority(9);
1059     aSelectionPrs->Display();
1060   }
1061
1062 #ifdef OCCT_DEBUG
1063     Standard_Real sec, cpu;
1064     Standard_Integer min, hour;
1065
1066     gTimer.Show ( sec, min, hour, cpu );
1067     cout << "HilightSelected : " << endl;
1068     cout << aSelNodes.Extent() << " nodes " << endl;
1069     cout << aSelElements.Extent() << " elements " << endl;
1070     cout << "Time : " << sec << " sec" << endl;
1071     cout << "CPU time : " << cpu << " sec" << endl << endl;
1072     gTimer.Stop();
1073 #endif
1074 }
1075
1076 //================================================================
1077 // Function : HilightOwnerWithColor
1078 // Purpose  :
1079 //================================================================
1080 void MeshVS_Mesh::HilightOwnerWithColor ( const Handle(PrsMgr_PresentationManager3d)& thePM,
1081                                           const Handle(Prs3d_Drawer)& theStyle,
1082                                           const Handle(SelectMgr_EntityOwner)& theOwner)
1083 {
1084   if (theOwner.IsNull())
1085     return;
1086
1087   const Quantity_Color& aColor = theStyle->Color();
1088   if (theOwner == GlobalSelOwner())
1089   {
1090     Standard_Integer aHiMode = HasHilightMode() ? HilightMode() : 0;
1091     thePM->Color (this, theStyle, aHiMode, NULL, Graphic3d_ZLayerId_Top);
1092     return;
1093   }
1094
1095   if ( myHilighter.IsNull() )
1096     return;
1097
1098   Handle( Prs3d_Presentation ) aHilightPrs;
1099   aHilightPrs = GetHilightPresentation( thePM );
1100
1101   aHilightPrs->Clear();
1102
1103   //new functionality
1104   if( HasPresentation() )
1105     aHilightPrs->SetTransformPersistence (Presentation()->TransformPersistence());
1106   //----------------
1107
1108   const Standard_Boolean isMeshEntityOwner = theOwner->IsKind ( STANDARD_TYPE ( MeshVS_MeshEntityOwner ) );
1109   const Standard_Boolean isWholeMeshOwner =
1110 //agv    !Owner.IsNull() && Owner==myWholeMeshOwner;
1111     IsWholeMeshOwner (theOwner);
1112
1113   Standard_Integer aDispMode = MeshVS_DMF_Shading;
1114   if ( HasDisplayMode() && ( DisplayMode() & MeshVS_DMF_OCCMask ) > MeshVS_DMF_WireFrame )
1115     aDispMode = ( DisplayMode() & MeshVS_DMF_OCCMask );
1116   //It because we draw hilighted owners only in shading or shrink (not in wireframe)
1117
1118   myHilightDrawer->SetColor( MeshVS_DA_InteriorColor, aColor );
1119   myHilightDrawer->SetColor( MeshVS_DA_BackInteriorColor, aColor );
1120   myHilightDrawer->SetColor( MeshVS_DA_EdgeColor, aColor );
1121   myHilightDrawer->SetColor( MeshVS_DA_BeamColor, aColor );
1122   myHilightDrawer->SetColor( MeshVS_DA_MarkerColor, aColor );
1123   myHilighter->SetDrawer( myHilightDrawer );
1124
1125   if( isMeshEntityOwner )
1126   {
1127     Handle ( MeshVS_MeshEntityOwner ) theAISOwner = Handle ( MeshVS_MeshEntityOwner )::DownCast ( theOwner );
1128     MeshVS_EntityType aType = theAISOwner->Type();
1129     Standard_Integer  anID  = theAISOwner->ID();
1130
1131     if ( theAISOwner->IsGroup() ) {
1132       MeshVS_EntityType aGroupType;
1133       TColStd_PackedMapOfInteger aGroupMap;
1134       if ( myDataSource->GetGroup( anID, aGroupType, aGroupMap ) ) {
1135         TColStd_PackedMapOfInteger tmp;
1136         myHilighter->Build( aHilightPrs, aGroupMap, tmp, aType!=MeshVS_ET_Node,
1137                             aDispMode | MeshVS_DMF_HilightPrs );
1138       }
1139     }
1140     else {
1141       TColStd_PackedMapOfInteger anOne, tmp;
1142       anOne.Add (anID);
1143       myHilighter->Build( aHilightPrs, anOne, tmp, aType!=MeshVS_ET_Node,
1144                           aDispMode | MeshVS_DMF_HilightPrs );
1145     }
1146   }
1147   else if( isWholeMeshOwner  )
1148   {
1149     if( ! GetDataSource().IsNull() )
1150     {
1151       TColStd_PackedMapOfInteger tmp;
1152       myHilighter->Build( aHilightPrs, GetDataSource()->GetAllElements(), tmp,
1153                           Standard_True, MeshVS_DMF_WireFrame );
1154     }
1155   }
1156   else 
1157   {
1158     Handle(MeshVS_MeshOwner) aMeshOwner = Handle(MeshVS_MeshOwner)::DownCast ( theOwner );
1159     if( !aMeshOwner.IsNull() )
1160     {
1161       Handle(TColStd_HPackedMapOfInteger) aNodes = aMeshOwner->GetDetectedNodes();
1162       Handle(TColStd_HPackedMapOfInteger) aElems = aMeshOwner->GetDetectedElements();
1163       // hilight detected entities
1164       if( !aNodes.IsNull() )
1165       {
1166         TColStd_PackedMapOfInteger tmp;
1167         myHilighter->Build( aHilightPrs, aNodes->Map(), tmp, Standard_False,
1168                             aDispMode | MeshVS_DMF_HilightPrs );
1169       }
1170       if( !aElems.IsNull() )
1171       {
1172         TColStd_PackedMapOfInteger tmp;
1173         myHilighter->Build( aHilightPrs, aElems->Map(), tmp, Standard_True,
1174                             aDispMode | MeshVS_DMF_HilightPrs );
1175       }
1176     }    
1177   }
1178
1179   aHilightPrs->SetZLayer (Graphic3d_ZLayerId_Topmost);
1180
1181   if (thePM->IsImmediateModeOn())
1182   {
1183     thePM->AddToImmediateList (aHilightPrs);
1184   }
1185   myHilighter->SetDrawer ( 0 );
1186 }
1187
1188 //=======================================================================
1189 //function : ClearSelected
1190 //purpose  :
1191 //=======================================================================
1192 void MeshVS_Mesh::ClearSelected ()
1193 {
1194   Handle( Prs3d_Presentation ) aSelectionPrs = GetSelectPresentation( NULL );  
1195   if( !aSelectionPrs.IsNull() )
1196     aSelectionPrs->Clear(); 
1197 }
1198
1199 //=======================================================================
1200 //function : FindBuilder
1201 //purpose  :
1202 //=======================================================================
1203 Handle (MeshVS_PrsBuilder) MeshVS_Mesh::FindBuilder ( const Standard_CString theTypeName ) const
1204 {
1205   Standard_Integer len = myBuilders.Length();
1206   Handle(MeshVS_PrsBuilder) aBuilder;
1207   Standard_Boolean IsExist = Standard_False;
1208
1209   for ( Standard_Integer i=1; i<=len && !IsExist; i++)
1210     if ( myBuilders.Value (i)->IsKind ( theTypeName ) )
1211     {
1212       aBuilder = myBuilders.Value (i);
1213       IsExist = Standard_True;
1214     }
1215
1216   return aBuilder;
1217 }
1218
1219 //=======================================================================
1220 //function : SetHilighter
1221 //purpose  :
1222 //=======================================================================
1223 void MeshVS_Mesh::SetHilighter ( const Handle( MeshVS_PrsBuilder )& Builder )
1224 {
1225   myHilighter = Builder;
1226 }
1227
1228 //=======================================================================
1229 //function : SetHilighter
1230 //purpose  :
1231 //=======================================================================
1232 Standard_Boolean MeshVS_Mesh::SetHilighter ( const Standard_Integer Index )
1233 {
1234   Handle( MeshVS_PrsBuilder ) aBuild = GetBuilder( Index );
1235   Standard_Boolean aRes = ( !aBuild.IsNull() );
1236   if ( aRes )
1237     myHilighter = aBuild;
1238   return aRes;
1239 }
1240
1241 //=======================================================================
1242 //function : SetHilighter
1243 //purpose  :
1244 //=======================================================================
1245 Standard_Boolean MeshVS_Mesh::SetHilighterById ( const Standard_Integer Id )
1246 {
1247   Handle( MeshVS_PrsBuilder ) aBuild = GetBuilderById( Id );
1248   Standard_Boolean aRes = ( !aBuild.IsNull() );
1249   if ( aRes )
1250     myHilighter = aBuild;
1251   return aRes;
1252 }
1253
1254 //=======================================================================
1255 //function : GetHilighter
1256 //purpose  :
1257 //=======================================================================
1258 Handle( MeshVS_PrsBuilder ) MeshVS_Mesh::GetHilighter () const
1259 {
1260   return myHilighter;
1261 }
1262
1263 //=======================================================================
1264 //function : IsSelectableElem
1265 //purpose  :
1266 //=======================================================================
1267 Standard_Boolean MeshVS_Mesh::IsSelectableElem ( const Standard_Integer ID ) const
1268 {
1269   return ! IsHiddenElem ( ID );
1270 }
1271
1272 //=======================================================================
1273 //function : IsSelectableNode
1274 //purpose  :
1275 //=======================================================================
1276 Standard_Boolean MeshVS_Mesh::IsSelectableNode ( const Standard_Integer ID ) const
1277 {
1278   return mySelectableNodes.IsNull() ? ! IsHiddenNode ( ID ) : 
1279                                       mySelectableNodes->Map().Contains( ID );
1280 }
1281
1282 //=======================================================================
1283 //function : GetSelectableNodes
1284 //purpose  :
1285 //=======================================================================
1286 const Handle(TColStd_HPackedMapOfInteger)& MeshVS_Mesh::GetSelectableNodes () const
1287 {
1288   return mySelectableNodes;
1289 }
1290
1291 //=======================================================================
1292 //function : SetSelectableNodes
1293 //purpose  :
1294 //=======================================================================
1295 void MeshVS_Mesh::SetSelectableNodes ( const Handle(TColStd_HPackedMapOfInteger)& Ids )
1296 {
1297   mySelectableNodes = Ids;
1298 }
1299
1300 //=======================================================================
1301 //function : UpdateSelectableNodes
1302 //purpose  :
1303 //=======================================================================
1304 void MeshVS_Mesh::UpdateSelectableNodes()
1305 {
1306   mySelectableNodes = new TColStd_HPackedMapOfInteger;
1307   
1308   Standard_Integer aMaxFaceNodes;
1309   Handle( MeshVS_DataSource ) aSource = GetDataSource();
1310   if ( aSource.IsNull() || myCurrentDrawer.IsNull() || !myCurrentDrawer->GetInteger
1311          ( MeshVS_DA_MaxFaceNodes, aMaxFaceNodes ) || aMaxFaceNodes<=0 )
1312     return;
1313
1314   // all non-hidden nodes are selectable;
1315   // by default (i.e. if myHiddenNodes.IsNull()) all nodes are hidden
1316   if ( ! myHiddenNodes.IsNull() )
1317   {
1318     mySelectableNodes->ChangeMap().Subtraction (aSource->GetAllNodes(),
1319                                                 myHiddenNodes->Map());
1320   } 
1321
1322   // add all nodes belonging to non-hidden elements
1323   TColStd_MapIteratorOfPackedMapOfInteger anIter( aSource->GetAllElements() );
1324   for ( ; anIter.More(); anIter.Next() )
1325   {
1326     Standard_Integer aKey = anIter.Key();
1327     if ( IsHiddenElem (aKey) )
1328       continue;
1329
1330     MeshVS_Buffer aNodesBuf (aMaxFaceNodes*sizeof(Standard_Integer));
1331     TColStd_Array1OfInteger aNodes (aNodesBuf, 1, aMaxFaceNodes);
1332     Standard_Integer NbNodes;
1333     if ( !aSource->GetNodesByElement ( aKey, aNodes, NbNodes ) )
1334       continue;
1335     for ( Standard_Integer i=1; i<=NbNodes; i++ )
1336       mySelectableNodes->ChangeMap().Add ( aNodes(i) );
1337   }
1338 }
1339
1340 //=======================================================================
1341 //function : GetMeshSelMethod
1342 //purpose  :
1343 //=======================================================================
1344 MeshVS_MeshSelectionMethod MeshVS_Mesh::GetMeshSelMethod() const
1345 {
1346   return mySelectionMethod;
1347 }
1348
1349 //=======================================================================
1350 //function : SetMeshSelMethod
1351 //purpose  :
1352 //=======================================================================
1353 void MeshVS_Mesh::SetMeshSelMethod( const MeshVS_MeshSelectionMethod M )
1354 {
1355   mySelectionMethod = M;
1356 }
1357
1358 //=======================================================================
1359 //function : IsWholeMeshOwner
1360 //purpose  : 
1361 //=======================================================================
1362
1363 Standard_Boolean MeshVS_Mesh::IsWholeMeshOwner
1364                             (const Handle(SelectMgr_EntityOwner)& theOwn) const
1365 {
1366   return theOwn.IsNull() ? Standard_False : (theOwn == myWholeMeshOwner);
1367 }