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