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