0012121: Optimization of existing selection classes
[occt.git] / src / AIS / AIS_ConnectedShape.cxx
1 // File:        AIS_ConnectedShape.cxx
2 // Created:     Wed Apr 10 16:40:43 1996
3 // Author:      Guest Design
4 //              <g_design>
5
6
7 #include <Standard_NotImplemented.hxx>
8
9 #include <AIS_ConnectedShape.ixx>
10
11 #include <AIS_InteractiveContext.hxx>
12 #include <AIS_Drawer.hxx>
13 #include <TopAbs_ShapeEnum.hxx>
14 #include <StdPrs_WFDeflectionShape.hxx>
15 #include <StdPrs_HLRPolyShape.hxx>
16 #include <Prs3d_Drawer.hxx>
17 #include <Aspect_TypeOfDeflection.hxx>
18 #include <BRepTools.hxx>
19 #include <OSD_Timer.hxx>
20 #include <StdSelect_BRepSelectionTool.hxx>
21 #include <StdSelect_BRepOwner.hxx>
22 #include <StdSelect.hxx>
23 #include <TopTools_IndexedMapOfShape.hxx>
24 #include <TopExp.hxx>
25 #include <Select3D_SensitiveEntity.hxx>
26 #include <SelectMgr_EntityOwner.hxx>
27 #include <SelectBasics_EntityOwner.hxx>
28 #include <AIS_MultipleConnectedShape.hxx>
29 #include <Precision.hxx>
30 #include <NCollection_DataMap.hxx>
31 #include <NCollection_List.hxx>
32
33 //=======================================================================
34 //function : AIS_ConnectedShape
35 //purpose  : 
36 //=======================================================================
37
38 AIS_ConnectedShape::AIS_ConnectedShape (const Handle(AIS_Shape)& TheAISShape,
39                                         const PrsMgr_TypeOfPresentation3d TheType): 
40 AIS_ConnectedInteractive(TheType)
41 {
42   myReference = TheAISShape;
43 }
44
45 AIS_ConnectedShape::AIS_ConnectedShape (const Handle(AIS_ConnectedShape)& TheConnectedShape,
46                                         const PrsMgr_TypeOfPresentation3d TheType): 
47 AIS_ConnectedInteractive(TheType)
48 {
49   myReference = TheConnectedShape;
50 }
51
52
53 //=======================================================================
54 //function : Type
55 //purpose  : 
56 //=======================================================================
57
58 AIS_KindOfInteractive AIS_ConnectedShape::Type() const
59 {return AIS_KOI_Shape;}
60
61 //=======================================================================
62 //function : Signature
63 //purpose  : 
64 //=======================================================================
65 Standard_Integer AIS_ConnectedShape::Signature() const
66 {return 1;}
67
68 //=======================================================================
69 //function : AcceptShapeDecomposition
70 //purpose  : 
71 //=======================================================================
72 Standard_Boolean AIS_ConnectedShape::AcceptShapeDecomposition() const 
73 {return Standard_True;}
74
75 //=======================================================================
76 //function : Compute Hidden Lines
77 //purpose  : 
78 //=======================================================================
79
80 void AIS_ConnectedShape::Compute(const Handle(Prs3d_Projector)& aProjector, 
81                                  const Handle(Prs3d_Presentation)& aPresentation)
82 {
83   UpdateShape(Standard_True);
84   Compute(aProjector,aPresentation,myOwnSh);
85 }
86
87
88 //=======================================================================
89 //function : Compute
90 //purpose  : 
91 //=======================================================================
92 void AIS_ConnectedShape::Compute(const Handle(Prs3d_Projector)& aProjector, 
93                                  const Handle(Geom_Transformation)& TheTrsf,
94                                  const Handle(Prs3d_Presentation)& aPresentation)
95 {
96   UpdateShape(Standard_False);
97   const TopLoc_Location& loc = myOwnSh.Location();
98   TopoDS_Shape shbis = myOwnSh.Located(TopLoc_Location(TheTrsf->Trsf())*loc);
99   Compute(aProjector,aPresentation,shbis);
100 }
101
102
103 //=======================================================================
104 //function : Compute
105 //purpose  : 
106 //=======================================================================
107
108 void AIS_ConnectedShape::Compute(const Handle(Prs3d_Projector)& aProjector, 
109                                  const Handle(Prs3d_Presentation)& aPresentation,
110                                  const TopoDS_Shape& SH)
111 {
112 //  Standard_Boolean recompute = Standard_False;
113 //  Standard_Boolean myFirstCompute = Standard_True;
114   switch (SH.ShapeType()){
115   case TopAbs_VERTEX:
116   case TopAbs_EDGE:
117   case TopAbs_WIRE:
118     {
119       aPresentation->SetDisplayPriority(4);
120       StdPrs_WFDeflectionShape::Add(aPresentation,SH,myDrawer);
121       break;
122     }
123   default:
124     {
125       Handle (Prs3d_Drawer) defdrawer = GetContext()->DefaultDrawer();
126       if (defdrawer->DrawHiddenLine()) 
127         {myDrawer->EnableDrawHiddenLine();}
128       else {myDrawer->DisableDrawHiddenLine();}
129       
130       Aspect_TypeOfDeflection prevdef = defdrawer->TypeOfDeflection();
131       defdrawer->SetTypeOfDeflection(Aspect_TOD_RELATIVE);
132
133       // process HLRAngle and HLRDeviationCoefficient()
134       Standard_Real prevangl = myDrawer->HLRAngle();
135       Standard_Real newangl = defdrawer->HLRAngle();
136       if (Abs(newangl- prevangl) > Precision::Angular()) {
137 #ifdef DEB
138         cout << "AIS_MultipleConnectedShape : compute"<<endl;
139         cout << "newangl   : " << newangl << " # de " << "prevangl  : " << prevangl << endl;
140 #endif  
141         BRepTools::Clean(SH);
142       }
143       myDrawer->SetHLRAngle(newangl);
144       myDrawer->SetHLRDeviationCoefficient(defdrawer->HLRDeviationCoefficient());
145       StdPrs_HLRPolyShape::Add(aPresentation,SH,myDrawer,aProjector);
146       defdrawer->SetTypeOfDeflection (prevdef);
147     }
148   }
149 }
150
151 //=======================================================================
152 //function : Compute
153 //purpose  : 
154 //=======================================================================
155
156 void AIS_ConnectedShape::Compute(const Handle_PrsMgr_PresentationManager2d& aPresentationManager2d,
157                                  const Handle_Graphic2d_GraphicObject& aGraphicObject,
158                                  const int anInteger)
159 {
160 // Standard_NotImplemented::Raise("AIS_ConnectedShape::Compute(const Handle_PrsMgr_PresentationManager2d&, const Handle_Graphic2d_GraphicObject&, const int)");
161  AIS_ConnectedInteractive::Compute( aPresentationManager2d ,aGraphicObject,anInteger) ; 
162 }
163
164 //=======================================================================
165 //function : ComputeSelection 
166 //purpose  : Attention fragile...
167 //=======================================================================
168 static Standard_Boolean IsEqual( const TopoDS_Shape& theLeft, 
169                                  const TopoDS_Shape& theRight )
170 {
171   return theLeft.IsEqual(theRight);
172 }
173
174 void AIS_ConnectedShape::ComputeSelection (const Handle(SelectMgr_Selection)& aSelection, 
175                                            const Standard_Integer aMode)
176 {
177   typedef NCollection_List<Handle(Select3D_SensitiveEntity)> SensitiveList;
178   typedef NCollection_DataMap<TopoDS_Shape, SensitiveList > Shapes2EntitiesMap; 
179
180   UpdateShape();
181   aSelection->Clear();
182   // It is checked if there is nothing to do with the reference
183   // of type update...
184   
185   if(!myReference->HasSelection(aMode))
186     myReference->UpdateSelection(aMode);
187   const Handle(SelectMgr_Selection)& aRefSel = myReference->Selection(aMode);
188   if(aRefSel->IsEmpty())
189     myReference->UpdateSelection(aMode);
190
191   if(aRefSel->UpdateStatus()==SelectMgr_TOU_Full)
192     myReference->UpdateSelection(aMode);
193   
194   Handle(StdSelect_BRepOwner) anOwner;
195   TopLoc_Location aBidLoc;
196   Handle(Select3D_SensitiveEntity) aSE, aNewSE;
197   Shapes2EntitiesMap aShapes2EntitiesMap;
198   SensitiveList aSEList;
199   TopoDS_Shape aSubShape;
200
201   // Fill in the map of subshapes and corresponding 
202   // sensitive entities associated with aMode 
203   for(aRefSel->Init(); aRefSel->More(); aRefSel->Next())
204   {
205     aSE = Handle(Select3D_SensitiveEntity)::DownCast(aRefSel->Sensitive()); 
206     if(!aSE.IsNull())
207     {
208       anOwner = Handle(StdSelect_BRepOwner)::DownCast(aSE->OwnerId());
209       if(!anOwner.IsNull())
210       {
211         aSubShape = anOwner->Shape(); 
212         if(!aShapes2EntitiesMap.IsBound(aSubShape))
213         {
214           aShapes2EntitiesMap.Bind(aSubShape, aSEList);
215         }
216         aShapes2EntitiesMap(aSubShape).Append(aSE);
217       }
218     }
219   }
220
221   // Fill in selection from aShapes2EntitiesMap
222   Shapes2EntitiesMap::Iterator aMapIt(aShapes2EntitiesMap);
223   for(; aMapIt.More(); aMapIt.Next())
224   {
225     aSEList = aMapIt.Value();
226     anOwner = new StdSelect_BRepOwner(aMapIt.Key(), 
227                                       this, 
228                                       aSEList.First()->OwnerId()->Priority(), 
229                                       Standard_True);
230     
231     SensitiveList::Iterator aListIt(aSEList);
232     for(; aListIt.More(); aListIt.Next())
233     {
234       aSE = aListIt.Value();
235       if(myLocation.IsIdentity())
236       {
237         aNewSE = aSE->GetConnected(aBidLoc);
238         aNewSE->Set(anOwner);
239         // In case if aSE caches some location-dependent data 
240         // that must be updated after setting anOwner
241         aNewSE->SetLocation(aBidLoc);
242       }
243       else
244       {
245         aNewSE = aSE->GetConnected(myLocation); 
246         aNewSE->Set(anOwner); 
247         // In case if aSE caches some location-dependent data 
248         // that must be updated after setting anOwner
249         aNewSE->SetLocation(myLocation);
250       }
251       aSelection->Add(aNewSE);
252     }
253   }
254
255   StdSelect::SetDrawerForBRepOwner(aSelection,myDrawer);  
256 }
257
258 //=======================================================================
259 //function : Shape
260 //purpose  : 
261 //=======================================================================
262
263 const TopoDS_Shape& AIS_ConnectedShape::Shape()
264
265   UpdateShape(); 
266   return myOwnSh;
267 }
268 AIS_ConnectedShape::AIS_ConnectedShape(const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d):
269 AIS_ConnectedInteractive(aTypeOfPresentation3d)
270 {    
271   SetHilightMode(0);
272 }
273   
274 //=======================================================================
275 //function : UpdateShape
276 //purpose  : if<WithLocation=False> computes only the deducted shape
277 //           from reference; does not put "myLocation"
278 //=======================================================================
279 void AIS_ConnectedShape::UpdateShape(const Standard_Boolean WithTheLocation)
280 {
281   if(myReference.IsNull()) return;
282
283   // attention great line...
284   if(myReference->Type()!=AIS_KOI_Shape) return;
285
286   Standard_Integer Sig = myReference->Signature();
287   
288   TopoDS_Shape S ;
289   switch(Sig){
290   case 0:
291     S = (*((Handle(AIS_Shape)*) &myReference))->Shape();
292     break;
293   case 1:
294     S = (*((Handle(AIS_ConnectedShape)*) &myReference))->Shape();
295     break;
296   case 2:
297     S=(*((Handle(AIS_MultipleConnectedShape)*) &myReference))->Shape();
298     break;
299   default:
300     S = myOwnSh;
301   }
302   if(S.IsNull()) return;
303   if(myLocation.IsIdentity() || !WithTheLocation) 
304     myOwnSh = S;
305   else
306     myOwnSh = S.Moved(myLocation);
307 }
308
309
310 //=======================================================================
311 //function : Connect
312 //purpose  : 
313 //=======================================================================
314 void AIS_ConnectedShape::
315 Connect(const Handle(AIS_InteractiveObject)& anotherIObj)
316 {
317   if(anotherIObj->Type()== AIS_KOI_Shape){
318     Standard_Integer Sig = anotherIObj->Signature();
319     if(Sig <=2)
320       AIS_ConnectedInteractive::Connect(anotherIObj);
321   }
322 }
323
324 //=======================================================================
325 //function : Connect
326 //purpose  : 
327 //=======================================================================
328 void AIS_ConnectedShape::
329 Connect(const Handle(AIS_InteractiveObject)& anotherIObj, 
330         const TopLoc_Location& aLocation)
331 {
332   if(anotherIObj->Type()== AIS_KOI_Shape){
333     Standard_Integer Sig = anotherIObj->Signature();
334     if(Sig <=2)
335       AIS_ConnectedInteractive::Connect(anotherIObj,aLocation);
336   }
337 }
338