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