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