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