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