e44d2869b09bb5cc0553b3da58adeda62e2bb6ac
[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           Bnd_Box box;
338           box.Add( gp_Pnt( min[0], min[1], min[2] ) );
339           box.Add( gp_Pnt( max[0], max[1], max[2] ) );
340
341           theSelection->Add( new Select3D_SensitiveBox( myWholeMeshOwner, box ) );
342         }
343         break;
344
345       case MeshVS_MSM_NODES:
346         {
347           TColStd_MapIteratorOfPackedMapOfInteger anIterN( anAllNodesMap );
348           for( ; anIterN.More(); anIterN.Next() )
349             if( myDataSource->GetGeom( anIterN.Key(), Standard_False, aCoords, NbNodes, aType ) &&
350                 !IsHiddenNode( anIterN.Key() ) )
351               theSelection->Add( new Select3D_SensitivePoint( myWholeMeshOwner, gp_Pnt ( aCoords(1), aCoords(2), aCoords(3) ) ) );
352         }
353         break;
354
355       case MeshVS_MSM_PRECISE:
356         {
357           Handle( Select3D_SensitiveEntity ) anEnt;
358           TColStd_MapIteratorOfPackedMapOfInteger anIterMV( anAllElementsMap );
359
360           TColStd_PackedMapOfInteger aSharedNodes;
361           for( ; anIterMV.More(); anIterMV.Next() )
362           {
363             Standard_Integer aKey = anIterMV.Key();
364
365             if( IsSelectableElem( aKey ) && 
366                 myDataSource->GetGeomType( aKey, Standard_True, aType ) && 
367                 aType==MeshVS_ET_Face )
368             {
369               myDataSource->GetGeom ( aKey, Standard_True, aCoords, NbNodes, aType );
370               if( NbNodes==0 )
371                 continue;
372
373               MeshVS_Buffer aNodesBuf (NbNodes*sizeof(Standard_Integer));
374               TColStd_Array1OfInteger aElemNodes(aNodesBuf, 1, NbNodes);
375               if ( !myDataSource->GetNodesByElement ( aKey, aElemNodes, NbNodes ) )
376                 continue;
377
378               TColgp_Array1OfPnt Points( 1, NbNodes );
379               for ( Standard_Integer i=1; i<=NbNodes; i++ )
380               {
381                 Points (i) = gp_Pnt ( aCoords (3*i-2), aCoords (3*i-1), aCoords (3*i) );
382                 aSharedNodes.Add( aElemNodes( i ) );
383               }
384
385               anEnt = new Select3D_SensitiveFace( myWholeMeshOwner, Points );
386               theSelection->Add( anEnt );
387             }
388           }
389           for( anIterMV.Initialize( anAllElementsMap ); anIterMV.More(); anIterMV.Next() )
390           {
391             Standard_Integer aKey = anIterMV.Key();
392
393             if( IsSelectableElem( aKey ) && 
394                 myDataSource->GetGeomType( aKey, Standard_True, aType ) && 
395                 aType==MeshVS_ET_Link )
396             {
397               myDataSource->GetGeom ( aKey, Standard_True, aCoords, NbNodes, aType );
398               if( NbNodes==0 )
399                 continue;
400
401               MeshVS_Buffer aNodesBuf (NbNodes*sizeof(Standard_Integer));
402               TColStd_Array1OfInteger aElemNodes(aNodesBuf, 1, NbNodes);
403               if ( !myDataSource->GetNodesByElement ( aKey, aElemNodes, NbNodes ) )
404                 continue;
405
406               TColgp_Array1OfPnt Points( 1, NbNodes );
407               Standard_Boolean all_shared = Standard_True;
408               for ( Standard_Integer i=1; i<=NbNodes; i++ )
409               {
410                 Points (i) = gp_Pnt ( aCoords (3*i-2), aCoords (3*i-1), aCoords (3*i) );
411                 all_shared = all_shared && aSharedNodes.Contains( aElemNodes( i ) );
412                 aSharedNodes.Add( aElemNodes( i ) );
413               }
414
415               if( !all_shared )
416               {
417                 anEnt = new Select3D_SensitiveSegment( myWholeMeshOwner, Points.Value( 1 ), Points.Value( 2 ) );
418                 theSelection->Add( anEnt );
419               }
420             }
421           }
422           for( anIterMV.Initialize( anAllNodesMap ); anIterMV.More(); anIterMV.Next() )
423           {
424             Standard_Integer aKey = anIterMV.Key();
425             if( IsSelectableElem( aKey ) && 
426                 myDataSource->GetGeom ( aKey, Standard_False, aCoords, NbNodes, aType ) && 
427                 !aSharedNodes.Contains( aKey ) )
428             {
429               anEnt = new Select3D_SensitivePoint( myWholeMeshOwner, gp_Pnt ( aCoords(1), aCoords(2), aCoords(3) ) ) ;
430               theSelection->Add( anEnt );
431             }
432           }
433         }
434         break;
435       }
436       break;
437
438     case MeshVS_SMF_Group:
439       {
440         myGroupOwners.Clear();
441
442         TColStd_PackedMapOfInteger anAllGroupsMap;
443         aSource->GetAllGroups( anAllGroupsMap );
444
445         Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
446
447         for ( anIter.Initialize( anAllGroupsMap ); anIter.More(); anIter.Next() )
448         {
449           Standard_Integer aKeyGroup = anIter.Key();
450
451           MeshVS_EntityType aGroupType;
452           TColStd_PackedMapOfInteger aGroupMap;
453           if ( !myDataSource->GetGroup( aKeyGroup, aGroupType, aGroupMap ) )
454             continue;
455
456           anAddr = myDataSource->GetGroupAddr ( aKeyGroup );
457           Standard_Integer aPrior = 0;
458
459           if( aGroupType == MeshVS_ET_Volume )
460             aPrior = 1;
461           if ( aGroupType == MeshVS_ET_Face )
462             aPrior = 2;
463           else if ( aGroupType == MeshVS_ET_Link )
464             aPrior = 3;
465           else if ( aGroupType == MeshVS_ET_0D )
466             aPrior = 4;
467           else if ( aGroupType == MeshVS_ET_Node )
468             aPrior = 5;
469
470           Handle (MeshVS_MeshEntityOwner) anOwner = new MeshVS_MeshEntityOwner
471             ( this, aKeyGroup, anAddr, aGroupType, aPrior, Standard_True );
472
473           myGroupOwners.Bind( aKeyGroup, anOwner );
474
475           Standard_Boolean added = Standard_False;
476           for ( TColStd_MapIteratorOfPackedMapOfInteger anIterMG (aGroupMap);
477                 anIterMG.More(); anIterMG.Next() )
478           {
479             Standard_Integer aKey = anIterMG.Key();
480             if ( aGroupType == MeshVS_ET_Node ) {
481               if( myDataSource->GetGeom( aKey, Standard_False, aCoords, NbNodes, aType ) &&
482                   IsSelectableNode/*!IsHiddenNode*/( aKey ) ) {
483                 theSelection->Add( new Select3D_SensitivePoint( anOwner, gp_Pnt ( aCoords(1), aCoords(2), aCoords(3) ) ) );
484                 added = Standard_True;
485               }
486             }
487             else if ( myDataSource->GetGeomType ( aKey, Standard_True, aType ) &&
488                       IsSelectableElem/*!IsHiddenElem*/( aKey ) ) {
489               myDataSource->GetGeom ( aKey, Standard_True, aCoords, NbNodes, aType );
490
491               TColgp_Array1OfPnt anArr( 1, NbNodes );
492               for ( Standard_Integer i=1; i<=NbNodes; i++ )
493               {
494                 x = aCoords(3*i-2);
495                 y = aCoords(3*i-1);
496                 z = aCoords(3*i);
497                 anArr.SetValue ( i, gp_Pnt ( x, y, z ) );
498               }
499
500               if ( aType == MeshVS_ET_Face && NbNodes > 0 )      // Faces: 2D-elements
501               {
502                 Handle (MeshVS_SensitiveFace) aFace = 
503                   new MeshVS_SensitiveFace( anOwner, anArr );
504                 theSelection->Add ( aFace );
505                 added = Standard_True;
506               }
507               else if ( aType == MeshVS_ET_Link && NbNodes > 0 ) // Links: 1D-elements
508               {
509                 Handle (MeshVS_SensitiveSegment) aSeg = new MeshVS_SensitiveSegment
510                   ( anOwner, anArr(1), anArr(2) );
511                 theSelection->Add ( aSeg );
512                 added = Standard_True;
513               }
514               else if( aType == MeshVS_ET_Volume && aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
515               {
516                 Handle( MeshVS_SensitivePolyhedron ) aPolyhedron = 
517                   new MeshVS_SensitivePolyhedron( anOwner, anArr, aTopo );
518                 theSelection->Add( aPolyhedron );
519                 added = Standard_True;
520               }
521               else //if ( aType == MeshVS_ET_0D )   // Custom : not only 0D-elements !!!
522               {
523                 Handle (SelectBasics_SensitiveEntity) anEnt =
524                   myHilighter->CustomSensitiveEntity ( anOwner, aKey );
525                 if (!anEnt.IsNull()) {
526                   theSelection->Add ( anEnt );
527                   added = Standard_True;
528                 }
529               }
530             }
531           }
532           if ( !added )
533             theSelection->Add ( new MeshVS_DummySensitiveEntity ( anOwner ) );
534         }
535       }
536       break;
537
538     default: // all residuary modes
539       {
540         Handle( MeshVS_HArray1OfSequenceOfInteger ) aTopo;
541
542         myElementOwners.Clear();
543
544         MeshVS_DataMapOfIntegerOwner* CurMap = &my0DOwners;
545         if ( theMode == MeshVS_ET_Link )
546           CurMap = &myLinkOwners;
547         else if ( theMode == MeshVS_ET_Face )
548           CurMap = &myFaceOwners;
549         else if ( theMode == MeshVS_ET_Volume )
550           CurMap = &myVolumeOwners;
551
552         CurMap->Clear();
553
554         for (TColStd_MapIteratorOfPackedMapOfInteger anIterMV (anAllElementsMap);
555              anIterMV.More(); anIterMV.Next() )
556         {
557           Standard_Integer aKey = anIterMV.Key();
558
559           if ( myDataSource->GetGeomType ( aKey, Standard_True, aType ) && theMode == aType )
560           {
561             myDataSource->GetGeom ( aKey, Standard_True, aCoords, NbNodes, aType );
562             anAddr = myDataSource->GetAddr ( aKey, Standard_True );
563
564             Standard_Integer aPrior = 0;
565
566             if( aType == MeshVS_ET_Volume )
567               aPrior = 1;
568             if ( aType == MeshVS_ET_Face )
569               aPrior = 2;
570             else if ( aType == MeshVS_ET_Link )
571               aPrior = 3;
572             else if ( aType == MeshVS_ET_0D )
573               aPrior = 4;
574
575             Handle (MeshVS_MeshEntityOwner) anOwner = new MeshVS_MeshEntityOwner
576               ( this, aKey, anAddr, aType, aPrior );
577
578             CurMap->Bind ( aKey, anOwner );
579
580             if ( IsSelectableElem( aKey ) ) //The element is selectable
581             {
582               TColgp_Array1OfPnt anArr( 1, NbNodes );
583               for ( Standard_Integer i=1; i<=NbNodes; i++ )
584               {
585                 x = aCoords(3*i-2);
586                 y = aCoords(3*i-1);
587                 z = aCoords(3*i);
588                 anArr.SetValue ( i, gp_Pnt ( x, y, z ) );
589               }
590
591               if ( aType == MeshVS_ET_Face && NbNodes > 0 )      // Faces: 2D-elements
592               {
593                 Handle (MeshVS_SensitiveFace) aFace = 
594                   new MeshVS_SensitiveFace( anOwner, anArr );
595                 theSelection->Add ( aFace );
596               }
597               else if ( aType == MeshVS_ET_Link && NbNodes > 0 ) // Links: 1D-elements
598               {
599                 Handle (MeshVS_SensitiveSegment) aSeg = new MeshVS_SensitiveSegment
600                   ( anOwner, anArr(1), anArr(2) );
601                 theSelection->Add ( aSeg );
602               }
603               else if( aType == MeshVS_ET_Volume && aSource->Get3DGeom( aKey, NbNodes, aTopo ) )
604               {
605                 Handle( MeshVS_SensitivePolyhedron ) aPolyhedron = 
606                   new MeshVS_SensitivePolyhedron( anOwner, anArr, aTopo );
607                 theSelection->Add( aPolyhedron );
608               }
609               else //if ( aType == MeshVS_ET_0D )   // Custom : not only 0D-elements !!!
610               {
611                 Handle (SelectBasics_SensitiveEntity) anEnt =
612                   myHilighter->CustomSensitiveEntity ( anOwner, aKey );
613                 if (!anEnt.IsNull())
614                   theSelection->Add ( anEnt );
615               }
616             }
617             else
618               theSelection->Add ( new MeshVS_DummySensitiveEntity ( anOwner ) );
619           }
620         }
621       }
622       break;
623     }
624   }
625
626   if ( ShowComputeSelectionTime )
627   {
628     Standard_Real sec, cpu;
629     Standard_Integer min, hour;
630
631     gTimer.Show ( sec, min, hour, cpu );
632     cout << "SelectionMode : " << theMode << endl;
633     cout << "Compute selection: " << sec << " sec" << endl;
634     cout << "Compute selection CPU : " << cpu << " sec" << endl << endl;
635     gTimer.Stop();
636   }
637 }
638
639 //================================================================
640 // Function : GetBuildersCount
641 // Purpose  :
642 //================================================================
643 Standard_Integer MeshVS_Mesh::GetBuildersCount () const
644 {
645   return myBuilders.Length();
646 }
647
648 //================================================================
649 // Function : GetFreeId
650 // Purpose  :
651 //================================================================
652 Standard_Integer MeshVS_Mesh::GetFreeId () const
653 {
654   TColStd_PackedMapOfInteger Ids;
655   Standard_Integer i, len = myBuilders.Length(), curId;
656
657   for ( i=1; i<=len; i++ )
658     Ids.Add( myBuilders.Value(i)->GetId () );
659
660   curId = 0;
661   while ( Ids.Contains( curId ) )
662     curId++;
663
664   return curId;
665 }
666
667 //================================================================
668 // Function : GetBuilder
669 // Purpose  :
670 //================================================================
671 Handle (MeshVS_PrsBuilder) MeshVS_Mesh::GetBuilder ( const Standard_Integer Index ) const
672 {
673   if ( Index>=1 && Index<=myBuilders.Length() )
674     return myBuilders.Value( Index );
675   else
676     return 0;
677 }
678
679 //================================================================
680 // Function : GetBuilderById
681 // Purpose  :
682 //================================================================
683 Handle (MeshVS_PrsBuilder) MeshVS_Mesh::GetBuilderById ( const Standard_Integer Id ) const
684 {
685   Handle (MeshVS_PrsBuilder) Result;
686
687   Standard_Integer i, len = myBuilders.Length();
688   for ( i=1; i<=len; i++ )
689     if ( myBuilders.Value(i)->GetId () == Id )
690     {
691       Result = myBuilders.Value(i);
692       break;
693     }
694   return Result;
695 }
696
697 //================================================================
698 // Function : AddBuilder
699 // Purpose  :
700 //================================================================
701 void MeshVS_Mesh::AddBuilder ( const Handle (MeshVS_PrsBuilder)& theBuilder,
702                                const Standard_Boolean TreatAsHilighter )
703 {
704   if ( theBuilder.IsNull() )
705     return;
706
707   Standard_Integer i, n = myBuilders.Length();
708   for ( i = 1; i<=n; i++ )
709     if ( myBuilders(i)->GetPriority() < theBuilder->GetPriority() )
710       break;
711
712   if ( i>n )
713     myBuilders.Append ( theBuilder );
714   else
715     myBuilders.InsertBefore ( i, theBuilder );
716
717   if( TreatAsHilighter )
718     myHilighter = theBuilder;
719 }
720
721 //================================================================
722 // Function : RemoveBuilder
723 // Purpose  :
724 //================================================================
725 void MeshVS_Mesh::RemoveBuilder ( const Standard_Integer theIndex )
726 {
727   Handle( MeshVS_PrsBuilder ) aBuild = GetBuilder( theIndex );
728   if ( !aBuild.IsNull() )
729   {
730     if ( aBuild == myHilighter )
731       myHilighter.Nullify();
732     myBuilders.Remove ( theIndex );
733   }
734 }
735
736 //================================================================
737 // Function : RemoveBuilderById
738 // Purpose  :
739 //================================================================
740 void MeshVS_Mesh::RemoveBuilderById ( const Standard_Integer Id )
741 {
742   Standard_Integer i, n = myBuilders.Length();
743   for ( i=1; i<=n; i++ )
744   {
745     Handle( MeshVS_PrsBuilder ) aCur = myBuilders(i);
746     if ( !aCur.IsNull() && aCur->GetId()==Id )
747       break;
748   }
749   if ( i>=1 && i<=n )
750   {
751     if ( GetBuilder( i )==myHilighter )
752       myHilighter.Nullify();
753     RemoveBuilder ( i );
754   }
755 }
756
757 //================================================================
758 // Function : SetHiddenElems
759 // Purpose  :
760 //================================================================
761 void MeshVS_Mesh::SetHiddenElems ( const Handle(TColStd_HPackedMapOfInteger)& theMap )
762 {
763   myHiddenElements = theMap;
764
765   // Note: update of list of selectable nodes -- this is not optimal!
766   Standard_Boolean AutoSelUpdate = Standard_False;
767   if ( !GetDrawer().IsNull() && GetDrawer()->GetBoolean( MeshVS_DA_SelectableAuto, AutoSelUpdate ) &&
768        AutoSelUpdate )
769     UpdateSelectableNodes();
770 }
771
772 //================================================================
773 // Function : SetHiddenNodes
774 // Purpose  :
775 //================================================================
776 void MeshVS_Mesh::SetHiddenNodes ( const Handle(TColStd_HPackedMapOfInteger)& theMap )
777 {
778   myHiddenNodes = theMap;
779
780   // Note: update of list of selectable nodes -- this is not optimal!
781   Standard_Boolean AutoSelUpdate = Standard_False;
782   if ( !GetDrawer().IsNull() && GetDrawer()->GetBoolean( MeshVS_DA_SelectableAuto, AutoSelUpdate ) &&
783        AutoSelUpdate )
784     UpdateSelectableNodes();
785 }
786
787 //================================================================
788 // Function : GetHiddenElems
789 // Purpose  :
790 //================================================================
791 const Handle(TColStd_HPackedMapOfInteger)& MeshVS_Mesh::GetHiddenElems () const
792 {
793   return myHiddenElements;
794 }
795
796 //================================================================
797 // Function : GetHiddenNodes
798 // Purpose  :
799 //================================================================
800 const Handle(TColStd_HPackedMapOfInteger)& MeshVS_Mesh::GetHiddenNodes () const
801 {
802   return myHiddenNodes;
803 }
804
805 //================================================================
806 // Function : AddToMap
807 // Purpose  :
808 //================================================================
809 void AddToMap ( MeshVS_DataMapOfIntegerOwner& Result, const MeshVS_DataMapOfIntegerOwner& Addition )
810 {
811   MeshVS_DataMapIteratorOfDataMapOfIntegerOwner anIt ( Addition );
812   for ( ; anIt.More(); anIt.Next() )
813     if ( Result.IsBound ( anIt.Key() ) )
814       Result.ChangeFind ( anIt.Key() ) = anIt.Value();
815     else
816       Result.Bind( anIt.Key(), anIt.Value() );
817 }
818
819 //================================================================
820 // Function : GetOwnerMaps
821 // Purpose  :
822 //================================================================
823 const MeshVS_DataMapOfIntegerOwner& MeshVS_Mesh::GetOwnerMaps ( const Standard_Boolean IsElements )
824 {
825   Handle(MeshVS_DataSource) aDS = GetDataSource();
826   if( !aDS.IsNull() && aDS->IsAdvancedSelectionEnabled() )
827     return myMeshOwners;
828   if ( IsElements )
829   {
830     if ( myElementOwners.IsEmpty() )
831     {
832       AddToMap ( myElementOwners, my0DOwners );
833       AddToMap ( myElementOwners, myLinkOwners );
834       AddToMap ( myElementOwners, myFaceOwners );
835       AddToMap ( myElementOwners, myVolumeOwners );
836     }
837     return myElementOwners;
838   }
839   else
840     return myNodeOwners;
841 }
842
843 //================================================================
844 // Function : IsHiddenElem
845 // Purpose  :
846 //================================================================
847 Standard_Boolean MeshVS_Mesh::IsHiddenElem ( const Standard_Integer theID ) const
848 {
849   return ! myHiddenElements.IsNull() && myHiddenElements->Map().Contains( theID );
850 }
851
852 //================================================================
853 // Function : IsHiddenNode
854 // Purpose  :
855 //================================================================
856 Standard_Boolean MeshVS_Mesh::IsHiddenNode ( const Standard_Integer theID ) const
857 {
858   // note that by default all nodes are hidden
859   return myHiddenNodes.IsNull() || myHiddenNodes->Map().Contains( theID );
860 }
861
862 //================================================================
863 // Function : GetDrawer
864 // Purpose  :
865 //================================================================
866 Handle( MeshVS_Drawer ) MeshVS_Mesh::GetDrawer() const
867 {
868   return myCurrentDrawer;
869 }
870
871 //================================================================
872 // Function : SetDrawer
873 // Purpose  :
874 //================================================================
875 void MeshVS_Mesh::SetDrawer(const Handle(MeshVS_Drawer)& aDrawer)
876 {
877   myCurrentDrawer = aDrawer;
878 }
879
880 //================================================================
881 // Function : GetDataSource
882 // Purpose  :
883 //================================================================
884 Handle(MeshVS_DataSource) MeshVS_Mesh::GetDataSource() const
885 {
886   return myDataSource;
887 }
888
889 //================================================================
890 // Function : SetDataSource
891 // Purpose  :
892 //================================================================
893 void MeshVS_Mesh::SetDataSource( const Handle(MeshVS_DataSource)& theDataSource )
894 {
895   myDataSource = theDataSource;
896 }
897
898 //================================================================
899 // Function : HilightSelected
900 // Purpose  :
901 //================================================================
902 void MeshVS_Mesh::HilightSelected ( const Handle(PrsMgr_PresentationManager3d)& thePM,
903                                     const SelectMgr_SequenceOfOwner& theOwners )
904 {
905   if ( myHilighter.IsNull() )
906     return;
907
908 //  if ( mySelectionPrs.IsNull() )
909 //    mySelectionPrs = new Prs3d_Presentation ( thePM->StructureManager() );
910
911   //new functionality
912
913   Handle( Prs3d_Presentation ) aSelectionPrs;
914
915   aSelectionPrs = GetSelectPresentation( thePM );
916
917   if( HasPresentation() )
918     aSelectionPrs->SetTransformPersistence( Presentation()->TransformPersistenceMode(), Presentation()->TransformPersistencePoint() );
919   //----------------
920
921   //   It is very important to call this parent method, because it check whether
922   // mySelectionPrs is created and if not, create it.
923
924 #ifdef _DEBUG
925   OSD_Timer gTimer;
926   gTimer.Reset();
927   gTimer.Start();
928 #endif
929
930   Standard_Integer len = theOwners.Length(), i;
931
932   Handle (MeshVS_MeshEntityOwner) anOwner;
933   TColStd_PackedMapOfInteger aSelNodes, aSelElements;
934
935   for( i=1; i<=len; i++ )
936   {
937     anOwner = Handle (MeshVS_MeshEntityOwner)::DownCast ( theOwners.Value ( i ) );
938     if ( !anOwner.IsNull() )
939     {
940       // nkv: add support of mesh groups
941       if ( anOwner->IsGroup() ) {
942         MeshVS_EntityType aGroupType;
943         TColStd_PackedMapOfInteger aGroupMap;
944         if ( GetDataSource()->GetGroup( anOwner->ID(), aGroupType, aGroupMap ) ) {
945           if ( aGroupType == MeshVS_ET_Node ) {
946             for( TColStd_MapIteratorOfPackedMapOfInteger anIt(aGroupMap); anIt.More(); anIt.Next() )
947               if( IsSelectableNode/*!IsHiddenNode*/( anIt.Key() ) )
948                 aSelNodes.Add( anIt.Key() );
949           }
950           else {
951             for( TColStd_MapIteratorOfPackedMapOfInteger anIt(aGroupMap); anIt.More(); anIt.Next() )
952               if( IsSelectableElem/*!IsHiddenElem*/( anIt.Key() ) )
953                 aSelElements.Add( anIt.Key() );
954           }
955         }
956       }
957       else {
958         if( anOwner->Type() == MeshVS_ET_Node )
959           aSelNodes.Add( anOwner->ID() );
960         else
961           aSelElements.Add( anOwner->ID() );
962       }
963     }
964     else if( GetDataSource()->IsAdvancedSelectionEnabled() )
965     {
966       Handle(MeshVS_MeshOwner) aMeshOwner = Handle(MeshVS_MeshOwner)::DownCast ( theOwners.Value ( i ) );
967       if( !aMeshOwner.IsNull() )
968       {
969         Handle(TColStd_HPackedMapOfInteger) aNodes = aMeshOwner->GetSelectedNodes();
970         Handle(TColStd_HPackedMapOfInteger) aElems = aMeshOwner->GetSelectedElements();
971         if( !aNodes.IsNull() )
972           aSelNodes.Assign( aNodes->Map() );
973         if( !aElems.IsNull() )
974           aSelElements.Assign( aElems->Map() );
975       }
976     }
977 //agv    else if( theOwners.Value ( i )==myWholeMeshOwner )
978     else if (IsWholeMeshOwner (theOwners.Value ( i )))
979     {
980       TColStd_MapIteratorOfPackedMapOfInteger anIt(GetDataSource()->GetAllNodes());
981       for( ; anIt.More(); anIt.Next() )
982         if( !IsHiddenNode( anIt.Key() ) )
983           aSelNodes.Add( anIt.Key() );
984
985       anIt = TColStd_MapIteratorOfPackedMapOfInteger( GetDataSource()->GetAllElements() );
986       for( ; anIt.More(); anIt.Next() )
987         if( !IsHiddenElem( anIt.Key() ) )
988           aSelElements.Add( anIt.Key() );
989
990       break;
991     }
992   }
993
994   Standard_Boolean IsNeedToRedisplay = Standard_False;
995
996   aSelectionPrs->Clear();
997
998   myHilighter->SetDrawer ( mySelectionDrawer );
999
1000   if( aSelNodes.Extent()>0 )
1001   {
1002     TColStd_PackedMapOfInteger tmp;
1003     myHilighter->Build ( aSelectionPrs, aSelNodes, tmp, Standard_False, MeshVS_DMF_SelectionPrs );
1004   }
1005   if( aSelElements.Extent()>0 )
1006   {
1007     TColStd_PackedMapOfInteger tmp;
1008     myHilighter->Build( aSelectionPrs, aSelElements, tmp, Standard_True, MeshVS_DMF_SelectionPrs );
1009   }
1010
1011   myHilighter->SetDrawer ( 0 );
1012
1013   IsNeedToRedisplay = Standard_True;
1014
1015   if ( IsNeedToRedisplay )
1016   {
1017     aSelectionPrs->SetDisplayPriority(9);
1018     aSelectionPrs->Display();
1019   }
1020
1021 #ifdef _DEBUG
1022     Standard_Real sec, cpu;
1023     Standard_Integer min, hour;
1024
1025     gTimer.Show ( sec, min, hour, cpu );
1026     cout << "HilightSelected : " << endl;
1027     cout << aSelNodes.Extent() << " nodes " << endl;
1028     cout << aSelElements.Extent() << " elements " << endl;
1029     cout << "Time : " << sec << " sec" << endl;
1030     cout << "CPU time : " << cpu << " sec" << endl << endl;
1031     gTimer.Stop();
1032 #endif
1033 }
1034
1035 //================================================================
1036 // Function : HilightOwnerWithColor
1037 // Purpose  :
1038 //================================================================
1039 void MeshVS_Mesh::HilightOwnerWithColor ( const Handle(PrsMgr_PresentationManager3d)& PM,
1040                                           const Quantity_NameOfColor Color,
1041                                           const Handle(SelectMgr_EntityOwner)& Owner)
1042 {
1043   if ( myHilighter.IsNull() )
1044     return;
1045
1046   SelectMgr_SequenceOfOwner theOwners;
1047   //new functionality
1048
1049   //if ( myHilightPrs.IsNull() )
1050   //  myHilightPrs = new Prs3d_Presentation ( PM->StructureManager() );
1051
1052   Handle( Prs3d_Presentation ) aHilightPrs;
1053   aHilightPrs = GetHilightPresentation( PM );
1054
1055   aHilightPrs->Clear();
1056
1057   //new functionality
1058   if( HasPresentation() )
1059     aHilightPrs->SetTransformPersistence( Presentation()->TransformPersistenceMode(), Presentation()->TransformPersistencePoint() );
1060   //----------------
1061
1062   if( Owner.IsNull() ) return;
1063
1064   const Standard_Boolean isMeshEntityOwner = Owner->IsKind ( STANDARD_TYPE ( MeshVS_MeshEntityOwner ) );
1065   const Standard_Boolean isWholeMeshOwner =
1066 //agv    !Owner.IsNull() && Owner==myWholeMeshOwner;
1067     IsWholeMeshOwner (Owner);
1068
1069   Standard_Integer aDispMode = MeshVS_DMF_Shading;
1070   if ( HasDisplayMode() && ( DisplayMode() & MeshVS_DMF_OCCMask ) > MeshVS_DMF_WireFrame )
1071     aDispMode = ( DisplayMode() & MeshVS_DMF_OCCMask );
1072   //It because we draw hilighted owners only in shading or shrink (not in wireframe)
1073
1074   myHilightDrawer->SetColor( MeshVS_DA_InteriorColor, Color );
1075   myHilightDrawer->SetColor( MeshVS_DA_BackInteriorColor, Color );
1076   myHilightDrawer->SetColor( MeshVS_DA_EdgeColor, Color );
1077   myHilightDrawer->SetColor( MeshVS_DA_BeamColor, Color );
1078   myHilightDrawer->SetColor( MeshVS_DA_MarkerColor, Color );
1079   myHilighter->SetDrawer( myHilightDrawer );
1080
1081   if( isMeshEntityOwner )
1082   {
1083     Handle ( MeshVS_MeshEntityOwner ) theAISOwner = Handle ( MeshVS_MeshEntityOwner )::DownCast ( Owner );
1084     MeshVS_EntityType aType = theAISOwner->Type();
1085     Standard_Integer  anID  = theAISOwner->ID();
1086
1087     if ( theAISOwner->IsGroup() ) {
1088       MeshVS_EntityType aGroupType;
1089       TColStd_PackedMapOfInteger aGroupMap;
1090       if ( myDataSource->GetGroup( anID, aGroupType, aGroupMap ) ) {
1091         TColStd_PackedMapOfInteger tmp;
1092         myHilighter->Build( aHilightPrs, aGroupMap, tmp, aType!=MeshVS_ET_Node,
1093                             aDispMode | MeshVS_DMF_HilightPrs );
1094       }
1095     }
1096     else {
1097       TColStd_PackedMapOfInteger anOne, tmp;
1098       anOne.Add (anID);
1099       myHilighter->Build( aHilightPrs, anOne, tmp, aType!=MeshVS_ET_Node,
1100                           aDispMode | MeshVS_DMF_HilightPrs );
1101     }
1102   }
1103   else if( isWholeMeshOwner  )
1104   {
1105     if( ! GetDataSource().IsNull() )
1106     {
1107       TColStd_PackedMapOfInteger tmp;
1108       myHilighter->Build( aHilightPrs, GetDataSource()->GetAllElements(), tmp,
1109                           Standard_True, MeshVS_DMF_WireFrame );
1110     }
1111   }
1112   else 
1113   {
1114     Handle(MeshVS_MeshOwner) aMeshOwner = Handle(MeshVS_MeshOwner)::DownCast ( Owner );
1115     if( !aMeshOwner.IsNull() )
1116     {
1117       Handle(TColStd_HPackedMapOfInteger) aNodes = aMeshOwner->GetDetectedNodes();
1118       Handle(TColStd_HPackedMapOfInteger) aElems = aMeshOwner->GetDetectedElements();
1119       // hilight detected entities
1120       if( !aNodes.IsNull() )
1121       {
1122         TColStd_PackedMapOfInteger tmp;
1123         myHilighter->Build( aHilightPrs, aNodes->Map(), tmp, Standard_False,
1124                             aDispMode | MeshVS_DMF_HilightPrs );
1125       }
1126       if( !aElems.IsNull() )
1127       {
1128         TColStd_PackedMapOfInteger tmp;
1129         myHilighter->Build( aHilightPrs, aElems->Map(), tmp, Standard_True,
1130                             aDispMode | MeshVS_DMF_HilightPrs );
1131       }
1132     }    
1133   }
1134
1135   if( PM->IsImmediateModeOn() )
1136     PM->AddToImmediateList( aHilightPrs );
1137   myHilighter->SetDrawer ( 0 );
1138 }
1139
1140 //=======================================================================
1141 //function : ClearSelected
1142 //purpose  :
1143 //=======================================================================
1144 void MeshVS_Mesh::ClearSelected ()
1145 {
1146   Handle( Prs3d_Presentation ) aSelectionPrs = GetSelectPresentation( NULL );  
1147   if( !aSelectionPrs.IsNull() )
1148     aSelectionPrs->Clear(); 
1149 }
1150
1151 //=======================================================================
1152 //function : FindBuilder
1153 //purpose  :
1154 //=======================================================================
1155 Handle (MeshVS_PrsBuilder) MeshVS_Mesh::FindBuilder ( const Standard_CString theTypeName ) const
1156 {
1157   Standard_Integer len = myBuilders.Length();
1158   Handle(MeshVS_PrsBuilder) aBuilder;
1159   Standard_Boolean IsExist = Standard_False;
1160
1161   for ( Standard_Integer i=1; i<=len && !IsExist; i++)
1162     if ( myBuilders.Value (i)->IsKind ( theTypeName ) )
1163     {
1164       aBuilder = myBuilders.Value (i);
1165       IsExist = Standard_True;
1166     }
1167
1168   return aBuilder;
1169 }
1170
1171 //=======================================================================
1172 //function : SetHilighter
1173 //purpose  :
1174 //=======================================================================
1175 void MeshVS_Mesh::SetHilighter ( const Handle( MeshVS_PrsBuilder )& Builder )
1176 {
1177   myHilighter = Builder;
1178 }
1179
1180 //=======================================================================
1181 //function : SetHilighter
1182 //purpose  :
1183 //=======================================================================
1184 Standard_Boolean MeshVS_Mesh::SetHilighter ( const Standard_Integer Index )
1185 {
1186   Handle( MeshVS_PrsBuilder ) aBuild = GetBuilder( Index );
1187   Standard_Boolean aRes = ( !aBuild.IsNull() );
1188   if ( aRes )
1189     myHilighter = aBuild;
1190   return aRes;
1191 }
1192
1193 //=======================================================================
1194 //function : SetHilighter
1195 //purpose  :
1196 //=======================================================================
1197 Standard_Boolean MeshVS_Mesh::SetHilighterById ( const Standard_Integer Id )
1198 {
1199   Handle( MeshVS_PrsBuilder ) aBuild = GetBuilderById( Id );
1200   Standard_Boolean aRes = ( !aBuild.IsNull() );
1201   if ( aRes )
1202     myHilighter = aBuild;
1203   return aRes;
1204 }
1205
1206 //=======================================================================
1207 //function : GetHilighter
1208 //purpose  :
1209 //=======================================================================
1210 Handle( MeshVS_PrsBuilder ) MeshVS_Mesh::GetHilighter () const
1211 {
1212   return myHilighter;
1213 }
1214
1215 //=======================================================================
1216 //function : IsSelectableElem
1217 //purpose  :
1218 //=======================================================================
1219 Standard_Boolean MeshVS_Mesh::IsSelectableElem ( const Standard_Integer ID ) const
1220 {
1221   return ! IsHiddenElem ( ID );
1222 }
1223
1224 //=======================================================================
1225 //function : IsSelectableNode
1226 //purpose  :
1227 //=======================================================================
1228 Standard_Boolean MeshVS_Mesh::IsSelectableNode ( const Standard_Integer ID ) const
1229 {
1230   return mySelectableNodes.IsNull() ? ! IsHiddenNode ( ID ) : 
1231                                       mySelectableNodes->Map().Contains( ID );
1232 }
1233
1234 //=======================================================================
1235 //function : GetSelectableNodes
1236 //purpose  :
1237 //=======================================================================
1238 const Handle(TColStd_HPackedMapOfInteger)& MeshVS_Mesh::GetSelectableNodes () const
1239 {
1240   return mySelectableNodes;
1241 }
1242
1243 //=======================================================================
1244 //function : SetSelectableNodes
1245 //purpose  :
1246 //=======================================================================
1247 void MeshVS_Mesh::SetSelectableNodes ( const Handle(TColStd_HPackedMapOfInteger)& Ids )
1248 {
1249   mySelectableNodes = Ids;
1250 }
1251
1252 //=======================================================================
1253 //function : UpdateSelectableNodes
1254 //purpose  :
1255 //=======================================================================
1256 void MeshVS_Mesh::UpdateSelectableNodes()
1257 {
1258   mySelectableNodes = new TColStd_HPackedMapOfInteger;
1259   
1260   Standard_Integer aMaxFaceNodes;
1261   Handle( MeshVS_DataSource ) aSource = GetDataSource();
1262   if ( aSource.IsNull() || myCurrentDrawer.IsNull() || !myCurrentDrawer->GetInteger
1263          ( MeshVS_DA_MaxFaceNodes, aMaxFaceNodes ) || aMaxFaceNodes<=0 )
1264     return;
1265
1266   // all non-hidden nodes are selectable;
1267   // by default (i.e. if myHiddenNodes.IsNull()) all nodes are hidden
1268   if ( ! myHiddenNodes.IsNull() )
1269   {
1270     mySelectableNodes->ChangeMap().Subtraction (aSource->GetAllNodes(),
1271                                                 myHiddenNodes->Map());
1272   } 
1273
1274   // add all nodes belonging to non-hidden elements
1275   TColStd_MapIteratorOfPackedMapOfInteger anIter( aSource->GetAllElements() );
1276   for ( ; anIter.More(); anIter.Next() )
1277   {
1278     Standard_Integer aKey = anIter.Key();
1279     if ( IsHiddenElem (aKey) )
1280       continue;
1281
1282     MeshVS_Buffer aNodesBuf (aMaxFaceNodes*sizeof(Standard_Integer));
1283     TColStd_Array1OfInteger aNodes (aNodesBuf, 1, aMaxFaceNodes);
1284     Standard_Integer NbNodes;
1285     if ( !aSource->GetNodesByElement ( aKey, aNodes, NbNodes ) )
1286       continue;
1287     for ( Standard_Integer i=1; i<=NbNodes; i++ )
1288       mySelectableNodes->ChangeMap().Add ( aNodes(i) );
1289   }
1290 }
1291
1292 //=======================================================================
1293 //function : GetMeshSelMethod
1294 //purpose  :
1295 //=======================================================================
1296 MeshVS_MeshSelectionMethod MeshVS_Mesh::GetMeshSelMethod() const
1297 {
1298   return mySelectionMethod;
1299 }
1300
1301 //=======================================================================
1302 //function : SetMeshSelMethod
1303 //purpose  :
1304 //=======================================================================
1305 void MeshVS_Mesh::SetMeshSelMethod( const MeshVS_MeshSelectionMethod M )
1306 {
1307   mySelectionMethod = M;
1308 }
1309
1310 //=======================================================================
1311 //function : IsWholeMeshOwner
1312 //purpose  : 
1313 //=======================================================================
1314
1315 Standard_Boolean MeshVS_Mesh::IsWholeMeshOwner
1316                             (const Handle(SelectMgr_EntityOwner)& theOwn) const
1317 {
1318   return theOwn.IsNull() ? Standard_False : (theOwn == myWholeMeshOwner);
1319 }