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