f80bdc2adc7661751f50c72f4299a7d5d819938b
[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   theAnotherObj->AddChild (this);
101 }
102
103 //=======================================================================
104 //function : Connect
105 //purpose  : 
106 //=======================================================================
107 void AIS_ConnectedInteractive::Connect (const Handle(AIS_InteractiveObject)& theAnotherObj, 
108                                         const gp_Trsf&                       theLocation)
109 {
110   Connect (theAnotherObj);
111
112   SetLocalTransformation (theLocation);
113 }
114
115
116 //=======================================================================
117 //function : Disconnect
118 //purpose  :
119 //=======================================================================
120
121 void AIS_ConnectedInteractive::Disconnect()
122 {
123   for(Standard_Integer aPrsIter = 1; aPrsIter <= myPresentations.Length(); ++aPrsIter)
124   {
125     const Handle(PrsMgr_Presentation)& aPrs = myPresentations (aPrsIter).Presentation();
126     if (!aPrs.IsNull())
127     {
128       aPrs->Presentation()->DisconnectAll (Graphic3d_TOC_DESCENDANT);
129     }
130   }
131 }
132 //=======================================================================
133 //function : Compute
134 //purpose  :
135 //=======================================================================
136 void AIS_ConnectedInteractive::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
137                                         const Handle(Prs3d_Presentation)&           thePrs,
138                                         const Standard_Integer                      theMode)
139 {
140   if (HasConnection())
141   {
142     thePrs->Clear (Standard_False);
143     thePrs->RemoveAll();
144
145     if (!myReference->HasInteractiveContext())
146     {
147       myReference->SetContext (GetContext());
148     }
149     thePrsMgr->Connect (this, myReference, theMode, theMode);
150     if (thePrsMgr->Presentation (myReference, theMode)->MustBeUpdated())
151     {
152       thePrsMgr->Update (myReference, theMode);
153     }
154   }
155
156   if (!thePrs.IsNull())
157   {
158     thePrs->ReCompute();
159   }
160 }
161
162 //=======================================================================
163 //function : Compute
164 //purpose  :
165 //=======================================================================
166 void AIS_ConnectedInteractive::Compute (const Handle(Prs3d_Projector)& theProjector,
167                                         const Handle(Geom_Transformation)& theTransformation,
168                                         const Handle(Prs3d_Presentation)& thePresentation)
169 {
170   updateShape (Standard_False);
171   if (myShape.IsNull())
172   {
173     return;
174   }
175   const TopLoc_Location& aLocation = myShape.Location();
176   TopoDS_Shape aShape = myShape.Located (TopLoc_Location (theTransformation->Trsf()) * aLocation);
177   Compute (theProjector, thePresentation, aShape);
178 }
179
180 //=======================================================================
181 //function : Compute
182 //purpose  :
183 //=======================================================================
184 void AIS_ConnectedInteractive::Compute(const Handle(Prs3d_Projector)& aProjector, const Handle(Prs3d_Presentation)& aPresentation)
185 {
186   updateShape (Standard_True);
187   Compute (aProjector, aPresentation, myShape);
188 }
189
190 //=======================================================================
191 //function : Compute
192 //purpose  :
193 //=======================================================================
194 void AIS_ConnectedInteractive::Compute (const Handle(Prs3d_Projector)& theProjector,
195                                         const Handle(Prs3d_Presentation)& thePresentation,
196                                         const TopoDS_Shape& theShape)
197 {
198   if (myShape.IsNull())
199   {
200     return;
201   }
202
203   switch (theShape.ShapeType())
204   {
205     case TopAbs_VERTEX:
206     case TopAbs_EDGE:
207     case TopAbs_WIRE:
208     {
209       thePresentation->SetDisplayPriority (4);
210       StdPrs_WFDeflectionShape::Add (thePresentation, theShape, myDrawer);
211       break;
212     }
213     default:
214     {
215       Handle(Prs3d_Drawer) aDefaultDrawer = GetContext()->DefaultDrawer();
216       if (aDefaultDrawer->DrawHiddenLine()) 
217       {
218         myDrawer->EnableDrawHiddenLine();
219       }
220       else 
221       {
222         myDrawer->DisableDrawHiddenLine();
223       }
224       
225       Aspect_TypeOfDeflection aPrevDeflection = aDefaultDrawer->TypeOfDeflection();
226       aDefaultDrawer->SetTypeOfDeflection(Aspect_TOD_RELATIVE);
227
228       // process HLRAngle and HLRDeviationCoefficient()
229       Standard_Real aPrevAngle = myDrawer->HLRAngle();
230       Standard_Real aNewAngle = aDefaultDrawer->HLRAngle();
231       if (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->UpdateSelection (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   if (TheRefSel->IsEmpty())
300   {
301     myReference->UpdateSelection (theMode);
302   }
303
304   for (TheRefSel->Init(); TheRefSel->More(); TheRefSel->Next())
305   {
306     aSensitive = Handle(Select3D_SensitiveEntity)::DownCast (TheRefSel->Sensitive());
307     if (!aSensitive.IsNull())
308     {
309       TopLoc_Location aLocation (Transformation());
310       // Get the copy of SE3D
311       aNewSensitive = aSensitive->GetConnected (aLocation);
312
313       aNewSensitive->Set(anOwner);
314       // In case if SE3D caches some location-dependent data
315       // that must be updated after setting OWN
316       aNewSensitive->SetLocation (aLocation);
317
318       theSelection->Add (aNewSensitive);
319     }
320   }
321 }
322
323 //=======================================================================
324 //function : ComputeSubShapeSelection 
325 //purpose  :
326 //=======================================================================
327 void AIS_ConnectedInteractive::computeSubShapeSelection (const Handle(SelectMgr_Selection)& theSelection, 
328                                                          const Standard_Integer theMode)
329 {
330   typedef NCollection_List<Handle(Select3D_SensitiveEntity)> SensitiveList;
331   typedef NCollection_DataMap<TopoDS_Shape, SensitiveList, TopTools_OrientedShapeMapHasher>
332     Shapes2EntitiesMap;
333
334   if (!myReference->HasSelection (theMode))
335     myReference->UpdateSelection (theMode);
336    
337   const Handle(SelectMgr_Selection)& aRefSel = myReference->Selection (theMode);
338
339   if (aRefSel->IsEmpty() || aRefSel->UpdateStatus() == SelectMgr_TOU_Full)
340   {
341     myReference->UpdateSelection (theMode);
342   }
343   
344   Handle(StdSelect_BRepOwner) anOwner;
345   TopLoc_Location aDummyLoc;
346
347   Handle(Select3D_SensitiveEntity) aSE, aNewSE;
348   Shapes2EntitiesMap aShapes2EntitiesMap;
349
350   SensitiveList aSEList;
351   TopoDS_Shape aSubShape;
352
353   // Fill in the map of subshapes and corresponding 
354   // sensitive entities associated with aMode 
355   for (aRefSel->Init(); aRefSel->More(); aRefSel->Next())
356   {
357     aSE = Handle(Select3D_SensitiveEntity)::DownCast (aRefSel->Sensitive()); 
358     if(!aSE.IsNull())
359     {
360       anOwner = Handle(StdSelect_BRepOwner)::DownCast (aSE->OwnerId());
361       if(!anOwner.IsNull())
362       {
363         aSubShape = anOwner->Shape(); 
364         if(!aShapes2EntitiesMap.IsBound (aSubShape))
365         {
366           aShapes2EntitiesMap.Bind (aSubShape, aSEList);
367         }
368         aShapes2EntitiesMap (aSubShape).Append (aSE);
369       }
370     }
371   }
372
373   // Fill in selection from aShapes2EntitiesMap
374   for (Shapes2EntitiesMap::Iterator aMapIt (aShapes2EntitiesMap); aMapIt.More(); aMapIt.Next())
375   {
376     aSEList = aMapIt.Value();
377     anOwner = new StdSelect_BRepOwner (aMapIt.Key(), 
378                                        this, 
379                                        aSEList.First()->OwnerId()->Priority(), 
380                                        Standard_True);
381
382     for (SensitiveList::Iterator aListIt (aSEList); aListIt.More(); aListIt.Next())
383     {      
384       aSE = aListIt.Value();
385
386       TopLoc_Location aLocation (Transformation());
387       aNewSE = aSE->GetConnected (aDummyLoc);
388       aNewSE->Set (anOwner);
389       // In case if aSE caches some location-dependent data 
390       // that must be updated after setting anOwner
391       aNewSE->SetLocation (aLocation);
392
393       theSelection->Add (aNewSE);
394     }
395   }
396
397   StdSelect::SetDrawerForBRepOwner (theSelection, myDrawer);  
398 }