0030675: Visualization - remove redundant proxy classes in hierarchy of PrsMgr_Presen...
[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_PresentationManager3d.hxx>
48 #include <Select3D_SensitiveBox.hxx>
49 #include <Select3D_SensitiveGroup.hxx>
50 #include <Select3D_SensitivePoint.hxx>
51 #include <Select3D_SensitiveTriangle.hxx>
52 #include <SelectBasics_SensitiveEntity.hxx>
53 #include <SelectMgr_EntityOwner.hxx>
54 #include <SelectMgr_Selection.hxx>
55 #include <SelectMgr_SequenceOfOwner.hxx>
56 #include <Standard_Type.hxx>
57 #include <StdSelect_BRepSelectionTool.hxx>
58 #include <TColgp_Array1OfPnt.hxx>
59 #include <TColStd_Array1OfInteger.hxx>
60 #include <TColStd_Array1OfReal.hxx>
61 #include <TColStd_HPackedMapOfInteger.hxx>
62 #include <TColStd_ListIteratorOfListOfInteger.hxx>
63 #include <TColStd_ListIteratorOfListOfReal.hxx>
64 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
65 #include <TColStd_SequenceOfInteger.hxx>
66
67 IMPLEMENT_STANDARD_RTTIEXT(MeshVS_Mesh,AIS_InteractiveObject)
68
69 //================================================================
70 // Function : Constructor MeshVS_Mesh
71 // Purpose  :
72 //================================================================
73 MeshVS_Mesh::MeshVS_Mesh (const Standard_Boolean theIsAllowOverlapped )
74 {
75   myDataSource.Nullify();
76   myHilighter.Nullify();
77   myWholeMeshOwner.Nullify();
78   mySelectionMethod = MeshVS_MSM_NODES;
79
80   SetAutoHilight ( Standard_False );
81
82   SetDisplayMode( MeshVS_DMF_WireFrame ); // Mode as defaut
83   SetHilightMode( MeshVS_DMF_WireFrame ); // Wireframe as default hilight mode
84
85   SetColor ( Quantity_NOC_WHITE );
86   SetMaterial ( Graphic3d_NOM_PLASTIC );
87
88   myCurrentDrawer = new MeshVS_Drawer();
89   myCurrentDrawer->SetColor   ( MeshVS_DA_InteriorColor, Quantity_NOC_BLUE4 );
90   myCurrentDrawer->SetInteger ( MeshVS_DA_InteriorStyle, Aspect_IS_SOLID );
91   myCurrentDrawer->SetInteger ( MeshVS_DA_MaxFaceNodes, 10 );
92   myCurrentDrawer->SetBoolean ( MeshVS_DA_IsAllowOverlapped, theIsAllowOverlapped );
93   myCurrentDrawer->SetBoolean ( MeshVS_DA_Reflection, Standard_True );
94   myCurrentDrawer->SetDouble  ( MeshVS_DA_ShrinkCoeff, 0.8 );
95   myCurrentDrawer->SetBoolean ( MeshVS_DA_ComputeTime, Standard_False );
96   myCurrentDrawer->SetBoolean ( MeshVS_DA_ComputeSelectionTime, Standard_False );
97   myCurrentDrawer->SetBoolean ( MeshVS_DA_DisplayNodes, Standard_True );
98   myCurrentDrawer->SetDouble  ( MeshVS_DA_EdgeWidth, 1.0 );
99   myCurrentDrawer->SetInteger ( MeshVS_DA_EdgeType, Aspect_TOL_SOLID );
100   myCurrentDrawer->SetInteger ( MeshVS_DA_MarkerType,  Aspect_TOM_O );
101   myCurrentDrawer->SetColor   ( MeshVS_DA_MarkerColor, Quantity_NOC_WHITE );
102   myCurrentDrawer->SetDouble  ( MeshVS_DA_MarkerScale, 1.0 );
103   myCurrentDrawer->SetInteger ( MeshVS_DA_BeamType, Aspect_TOL_SOLID );
104   myCurrentDrawer->SetDouble  ( MeshVS_DA_BeamWidth, 1.0 );
105   myCurrentDrawer->SetBoolean ( MeshVS_DA_SmoothShading, Standard_False );
106   myCurrentDrawer->SetBoolean ( MeshVS_DA_SupressBackFaces, Standard_False );
107
108   mySelectionDrawer = new MeshVS_Drawer();
109   mySelectionDrawer->Assign ( myCurrentDrawer );
110   mySelectionDrawer->SetInteger ( MeshVS_DA_MarkerType,  Aspect_TOM_STAR );
111   mySelectionDrawer->SetColor   ( MeshVS_DA_MarkerColor, Quantity_NOC_GRAY80 );
112   mySelectionDrawer->SetDouble  ( MeshVS_DA_MarkerScale, 2.0 );
113
114   mySelectionDrawer->SetColor   ( MeshVS_DA_BeamColor, Quantity_NOC_GRAY80 );
115   mySelectionDrawer->SetInteger ( MeshVS_DA_BeamType,  Aspect_TOL_SOLID );
116   mySelectionDrawer->SetDouble  ( MeshVS_DA_BeamWidth, 3.0 );
117
118   myHilightDrawer = new MeshVS_Drawer ();
119   myHilightDrawer->Assign ( myCurrentDrawer );
120   myHilightDrawer->SetDouble   ( MeshVS_DA_ShrinkCoeff, 0.7 );
121   myHilightDrawer->SetInteger  ( MeshVS_DA_InteriorStyle, Aspect_IS_SOLID );
122   myHilightDrawer->SetColor    ( MeshVS_DA_InteriorColor, Quantity_NOC_YELLOW );
123   myHilightDrawer->SetColor    ( MeshVS_DA_BackInteriorColor, Quantity_NOC_YELLOW );
124   myHilightDrawer->SetColor    ( MeshVS_DA_EdgeColor, Quantity_NOC_GREEN );
125   myHilightDrawer->SetInteger  ( MeshVS_DA_EdgeType, Aspect_TOL_SOLID );
126   myHilightDrawer->SetDouble   ( MeshVS_DA_EdgeWidth, 1.0 );
127   myHilightDrawer->SetMaterial ( MeshVS_DA_FrontMaterial, Graphic3d_NOM_PLASTIC );
128   myHilightDrawer->SetMaterial ( MeshVS_DA_BackMaterial, Graphic3d_NOM_PLASTIC );
129
130   myHilightDrawer->SetColor   ( MeshVS_DA_BeamColor, Quantity_NOC_GRAY80 );
131   myHilightDrawer->SetInteger ( MeshVS_DA_BeamType,  Aspect_TOL_SOLID );
132   myHilightDrawer->SetDouble  ( MeshVS_DA_BeamWidth, 3.0 );
133
134   myHilightDrawer->SetInteger ( MeshVS_DA_MarkerType,  Aspect_TOM_STAR );
135   myHilightDrawer->SetColor   ( MeshVS_DA_MarkerColor, Quantity_NOC_GRAY80 );
136   myHilightDrawer->SetDouble  ( MeshVS_DA_MarkerScale, 2.0 );
137 }
138
139 //================================================================
140 // Function : AcceptDisplayMode
141 // Purpose  :
142 //================================================================
143 Standard_Boolean MeshVS_Mesh::AcceptDisplayMode (const Standard_Integer theMode) const
144 {
145   if (theMode <= 0)
146   {
147     return Standard_False;
148   }
149   else if (myBuilders.IsEmpty())
150   {
151     return Standard_True;
152   }
153
154   for (MeshVS_SequenceOfPrsBuilder::Iterator aBuilderIter (myBuilders); aBuilderIter.More(); aBuilderIter.Next())
155   {
156     Handle(MeshVS_PrsBuilder) aBuilder = aBuilderIter.Value();
157     if (!aBuilder.IsNull()
158       && aBuilder->TestFlags (theMode))
159     {
160       return Standard_True;
161     }
162   }
163   return Standard_False;
164 }
165
166 //================================================================
167 // Function : Compute
168 // Purpose  :
169 //================================================================
170 void MeshVS_Mesh::Compute ( const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
171                             const Handle(Prs3d_Presentation)& thePresentation,
172                             const Standard_Integer theMode )
173 {
174   Standard_Boolean toShowComputeTime = Standard_True;
175   myCurrentDrawer->GetBoolean (MeshVS_DA_ComputeTime, toShowComputeTime);
176   OSD_Timer aTimer;
177   if (toShowComputeTime)
178   {
179     aTimer.Reset();
180     aTimer.Start();
181   }
182
183   // Repair Ids in map if necessary
184   Handle( MeshVS_DataSource ) aDS = GetDataSource();
185   if (aDS.IsNull()
186    || theMode <= 0)
187   {
188     return;
189   }
190
191   const TColStd_PackedMapOfInteger& aNodes = aDS->GetAllNodes();
192   const TColStd_PackedMapOfInteger& aElems = aDS->GetAllElements();
193   const Standard_Boolean hasNodes    = !aNodes.IsEmpty();
194   const Standard_Boolean hasElements = !aElems.IsEmpty();
195
196   TColStd_PackedMapOfInteger aNodesToExclude, aElemsToExclude;
197   for (MeshVS_SequenceOfPrsBuilder::Iterator aBuilderIter (myBuilders); aBuilderIter.More(); aBuilderIter.Next())
198   {
199     const Handle(MeshVS_PrsBuilder)& aBuilder = aBuilderIter.Value();
200     if (!aBuilder.IsNull()
201       && aBuilder->TestFlags (theMode))
202     {
203       aBuilder->SetPresentationManager (thePrsMgr);
204       if (hasNodes)
205       {
206         aBuilder->Build (thePresentation, aNodes, aNodesToExclude, Standard_False, theMode);
207       }
208       if (hasElements)
209       {
210         aBuilder->Build (thePresentation, aElems, aElemsToExclude, Standard_True,  theMode);
211       }
212     }
213   }
214
215   if (toShowComputeTime)
216   {
217     Standard_Real aSec, aCpu;
218     Standard_Integer aMin, anHour;
219     aTimer.Show (aSec, aMin, anHour, aCpu);
220     std::cout << "DisplayMode : " << theMode << "\n";
221     std::cout << "Compute : " << aSec << " sec\n";
222     std::cout << "Compute CPU : " << aCpu << " sec\n\n";
223   }
224 }
225
226 //================================================================
227 // Function : scanFacesForSharedNodes
228 // Purpose  :
229 //================================================================
230 void MeshVS_Mesh::scanFacesForSharedNodes (const TColStd_PackedMapOfInteger& theAllElements,
231                                            const Standard_Integer theNbMaxFaceNodes,
232                                            TColStd_PackedMapOfInteger& theSharedNodes) const
233 {
234   theSharedNodes.Clear();
235   MeshVS_EntityType aType;
236   Standard_Integer aNbNodes;
237   MeshVS_Buffer aCoordsBuf (3 * theNbMaxFaceNodes * sizeof (Standard_Real));
238   TColStd_Array1OfReal aCoords (aCoordsBuf, 1, 3 * theNbMaxFaceNodes);
239   for (TColStd_MapIteratorOfPackedMapOfInteger aFaceIter (theAllElements); aFaceIter.More(); aFaceIter.Next())
240   {
241     const Standard_Integer aFaceIdx = aFaceIter.Key();
242
243     if (IsSelectableElem (aFaceIdx) &&
244       myDataSource->GetGeomType (aFaceIdx, Standard_True, aType) &&
245       aType == MeshVS_ET_Face)
246     {
247       myDataSource->GetGeom (aFaceIdx, Standard_True, aCoords, aNbNodes, aType );
248       if (aNbNodes == 0)
249         continue;
250
251       MeshVS_Buffer aNodesBuf (aNbNodes * sizeof (Standard_Integer));
252       TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
253       if (!myDataSource->GetNodesByElement (aFaceIdx, aElemNodes, aNbNodes))
254         continue;
255
256       MeshVS_Buffer aFacePntsBuf (aNbNodes * 3 * sizeof (Standard_Real));
257       TColgp_Array1OfPnt aFacePnts (aFacePntsBuf, 1, aNbNodes);
258       for (Standard_Integer aNodeIdx = 1; aNodeIdx <= aNbNodes; ++aNodeIdx)
259       {
260         theSharedNodes.Add (aElemNodes (aNodeIdx));
261       }
262     }
263   }
264 }
265
266 //================================================================
267 // Function : ComputeSelection
268 // Purpose  :
269 //================================================================
270 void MeshVS_Mesh::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
271                                     const Standard_Integer theMode)
272 {
273   OSD_Timer gTimer;
274   Standard_Boolean toShowComputeSelectionTime = Standard_True;
275   myCurrentDrawer->GetBoolean( MeshVS_DA_ComputeSelectionTime, toShowComputeSelectionTime);
276   if (toShowComputeSelectionTime)
277   {
278     gTimer.Reset();
279     gTimer.Start();
280   }
281
282   Standard_Integer aMaxFaceNodes = 0;
283   Handle(MeshVS_DataSource) aSource = GetDataSource();
284   if (aSource.IsNull()
285   ||  myCurrentDrawer.IsNull()
286   || !myCurrentDrawer->GetInteger (MeshVS_DA_MaxFaceNodes, aMaxFaceNodes)
287   ||  aMaxFaceNodes <= 0)
288   {
289     return;
290   }
291
292   const Standard_Integer aMode = HasDisplayMode() ? DisplayMode() : DefaultDisplayMode();
293   if (myHilighter.IsNull()
294    || (aMode & MeshVS_DMF_OCCMask) == 0)
295   {
296     return;
297   }
298
299   // Make two array aliases pointing to the same memory:
300   // - TColStd_Array1OfReal for getting values from MeshVS_DataSource interface
301   // - array of gp_Pnt for convenient work with array of points
302   MeshVS_Buffer aCoordsBuf (3 * aMaxFaceNodes * sizeof(Standard_Real));
303   NCollection_Array1<gp_Pnt> aPntArray (aCoordsBuf, 1, aMaxFaceNodes);
304   TColStd_Array1OfReal aPntArrayAsCoordArray (aCoordsBuf, 1, 3 * aMaxFaceNodes);
305
306   const TColStd_PackedMapOfInteger& anAllNodesMap    = aSource->GetAllNodes();
307   const TColStd_PackedMapOfInteger& anAllElementsMap = aSource->GetAllElements();
308   if (aSource->IsAdvancedSelectionEnabled())
309   {
310     Handle(MeshVS_MeshOwner) anOwner;    
311     for (MeshVS_DataMapIteratorOfDataMapOfIntegerOwner anIt (GetOwnerMaps (Standard_False)); anIt.More(); anIt.Next())
312     {
313       anOwner = Handle(MeshVS_MeshOwner)::DownCast (anIt.Value());
314       if (!anOwner.IsNull())
315       {
316         // get the owner if it is already created
317         break;
318       }
319     }
320     if (anOwner.IsNull())
321     {
322       // create one owner for the whole mesh and for all selection modes
323       anOwner = new MeshVS_MeshOwner (this, aSource, 5);
324     }
325
326     // Save the owner. It will be available via GetOwnerMaps method
327     if (!myMeshOwners.IsBound (1))
328     {
329       myMeshOwners.Bind (1, anOwner);
330     }
331     // Create one sensitive entity. It should detect mesh entities correspondingly to selection mode
332     Handle(MeshVS_SensitiveMesh) aSensMesh = new MeshVS_SensitiveMesh (anOwner, theMode);
333     theSelection->Add (aSensMesh);
334   }
335   else
336   {
337     switch (theMode)
338     {
339       case MeshVS_SMF_Node:
340       {
341         myNodeOwners.Clear();
342         for (TColStd_MapIteratorOfPackedMapOfInteger anIter (anAllNodesMap); anIter.More(); anIter.Next())
343         {
344           const Standard_Integer aKey = anIter.Key();
345           Standard_Integer aNbNodes = 0;
346           MeshVS_EntityType aType = MeshVS_ET_NONE;
347           if (!myDataSource->GetGeom (aKey, Standard_False, aPntArrayAsCoordArray, aNbNodes, aType))
348           {
349             continue;
350           }
351
352           Standard_Address anAddr = myDataSource->GetAddr (aKey, Standard_False);
353           Handle(MeshVS_MeshEntityOwner) anOwner = new MeshVS_MeshEntityOwner (this, aKey, anAddr, aType, 5);
354           myNodeOwners.Bind (aKey, anOwner);
355           if (IsSelectableNode (aKey))
356           {
357             Handle(Select3D_SensitivePoint) aPoint = new Select3D_SensitivePoint (anOwner, aPntArray.First());
358             theSelection->Add (aPoint);
359           }
360           else
361           {
362             theSelection->Add (new MeshVS_DummySensitiveEntity (anOwner));
363           }
364         }
365         break;
366       }
367       case MeshVS_SMF_Mesh:
368       {
369         if (myWholeMeshOwner.IsNull())
370         {
371           myWholeMeshOwner = new SelectMgr_EntityOwner (this);
372         }
373
374         switch (mySelectionMethod)
375         {
376           case MeshVS_MSM_BOX:
377           {
378             Bnd_Box aBndBox;
379             BoundingBox (aBndBox);
380             if (!aBndBox.IsVoid())
381             {
382               theSelection->Add (new Select3D_SensitiveBox (myWholeMeshOwner, aBndBox));
383             }
384             break;
385           }
386           case MeshVS_MSM_NODES:
387           {
388             theSelection->Add (new MeshVS_CommonSensitiveEntity (myWholeMeshOwner, this, MeshVS_MSM_NODES));
389             break;
390           }
391           case MeshVS_MSM_PRECISE:
392           {
393             theSelection->Add (new MeshVS_CommonSensitiveEntity (myWholeMeshOwner, this, MeshVS_MSM_PRECISE));
394
395             // since MeshVS_Mesh objects can contain free edges and vertices, it is necessary to create
396             // separate sensitive entity for each of them
397             TColStd_PackedMapOfInteger aSharedNodes;
398             scanFacesForSharedNodes (anAllElementsMap, aMaxFaceNodes, aSharedNodes);
399
400             // create sensitive entities for free edges, if there are any
401             Standard_Integer aNbNodes = 0;
402             MeshVS_EntityType aType = MeshVS_ET_NONE;
403             for (TColStd_MapIteratorOfPackedMapOfInteger anElemIter (anAllElementsMap); anElemIter.More(); anElemIter.Next())
404             {
405               const Standard_Integer anElemIdx = anElemIter.Key();
406               if (IsSelectableElem (anElemIdx)
407                && myDataSource->GetGeomType (anElemIdx, Standard_True, aType)
408                && aType == MeshVS_ET_Link)
409               {
410                 myDataSource->GetGeom (anElemIdx, Standard_True, aPntArrayAsCoordArray, aNbNodes, aType);
411                 if (aNbNodes == 0)
412                 {
413                   continue;
414                 }
415
416                 MeshVS_Buffer aNodesBuf (aNbNodes * sizeof(Standard_Integer));
417                 TColStd_Array1OfInteger aElemNodes (aNodesBuf, 1, aNbNodes);
418                 if (!myDataSource->GetNodesByElement (anElemIdx, aElemNodes, aNbNodes))
419                 {
420                   continue;
421                 }
422
423                 MeshVS_Buffer aPntsBuf (aNbNodes * 3 * sizeof(Standard_Real));
424                 TColgp_Array1OfPnt aLinkPnts (aPntsBuf, 1, aNbNodes);
425                 Standard_Boolean isVertsShared = Standard_True;
426                 for (Standard_Integer aPntIdx = 1; aPntIdx <= aNbNodes; ++aPntIdx)
427                 {
428                   aLinkPnts (aPntIdx) = aPntArray.Value (aPntIdx);
429                   isVertsShared = isVertsShared && aSharedNodes.Contains (aElemNodes (aPntIdx));
430                   aSharedNodes.Add (aElemNodes (aPntIdx));
431                 }
432
433                 if (!isVertsShared)
434                 {
435                   Handle(Select3D_SensitiveEntity) aLinkEnt = new Select3D_SensitiveSegment (myWholeMeshOwner, aLinkPnts.Value (1), aLinkPnts.Value (2));
436                   theSelection->Add (aLinkEnt);
437                 }
438               }
439             }
440
441             // create sensitive entities for free nodes, if there are any
442             for (TColStd_MapIteratorOfPackedMapOfInteger aNodesIter (anAllNodesMap); aNodesIter.More(); aNodesIter.Next())
443             {
444               const Standard_Integer aNodeIdx = aNodesIter.Key();
445               if (IsSelectableNode (aNodeIdx)
446               &&  myDataSource->GetGeom (aNodeIdx, Standard_False, aPntArrayAsCoordArray, aNbNodes, aType)
447               && !aSharedNodes.Contains (aNodeIdx))
448               {
449                 Handle(Select3D_SensitiveEntity) aNodeEnt = new Select3D_SensitivePoint (myWholeMeshOwner, aPntArray.First());
450                 theSelection->Add (aNodeEnt);
451               }
452             }
453           }
454           break;
455         }
456         break;
457       }
458       case MeshVS_SMF_Group:
459       {
460         myGroupOwners.Clear();
461
462         TColStd_PackedMapOfInteger anAllGroupsMap;
463         aSource->GetAllGroups (anAllGroupsMap);
464
465         Handle(MeshVS_HArray1OfSequenceOfInteger) aTopo;
466         for (TColStd_MapIteratorOfPackedMapOfInteger anIter (anAllGroupsMap); anIter.More(); anIter.Next())
467         {
468           const Standard_Integer aKeyGroup = anIter.Key();
469           MeshVS_EntityType aGroupType = MeshVS_ET_NONE;
470           TColStd_PackedMapOfInteger aGroupMap;
471           if (!myDataSource->GetGroup (aKeyGroup, aGroupType, aGroupMap))
472           {
473             continue;
474           }
475
476           Standard_Address anAddr = myDataSource->GetGroupAddr (aKeyGroup);
477           Standard_Integer aPrior = 0;
478           switch (aGroupType)
479           {
480             case MeshVS_ET_Volume: aPrior = 1; break;
481             case MeshVS_ET_Face:   aPrior = 2; break;
482             case MeshVS_ET_Link:   aPrior = 3; break;
483             case MeshVS_ET_0D:     aPrior = 4; break;
484             case MeshVS_ET_Node:   aPrior = 5; break;
485             default: break;
486           }
487
488           Handle(MeshVS_MeshEntityOwner) anOwner = new MeshVS_MeshEntityOwner (this, aKeyGroup, anAddr, aGroupType, aPrior, Standard_True);
489           myGroupOwners.Bind (aKeyGroup, anOwner);
490
491           Standard_Boolean added = Standard_False;
492           Standard_Integer aNbNodes = 0;
493           MeshVS_EntityType aType = MeshVS_ET_NONE;
494           for (TColStd_MapIteratorOfPackedMapOfInteger anIterMG (aGroupMap); anIterMG.More(); anIterMG.Next())
495           {
496             Standard_Integer aKey = anIterMG.Key();
497             if (aGroupType == MeshVS_ET_Node)
498             {
499               if (myDataSource->GetGeom (aKey, Standard_False, aPntArrayAsCoordArray, aNbNodes, aType)
500                && IsSelectableNode/*!IsHiddenNode*/(aKey))
501               {
502                 theSelection->Add (new Select3D_SensitivePoint (anOwner, aPntArray.First ()));
503                 added = Standard_True;
504               }
505             }
506             else if (myDataSource->GetGeomType (aKey, Standard_True, aType)
507                   && IsSelectableElem/*!IsHiddenElem*/(aKey))
508             {
509               myDataSource->GetGeom (aKey, Standard_True, aPntArrayAsCoordArray, aNbNodes, aType);
510               if (aType == MeshVS_ET_Face && aNbNodes > 0) // Faces: 2D-elements
511               {
512                 Handle(Select3D_SensitiveEntity) aSensFace;
513                 if (aNbNodes == 3)
514                 {
515                   aSensFace = new Select3D_SensitiveTriangle (anOwner,
516                                                               aPntArray.Value (1), aPntArray.Value (2), aPntArray.Value (3),
517                                                               Select3D_TOS_INTERIOR);
518                 }
519                 else if (aNbNodes == 4)
520                 {
521                   aSensFace = new MeshVS_SensitiveQuad (anOwner, aPntArray);
522                 }
523                 else
524                 {
525                   aSensFace = new MeshVS_SensitiveFace (anOwner, aPntArray);
526                 }
527                 theSelection->Add (aSensFace);
528                 added = Standard_True;
529               }
530               else if (aType == MeshVS_ET_Link && aNbNodes > 0) // Links: 1D-elements
531               {
532                 Handle (MeshVS_SensitiveSegment) aSeg = new MeshVS_SensitiveSegment (anOwner, aPntArray (1), aPntArray (2));
533                 theSelection->Add (aSeg);
534                 added = Standard_True;
535               }
536               else if (aType == MeshVS_ET_Volume
537                     && aSource->Get3DGeom (aKey, aNbNodes, aTopo))
538               {
539                 Handle(MeshVS_SensitivePolyhedron) aPolyhedron = new MeshVS_SensitivePolyhedron (anOwner, aPntArray, aTopo);
540                 theSelection->Add (aPolyhedron);
541                 added = Standard_True;
542               }
543               else //if ( aType == MeshVS_ET_0D )   // Custom : not only 0D-elements !!!
544               {
545                 Handle(SelectBasics_SensitiveEntity) anEnt = myHilighter->CustomSensitiveEntity (anOwner, aKey);
546                 if (!anEnt.IsNull())
547                 {
548                   theSelection->Add (anEnt);
549                   added = Standard_True;
550                 }
551               }
552             }
553           }
554           if (!added)
555           {
556             theSelection->Add (new MeshVS_DummySensitiveEntity (anOwner));
557           }
558         }
559         break;
560       }
561       default: // all residuary modes
562       {
563         Handle(MeshVS_HArray1OfSequenceOfInteger) aTopo;
564         myElementOwners.Clear();
565
566         MeshVS_DataMapOfIntegerOwner* aCurMap = &my0DOwners;
567         if (theMode == MeshVS_ET_Link)
568         {
569           aCurMap = &myLinkOwners;
570         }
571         else if (theMode == MeshVS_ET_Face)
572         {
573           aCurMap = &myFaceOwners;
574         }
575         else if (theMode == MeshVS_ET_Volume)
576         {
577           aCurMap = &myVolumeOwners;
578         }
579         aCurMap->Clear();
580
581         Standard_Integer aNbNodes = 0;
582         MeshVS_EntityType aType = MeshVS_ET_NONE;
583         for (TColStd_MapIteratorOfPackedMapOfInteger anIterMV (anAllElementsMap); anIterMV.More(); anIterMV.Next())
584         {
585           Standard_Integer aKey = anIterMV.Key();
586           if (myDataSource->GetGeomType (aKey, Standard_True, aType)
587            && theMode == aType)
588           {
589             myDataSource->GetGeom (aKey, Standard_True, aPntArrayAsCoordArray, aNbNodes, aType);
590             Standard_Address anAddr = myDataSource->GetAddr (aKey, Standard_True);
591
592             Standard_Integer aPrior = 0;
593             switch (aType)
594             {
595               case MeshVS_ET_Volume: aPrior = 1; break;
596               case MeshVS_ET_Face:   aPrior = 2; break;
597               case MeshVS_ET_Link:   aPrior = 3; break;
598               case MeshVS_ET_0D:     aPrior = 4; break;
599               default: break;
600             }
601
602             Handle(MeshVS_MeshEntityOwner) anOwner = new MeshVS_MeshEntityOwner (this, aKey, anAddr, aType, aPrior);
603             aCurMap->Bind (aKey, anOwner);
604             if (IsSelectableElem (aKey)) // The element is selectable
605             {
606               if (aType == MeshVS_ET_Face && aNbNodes > 0) // Faces: 2D-elements
607               {
608                 Handle(Select3D_SensitiveEntity) aSensFace;
609                 if (aNbNodes == 3)
610                 {
611                   aSensFace = new Select3D_SensitiveTriangle (anOwner,
612                                                               aPntArray.Value (1), aPntArray.Value (2), aPntArray.Value (3),
613                                                               Select3D_TOS_INTERIOR);
614                 }
615                 else if (aNbNodes == 4)
616                 {
617                   aSensFace = new MeshVS_SensitiveQuad (anOwner, aPntArray);
618                 }
619                 else
620                 {
621                   aSensFace = new MeshVS_SensitiveFace (anOwner, aPntArray);
622                 }
623                 theSelection->Add (aSensFace);
624               }
625               else if (aType == MeshVS_ET_Link && aNbNodes > 0) // Links: 1D-elements
626               {
627                 Handle(MeshVS_SensitiveSegment) aSeg = new MeshVS_SensitiveSegment (anOwner, aPntArray (1), aPntArray (2));
628                 theSelection->Add (aSeg);
629               }
630               else if (aType == MeshVS_ET_Volume
631                     && aSource->Get3DGeom (aKey, aNbNodes, aTopo))
632               {
633                 Handle(MeshVS_SensitivePolyhedron) aPolyhedron = new MeshVS_SensitivePolyhedron (anOwner, aPntArray, aTopo);
634                 theSelection->Add (aPolyhedron);
635               }
636               else //if ( aType == MeshVS_ET_0D )   // Custom : not only 0D-elements !!!
637               {
638                 Handle(SelectBasics_SensitiveEntity) anEnt = myHilighter->CustomSensitiveEntity (anOwner, aKey);
639                 if (!anEnt.IsNull())
640                 {
641                   theSelection->Add (anEnt);
642                 }
643               }
644             }
645             else
646             {
647               theSelection->Add (new MeshVS_DummySensitiveEntity (anOwner));
648             }
649           }
650         }
651         break;
652       }
653     }
654   }
655
656   StdSelect_BRepSelectionTool::PreBuildBVH (theSelection);
657
658   if (toShowComputeSelectionTime)
659   {
660     Standard_Real sec, cpu;
661     Standard_Integer min, hour;
662     gTimer.Show (sec, min, hour, cpu);
663     std::cout << "SelectionMode : " << theMode << "\n";
664     std::cout << "Compute selection: " << sec << " sec\n";
665     std::cout << "Compute selection CPU : " << cpu << " sec\n\n";
666     gTimer.Stop();
667   }
668 }
669
670 //================================================================
671 // Function : GetBuildersCount
672 // Purpose  :
673 //================================================================
674 Standard_Integer MeshVS_Mesh::GetBuildersCount () const
675 {
676   return myBuilders.Length();
677 }
678
679 //================================================================
680 // Function : GetFreeId
681 // Purpose  :
682 //================================================================
683 Standard_Integer MeshVS_Mesh::GetFreeId () const
684 {
685   TColStd_PackedMapOfInteger Ids;
686   Standard_Integer i, len = myBuilders.Length(), curId;
687
688   for ( i=1; i<=len; i++ )
689     Ids.Add( myBuilders.Value(i)->GetId () );
690
691   curId = 0;
692   while ( Ids.Contains( curId ) )
693     curId++;
694
695   return curId;
696 }
697
698 //================================================================
699 // Function : GetBuilder
700 // Purpose  :
701 //================================================================
702 Handle (MeshVS_PrsBuilder) MeshVS_Mesh::GetBuilder ( const Standard_Integer Index ) const
703 {
704   if ( Index>=1 && Index<=myBuilders.Length() )
705     return myBuilders.Value( Index );
706   else
707     return 0;
708 }
709
710 //================================================================
711 // Function : GetBuilderById
712 // Purpose  :
713 //================================================================
714 Handle (MeshVS_PrsBuilder) MeshVS_Mesh::GetBuilderById ( const Standard_Integer Id ) const
715 {
716   Handle (MeshVS_PrsBuilder) Result;
717
718   Standard_Integer i, len = myBuilders.Length();
719   for ( i=1; i<=len; i++ )
720     if ( myBuilders.Value(i)->GetId () == Id )
721     {
722       Result = myBuilders.Value(i);
723       break;
724     }
725   return Result;
726 }
727
728 //================================================================
729 // Function : AddBuilder
730 // Purpose  :
731 //================================================================
732 void MeshVS_Mesh::AddBuilder ( const Handle (MeshVS_PrsBuilder)& theBuilder,
733                                const Standard_Boolean TreatAsHilighter )
734 {
735   if ( theBuilder.IsNull() )
736     return;
737
738   Standard_Integer i, n = myBuilders.Length();
739   for ( i = 1; i<=n; i++ )
740     if ( myBuilders(i)->GetPriority() < theBuilder->GetPriority() )
741       break;
742
743   if ( i>n )
744     myBuilders.Append ( theBuilder );
745   else
746     myBuilders.InsertBefore ( i, theBuilder );
747
748   if( TreatAsHilighter )
749     myHilighter = theBuilder;
750 }
751
752 //================================================================
753 // Function : RemoveBuilder
754 // Purpose  :
755 //================================================================
756 void MeshVS_Mesh::RemoveBuilder ( const Standard_Integer theIndex )
757 {
758   Handle( MeshVS_PrsBuilder ) aBuild = GetBuilder( theIndex );
759   if ( !aBuild.IsNull() )
760   {
761     if ( aBuild == myHilighter )
762       myHilighter.Nullify();
763     myBuilders.Remove ( theIndex );
764   }
765 }
766
767 //================================================================
768 // Function : RemoveBuilderById
769 // Purpose  :
770 //================================================================
771 void MeshVS_Mesh::RemoveBuilderById ( const Standard_Integer Id )
772 {
773   Standard_Integer i, n = myBuilders.Length();
774   for ( i=1; i<=n; i++ )
775   {
776     Handle( MeshVS_PrsBuilder ) aCur = myBuilders(i);
777     if ( !aCur.IsNull() && aCur->GetId()==Id )
778       break;
779   }
780   if ( i>=1 && i<=n )
781   {
782     if ( GetBuilder( i )==myHilighter )
783       myHilighter.Nullify();
784     RemoveBuilder ( i );
785   }
786 }
787
788 //================================================================
789 // Function : SetHiddenElems
790 // Purpose  :
791 //================================================================
792 void MeshVS_Mesh::SetHiddenElems ( const Handle(TColStd_HPackedMapOfInteger)& theMap )
793 {
794   myHiddenElements = theMap;
795
796   // Note: update of list of selectable nodes -- this is not optimal!
797   Standard_Boolean AutoSelUpdate = Standard_False;
798   if ( !GetDrawer().IsNull() && GetDrawer()->GetBoolean( MeshVS_DA_SelectableAuto, AutoSelUpdate ) &&
799        AutoSelUpdate )
800     UpdateSelectableNodes();
801 }
802
803 //================================================================
804 // Function : SetHiddenNodes
805 // Purpose  :
806 //================================================================
807 void MeshVS_Mesh::SetHiddenNodes ( const Handle(TColStd_HPackedMapOfInteger)& theMap )
808 {
809   myHiddenNodes = theMap;
810
811   // Note: update of list of selectable nodes -- this is not optimal!
812   Standard_Boolean AutoSelUpdate = Standard_False;
813   if ( !GetDrawer().IsNull() && GetDrawer()->GetBoolean( MeshVS_DA_SelectableAuto, AutoSelUpdate ) &&
814        AutoSelUpdate )
815     UpdateSelectableNodes();
816 }
817
818 //================================================================
819 // Function : GetHiddenElems
820 // Purpose  :
821 //================================================================
822 const Handle(TColStd_HPackedMapOfInteger)& MeshVS_Mesh::GetHiddenElems () const
823 {
824   return myHiddenElements;
825 }
826
827 //================================================================
828 // Function : GetHiddenNodes
829 // Purpose  :
830 //================================================================
831 const Handle(TColStd_HPackedMapOfInteger)& MeshVS_Mesh::GetHiddenNodes () const
832 {
833   return myHiddenNodes;
834 }
835
836 //================================================================
837 // Function : AddToMap
838 // Purpose  :
839 //================================================================
840 void AddToMap ( MeshVS_DataMapOfIntegerOwner& Result, const MeshVS_DataMapOfIntegerOwner& Addition )
841 {
842   MeshVS_DataMapIteratorOfDataMapOfIntegerOwner anIt ( Addition );
843   for ( ; anIt.More(); anIt.Next() )
844     if ( Result.IsBound ( anIt.Key() ) )
845       Result.ChangeFind ( anIt.Key() ) = anIt.Value();
846     else
847       Result.Bind( anIt.Key(), anIt.Value() );
848 }
849
850 //================================================================
851 // Function : GetOwnerMaps
852 // Purpose  :
853 //================================================================
854 const MeshVS_DataMapOfIntegerOwner& MeshVS_Mesh::GetOwnerMaps ( const Standard_Boolean IsElements )
855 {
856   Handle(MeshVS_DataSource) aDS = GetDataSource();
857   if( !aDS.IsNull() && aDS->IsAdvancedSelectionEnabled() )
858     return myMeshOwners;
859   if ( IsElements )
860   {
861     if ( myElementOwners.IsEmpty() )
862     {
863       AddToMap ( myElementOwners, my0DOwners );
864       AddToMap ( myElementOwners, myLinkOwners );
865       AddToMap ( myElementOwners, myFaceOwners );
866       AddToMap ( myElementOwners, myVolumeOwners );
867     }
868     return myElementOwners;
869   }
870   else
871     return myNodeOwners;
872 }
873
874 //================================================================
875 // Function : IsHiddenElem
876 // Purpose  :
877 //================================================================
878 Standard_Boolean MeshVS_Mesh::IsHiddenElem ( const Standard_Integer theID ) const
879 {
880   return ! myHiddenElements.IsNull() && myHiddenElements->Map().Contains( theID );
881 }
882
883 //================================================================
884 // Function : IsHiddenNode
885 // Purpose  :
886 //================================================================
887 Standard_Boolean MeshVS_Mesh::IsHiddenNode ( const Standard_Integer theID ) const
888 {
889   // note that by default all nodes are hidden
890   return myHiddenNodes.IsNull() || myHiddenNodes->Map().Contains( theID );
891 }
892
893 //================================================================
894 // Function : GetDrawer
895 // Purpose  :
896 //================================================================
897 Handle( MeshVS_Drawer ) MeshVS_Mesh::GetDrawer() const
898 {
899   return myCurrentDrawer;
900 }
901
902 //================================================================
903 // Function : SetDrawer
904 // Purpose  :
905 //================================================================
906 void MeshVS_Mesh::SetDrawer(const Handle(MeshVS_Drawer)& aDrawer)
907 {
908   myCurrentDrawer = aDrawer;
909 }
910
911 //================================================================
912 // Function : GetDataSource
913 // Purpose  :
914 //================================================================
915 Handle(MeshVS_DataSource) MeshVS_Mesh::GetDataSource() const
916 {
917   return myDataSource;
918 }
919
920 //================================================================
921 // Function : SetDataSource
922 // Purpose  :
923 //================================================================
924 void MeshVS_Mesh::SetDataSource( const Handle(MeshVS_DataSource)& theDataSource )
925 {
926   myDataSource = theDataSource;
927 }
928
929 //================================================================
930 // Function : HilightSelected
931 // Purpose  :
932 //================================================================
933 void MeshVS_Mesh::HilightSelected ( const Handle(PrsMgr_PresentationManager3d)& thePM,
934                                     const SelectMgr_SequenceOfOwner& theOwners )
935 {
936   if ( myHilighter.IsNull() )
937     return;
938
939 //  if ( mySelectionPrs.IsNull() )
940 //    mySelectionPrs = new Prs3d_Presentation ( thePM->StructureManager() );
941
942   //new functionality
943
944   Handle( Prs3d_Presentation ) aSelectionPrs;
945
946   aSelectionPrs = GetSelectPresentation( thePM );
947
948   if( HasPresentation() )
949     aSelectionPrs->SetTransformPersistence (Presentation()->TransformPersistence());
950   //----------------
951
952   //   It is very important to call this parent method, because it check whether
953   // mySelectionPrs is created and if not, create it.
954
955 #ifdef OCCT_DEBUG
956   OSD_Timer gTimer;
957   gTimer.Reset();
958   gTimer.Start();
959 #endif
960
961   Standard_Integer len = theOwners.Length(), i;
962
963   Handle (MeshVS_MeshEntityOwner) anOwner;
964   TColStd_PackedMapOfInteger aSelNodes, aSelElements;
965
966   for( i=1; i<=len; i++ )
967   {
968     if (theOwners.Value (i) == GlobalSelOwner())
969     {
970       const Standard_Integer aHiMode = HasHilightMode() ? HilightMode() : 0;
971       const Handle(Prs3d_Drawer)& aSelStyle = !HilightAttributes().IsNull() ? HilightAttributes() : GetContext()->SelectionStyle();
972       thePM->Color (this, aSelStyle, aHiMode);
973       continue;
974     }
975     anOwner = Handle (MeshVS_MeshEntityOwner)::DownCast ( theOwners.Value ( i ) );
976     if ( !anOwner.IsNull() )
977     {
978       // nkv: add support of mesh groups
979       if ( anOwner->IsGroup() ) {
980         MeshVS_EntityType aGroupType;
981         TColStd_PackedMapOfInteger aGroupMap;
982         if ( GetDataSource()->GetGroup( anOwner->ID(), aGroupType, aGroupMap ) ) {
983           if ( aGroupType == MeshVS_ET_Node ) {
984             for( TColStd_MapIteratorOfPackedMapOfInteger anIt(aGroupMap); anIt.More(); anIt.Next() )
985               if( IsSelectableNode/*!IsHiddenNode*/( anIt.Key() ) )
986                 aSelNodes.Add( anIt.Key() );
987           }
988           else {
989             for( TColStd_MapIteratorOfPackedMapOfInteger anIt(aGroupMap); anIt.More(); anIt.Next() )
990               if( IsSelectableElem/*!IsHiddenElem*/( anIt.Key() ) )
991                 aSelElements.Add( anIt.Key() );
992           }
993         }
994       }
995       else {
996         if( anOwner->Type() == MeshVS_ET_Node )
997           aSelNodes.Add( anOwner->ID() );
998         else
999           aSelElements.Add( anOwner->ID() );
1000       }
1001     }
1002     else if( GetDataSource()->IsAdvancedSelectionEnabled() )
1003     {
1004       Handle(MeshVS_MeshOwner) aMeshOwner = Handle(MeshVS_MeshOwner)::DownCast ( theOwners.Value ( i ) );
1005       if( !aMeshOwner.IsNull() )
1006       {
1007         Handle(TColStd_HPackedMapOfInteger) aNodes = aMeshOwner->GetSelectedNodes();
1008         Handle(TColStd_HPackedMapOfInteger) aElems = aMeshOwner->GetSelectedElements();
1009         if( !aNodes.IsNull() )
1010           aSelNodes.Assign( aNodes->Map() );
1011         if( !aElems.IsNull() )
1012