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