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