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