0026936: Drawbacks of inlining in new type system in OCCT 7.0 -- automatic
[occt.git] / src / AIS / AIS_ConnectedInteractive.cxx
1 // Created on: 1997-01-08
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <AIS_ConnectedInteractive.hxx>
19 #include <AIS_InteractiveContext.hxx>
20 #include <AIS_InteractiveObject.hxx>
21 #include <AIS_Shape.hxx>
22 #include <BRepTools.hxx>
23 #include <Geom_Transformation.hxx>
24 #include <gp_Trsf.hxx>
25 #include <NCollection_DataMap.hxx>
26 #include <Precision.hxx>
27 #include <Prs3d_Drawer.hxx>
28 #include <Prs3d_Presentation.hxx>
29 #include <Prs3d_Projector.hxx>
30 #include <PrsMgr_ModedPresentation.hxx>
31 #include <PrsMgr_Presentation.hxx>
32 #include <Select3D_SensitiveEntity.hxx>
33 #include <SelectMgr_EntityOwner.hxx>
34 #include <SelectMgr_Selection.hxx>
35 #include <Standard_NotImplemented.hxx>
36 #include <Standard_ProgramError.hxx>
37 #include <Standard_Type.hxx>
38 #include <StdPrs_HLRPolyShape.hxx>
39 #include <StdPrs_WFShape.hxx>
40 #include <StdSelect.hxx>
41 #include <StdSelect_BRepOwner.hxx>
42 #include <TopAbs_ShapeEnum.hxx>
43 #include <TopoDS_Shape.hxx>
44 #include <TopTools_IndexedMapOfShape.hxx>
45 #include <TopTools_OrientedShapeMapHasher.hxx>
46
47 IMPLEMENT_STANDARD_RTTIEXT(AIS_ConnectedInteractive,AIS_InteractiveObject)
48
49 //=======================================================================
50 //function : AIS_ConnectedInteractive
51 //purpose  : 
52 //=======================================================================
53 AIS_ConnectedInteractive::AIS_ConnectedInteractive(const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d):
54 AIS_InteractiveObject(aTypeOfPresentation3d)
55 {
56   SetHilightMode(0);
57 }
58
59 //=======================================================================
60 //function : Type
61 //purpose  : 
62 //=======================================================================
63 AIS_KindOfInteractive AIS_ConnectedInteractive::Type() const
64 {
65   return AIS_KOI_Object;
66 }
67
68 Standard_Integer AIS_ConnectedInteractive::Signature() const
69 {
70   return 0;
71 }
72
73
74 //=======================================================================
75 //function : Connect
76 //purpose  : 
77 //=======================================================================
78 void AIS_ConnectedInteractive::Connect (const Handle(AIS_InteractiveObject)& theAnotherObj)
79 {
80   if (myReference == theAnotherObj) return;
81
82   Handle(AIS_ConnectedInteractive) aConnected = Handle(AIS_ConnectedInteractive)::DownCast (theAnotherObj);
83   if (!aConnected.IsNull())
84   {
85     myReference = aConnected->myReference;
86   }
87   else if (theAnotherObj->HasOwnPresentations())
88   {
89     myReference = theAnotherObj;
90   }
91   else
92   {
93     Standard_ProgramError::Raise ("AIS_ConnectedInteractive::Connect() - object without own presentation can not be connected");
94   }
95
96   if (!myReference.IsNull())
97   {
98     myTypeOfPresentation3d = myReference->TypeOfPresentation3d();
99   }
100 }
101
102 //=======================================================================
103 //function : Connect
104 //purpose  : 
105 //=======================================================================
106 void AIS_ConnectedInteractive::Connect (const Handle(AIS_InteractiveObject)& theAnotherObj, 
107                                         const gp_Trsf&                       theLocation)
108 {
109   Connect (theAnotherObj);
110
111   SetLocalTransformation (theLocation);
112 }
113
114
115 //=======================================================================
116 //function : Disconnect
117 //purpose  :
118 //=======================================================================
119
120 void AIS_ConnectedInteractive::Disconnect()
121 {
122   for(Standard_Integer aPrsIter = 1; aPrsIter <= myPresentations.Length(); ++aPrsIter)
123   {
124     const Handle(PrsMgr_Presentation)& aPrs = myPresentations (aPrsIter).Presentation();
125     if (!aPrs.IsNull())
126     {
127       aPrs->Presentation()->DisconnectAll (Graphic3d_TOC_DESCENDANT);
128     }
129   }
130 }
131 //=======================================================================
132 //function : Compute
133 //purpose  :
134 //=======================================================================
135 void AIS_ConnectedInteractive::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
136                                         const Handle(Prs3d_Presentation)&           thePrs,
137                                         const Standard_Integer                      theMode)
138 {
139   if (HasConnection())
140   {
141     thePrs->Clear (Standard_False);
142     thePrs->RemoveAll();
143
144     if (!myReference->HasInteractiveContext())
145     {
146       myReference->SetContext (GetContext());
147     }
148     thePrsMgr->Connect (this, myReference, theMode, theMode);
149     if (thePrsMgr->Presentation (myReference, theMode)->MustBeUpdated())
150     {
151       thePrsMgr->Update (myReference, theMode);
152     }
153   }
154
155   if (!thePrs.IsNull())
156   {
157     thePrs->ReCompute();
158   }
159 }
160
161 //=======================================================================
162 //function : Compute
163 //purpose  :
164 //=======================================================================
165 void AIS_ConnectedInteractive::Compute (const Handle(Prs3d_Projector)& theProjector,
166                                         const Handle(Geom_Transformation)& theTransformation,
167                                         const Handle(Prs3d_Presentation)& thePresentation)
168 {
169   updateShape (Standard_False);
170   if (myShape.IsNull())
171   {
172     return;
173   }
174   const TopLoc_Location& aLocation = myShape.Location();
175   TopoDS_Shape aShape = myShape.Located (TopLoc_Location (theTransformation->Trsf()) * aLocation);
176   Compute (theProjector, thePresentation, aShape);
177 }
178
179 //=======================================================================
180 //function : Compute
181 //purpose  :
182 //=======================================================================
183 void AIS_ConnectedInteractive::Compute(const Handle(Prs3d_Projector)& aProjector, const Handle(Prs3d_Presentation)& aPresentation)
184 {
185   updateShape (Standard_True);
186   Compute (aProjector, aPresentation, myShape);
187 }
188
189 //=======================================================================
190 //function : Compute
191 //purpose  :
192 //=======================================================================
193 void AIS_ConnectedInteractive::Compute (const Handle(Prs3d_Projector)& theProjector,
194                                         const Handle(Prs3d_Presentation)& thePresentation,
195                                         const TopoDS_Shape& theShape)
196 {
197   if (myShape.IsNull())
198   {
199     return;
200   }
201
202   switch (theShape.ShapeType())
203   {
204     case TopAbs_VERTEX:
205     case TopAbs_EDGE:
206     case TopAbs_WIRE:
207     {
208       thePresentation->SetDisplayPriority (4);
209       StdPrs_WFShape::Add (thePresentation, theShape, myDrawer);
210       break;
211     }
212     default:
213     {
214       Handle(Prs3d_Drawer) aDefaultDrawer = GetContext()->DefaultDrawer();
215       if (aDefaultDrawer->DrawHiddenLine()) 
216       {
217         myDrawer->EnableDrawHiddenLine();
218       }
219       else 
220       {
221         myDrawer->DisableDrawHiddenLine();
222       }
223       
224       Aspect_TypeOfDeflection aPrevDeflection = aDefaultDrawer->TypeOfDeflection();
225       aDefaultDrawer->SetTypeOfDeflection(Aspect_TOD_RELATIVE);
226
227       // process HLRAngle and HLRDeviationCoefficient()
228       Standard_Real aPrevAngle = myDrawer->HLRAngle();
229       Standard_Real aNewAngle = aDefaultDrawer->HLRAngle();
230       if (myDrawer->IsAutoTriangulation() &&
231           Abs (aNewAngle - aPrevAngle) > Precision::Angular())
232       {
233         BRepTools::Clean (theShape);
234       }
235
236       myDrawer->SetHLRAngle (aNewAngle);
237       myDrawer->SetHLRDeviationCoefficient (aDefaultDrawer->HLRDeviationCoefficient());
238       StdPrs_HLRPolyShape::Add (thePresentation, theShape, myDrawer, theProjector);
239       aDefaultDrawer->SetTypeOfDeflection (aPrevDeflection);
240     }
241   }
242 }
243
244 //=======================================================================
245 //function : updateShape
246 //purpose  : 
247 //=======================================================================
248 void AIS_ConnectedInteractive::updateShape (const Standard_Boolean isWithLocation)
249 {
250   Handle(AIS_Shape) anAisShape = Handle(AIS_Shape)::DownCast (myReference);
251   if (anAisShape.IsNull())
252   {
253     return;
254   }
255  
256   TopoDS_Shape aShape = anAisShape->Shape();
257   if (aShape.IsNull())
258   {
259     return;
260   }
261
262   if(!isWithLocation)
263   {
264     myShape = aShape;
265   }
266   else
267   {
268     myShape = aShape.Moved (TopLoc_Location (Transformation()));
269   }
270 }
271
272 //=======================================================================
273 //function : ComputeSelection
274 //purpose  : 
275 //=======================================================================
276 void AIS_ConnectedInteractive::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection, 
277                                                  const Standard_Integer theMode)
278 {
279   if (!HasConnection())
280   {
281     return;
282   }
283
284   if (theMode != 0 && myReference->AcceptShapeDecomposition())
285   {
286     computeSubShapeSelection (theSelection, theMode);
287     return;
288   }
289
290   if (!myReference->HasSelection (theMode))
291   {
292     myReference->RecomputePrimitives (theMode);
293   }
294
295   const Handle(SelectMgr_Selection)& TheRefSel = myReference->Selection (theMode);
296   Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
297   Handle(Select3D_SensitiveEntity) aSensitive, aNewSensitive;
298
299   TopLoc_Location aLocation (Transformation());
300   anOwner->SetLocation (aLocation);
301
302   if (TheRefSel->IsEmpty())
303   {
304     myReference->RecomputePrimitives (theMode);
305   }
306
307   for (TheRefSel->Init(); TheRefSel->More(); TheRefSel->Next())
308   {
309     aSensitive = Handle(Select3D_SensitiveEntity)::DownCast (TheRefSel->Sensitive()->BaseSensitive());
310     if (!aSensitive.IsNull())
311     {
312       // Get the copy of SE3D
313       aNewSensitive = aSensitive->GetConnected();
314
315       aNewSensitive->Set(anOwner);
316
317       theSelection->Add (aNewSensitive);
318     }
319   }
320 }
321
322 //=======================================================================
323 //function : ComputeSubShapeSelection 
324 //purpose  :
325 //=======================================================================
326 void AIS_ConnectedInteractive::computeSubShapeSelection (const Handle(SelectMgr_Selection)& theSelection, 
327                                                          const Standard_Integer theMode)
328 {
329   typedef NCollection_List<Handle(Select3D_SensitiveEntity)> SensitiveList;
330   typedef NCollection_DataMap<TopoDS_Shape, SensitiveList, TopTools_OrientedShapeMapHasher>
331     Shapes2EntitiesMap;
332
333   if (!myReference->HasSelection (theMode))
334     myReference->RecomputePrimitives (theMode);
335    
336   const Handle(SelectMgr_Selection)& aRefSel = myReference->Selection (theMode);
337
338   if (aRefSel->IsEmpty() || aRefSel->UpdateStatus() == SelectMgr_TOU_Full)
339   {
340     myReference->RecomputePrimitives (theMode);
341   }
342   
343   Handle(StdSelect_BRepOwner) anOwner;
344   TopLoc_Location aDummyLoc;
345
346   Handle(Select3D_SensitiveEntity) aSE, aNewSE;
347   Shapes2EntitiesMap aShapes2EntitiesMap;
348
349   SensitiveList aSEList;
350   TopoDS_Shape aSubShape;
351
352   // Fill in the map of subshapes and corresponding 
353   // sensitive entities associated with aMode 
354   for (aRefSel->Init(); aRefSel->More(); aRefSel->Next())
355   {
356     aSE = Handle(Select3D_SensitiveEntity)::DownCast (aRefSel->Sensitive()->BaseSensitive());
357     if(!aSE.IsNull())
358     {
359       anOwner = Handle(StdSelect_BRepOwner)::DownCast (aSE->OwnerId());
360       if(!anOwner.IsNull())
361       {
362         aSubShape = anOwner->Shape(); 
363         if(!aShapes2EntitiesMap.IsBound (aSubShape))
364         {
365           aShapes2EntitiesMap.Bind (aSubShape, aSEList);
366         }
367         aShapes2EntitiesMap (aSubShape).Append (aSE);
368       }
369     }
370   }
371
372   // Fill in selection from aShapes2EntitiesMap
373   for (Shapes2EntitiesMap::Iterator aMapIt (aShapes2EntitiesMap); aMapIt.More(); aMapIt.Next())
374   {
375     aSEList = aMapIt.Value();
376     anOwner = new StdSelect_BRepOwner (aMapIt.Key(), 
377                                        this, 
378                                        aSEList.First()->OwnerId()->Priority(), 
379                                        Standard_True);
380     anOwner->SetLocation (Transformation());
381
382     for (SensitiveList::Iterator aListIt (aSEList); aListIt.More(); aListIt.Next())
383     {
384       aSE = aListIt.Value();
385
386       aNewSE = aSE->GetConnected();
387       aNewSE->Set (anOwner);
388
389       theSelection->Add (aNewSE);
390     }
391   }
392
393   StdSelect::SetDrawerForBRepOwner (theSelection, myDrawer);  
394 }