0025341: Visualization - disallow displaying object as part of connected one 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 <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 <Select3D_SensitiveEntity.hxx>
27 #include <SelectMgr_EntityOwner.hxx>
28 #include <SelectMgr_Selection.hxx>
29 #include <Standard_NotImplemented.hxx>
30 #include <Standard_ProgramError.hxx>
31 #include <Standard_Type.hxx>
32 #include <StdPrs_HLRPolyShape.hxx>
33 #include <StdPrs_WFShape.hxx>
34 #include <StdSelect.hxx>
35 #include <StdSelect_BRepOwner.hxx>
36 #include <TopAbs_ShapeEnum.hxx>
37 #include <TopoDS_Shape.hxx>
38 #include <TopTools_IndexedMapOfShape.hxx>
39 #include <TopTools_OrientedShapeMapHasher.hxx>
40
41 IMPLEMENT_STANDARD_RTTIEXT(AIS_ConnectedInteractive,AIS_InteractiveObject)
42
43 //=======================================================================
44 //function : AIS_ConnectedInteractive
45 //purpose  : 
46 //=======================================================================
47 AIS_ConnectedInteractive::AIS_ConnectedInteractive(const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d):
48 AIS_InteractiveObject(aTypeOfPresentation3d)
49 {
50   //
51 }
52
53 //=======================================================================
54 //function : connect
55 //purpose  :
56 //=======================================================================
57 void AIS_ConnectedInteractive::connect (const Handle(AIS_InteractiveObject)& theAnotherObj,
58                                         const Handle(Geom_Transformation)&   theLocation)
59 {
60   if (myReference == theAnotherObj)
61   {
62     setLocalTransformation (theLocation);
63     return;
64   }
65
66   Handle(AIS_ConnectedInteractive) aConnected = Handle(AIS_ConnectedInteractive)::DownCast (theAnotherObj);
67   if (!aConnected.IsNull())
68   {
69     myReference = aConnected->myReference;
70   }
71   else if (theAnotherObj->HasOwnPresentations())
72   {
73     myReference = theAnotherObj;
74   }
75   else
76   {
77     throw Standard_ProgramError("AIS_ConnectedInteractive::Connect() - object without own presentation can not be connected");
78   }
79
80   if (!myReference.IsNull())
81   {
82     if (myReference->HasInteractiveContext()
83      && myReference->GetContext()->DisplayStatus (myReference) != AIS_DS_None)
84     {
85       myReference.Nullify();
86       throw Standard_ProgramError("AIS_ConnectedInteractive::Connect() - connected object should NOT be displayed in context");
87     }
88     myTypeOfPresentation3d = myReference->TypeOfPresentation3d();
89   }
90   setLocalTransformation (theLocation);
91 }
92
93 //=======================================================================
94 //function : Disconnect
95 //purpose  :
96 //=======================================================================
97
98 void AIS_ConnectedInteractive::Disconnect()
99 {
100   for (PrsMgr_Presentations::Iterator aPrsIter (myPresentations); aPrsIter.More(); aPrsIter.Next())
101   {
102     const Handle(PrsMgr_Presentation)& aPrs = aPrsIter.Value();
103     if (!aPrs.IsNull())
104     {
105       aPrs->DisconnectAll (Graphic3d_TOC_DESCENDANT);
106     }
107   }
108 }
109 //=======================================================================
110 //function : Compute
111 //purpose  :
112 //=======================================================================
113 void AIS_ConnectedInteractive::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
114                                         const Handle(Prs3d_Presentation)&           thePrs,
115                                         const Standard_Integer                      theMode)
116 {
117   if (HasConnection())
118   {
119     thePrs->Clear (Standard_False);
120     thePrs->DisconnectAll (Graphic3d_TOC_DESCENDANT);
121
122     if (!myReference->HasInteractiveContext())
123     {
124       myReference->SetContext (GetContext());
125     }
126     thePrsMgr->Connect (this, myReference, theMode, theMode);
127     if (thePrsMgr->Presentation (myReference, theMode)->MustBeUpdated())
128     {
129       thePrsMgr->Update (myReference, theMode);
130     }
131   }
132
133   if (!thePrs.IsNull())
134   {
135     thePrs->ReCompute();
136   }
137 }
138
139 //=======================================================================
140 //function : Compute
141 //purpose  :
142 //=======================================================================
143 void AIS_ConnectedInteractive::Compute (const Handle(Prs3d_Projector)& theProjector,
144                                         const Handle(Geom_Transformation)& theTransformation,
145                                         const Handle(Prs3d_Presentation)& thePresentation)
146 {
147   updateShape (Standard_False);
148   if (myShape.IsNull())
149   {
150     return;
151   }
152   const TopLoc_Location& aLocation = myShape.Location();
153   TopoDS_Shape aShape = myShape.Located (TopLoc_Location (theTransformation->Trsf()) * aLocation);
154   Compute (theProjector, thePresentation, aShape);
155 }
156
157 //=======================================================================
158 //function : Compute
159 //purpose  :
160 //=======================================================================
161 void AIS_ConnectedInteractive::Compute(const Handle(Prs3d_Projector)& aProjector, const Handle(Prs3d_Presentation)& aPresentation)
162 {
163   updateShape (Standard_True);
164   Compute (aProjector, aPresentation, myShape);
165 }
166
167 //=======================================================================
168 //function : Compute
169 //purpose  :
170 //=======================================================================
171 void AIS_ConnectedInteractive::Compute (const Handle(Prs3d_Projector)& theProjector,
172                                         const Handle(Prs3d_Presentation)& thePrs,
173                                         const TopoDS_Shape& theShape)
174 {
175   AIS_Shape::computeHlrPresentation (theProjector, thePrs, theShape, myDrawer);
176 }
177
178 //=======================================================================
179 //function : updateShape
180 //purpose  : 
181 //=======================================================================
182 void AIS_ConnectedInteractive::updateShape (const Standard_Boolean isWithLocation)
183 {
184   Handle(AIS_Shape) anAisShape = Handle(AIS_Shape)::DownCast (myReference);
185   if (anAisShape.IsNull())
186   {
187     return;
188   }
189  
190   TopoDS_Shape aShape = anAisShape->Shape();
191   if (aShape.IsNull())
192   {
193     return;
194   }
195
196   if(!isWithLocation)
197   {
198     myShape = aShape;
199   }
200   else
201   {
202     myShape = aShape.Moved (TopLoc_Location (Transformation()));
203   }
204 }
205
206 //=======================================================================
207 //function : ComputeSelection
208 //purpose  : 
209 //=======================================================================
210 void AIS_ConnectedInteractive::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection, 
211                                                  const Standard_Integer theMode)
212 {
213   if (!HasConnection())
214   {
215     return;
216   }
217
218   if (theMode != 0 && myReference->AcceptShapeDecomposition())
219   {
220     computeSubShapeSelection (theSelection, theMode);
221     return;
222   }
223
224   if (!myReference->HasSelection (theMode))
225   {
226     myReference->RecomputePrimitives (theMode);
227   }
228
229   const Handle(SelectMgr_Selection)& TheRefSel = myReference->Selection (theMode);
230   Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
231
232   TopLoc_Location aLocation (Transformation());
233   anOwner->SetLocation (aLocation);
234
235   if (TheRefSel->IsEmpty())
236   {
237     myReference->RecomputePrimitives (theMode);
238   }
239
240   for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (TheRefSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
241   {
242     if (const Handle(Select3D_SensitiveEntity)& aSensitive = aSelEntIter.Value()->BaseSensitive())
243     {
244       // Get the copy of SE3D
245       if (Handle(Select3D_SensitiveEntity) aNewSensitive = aSensitive->GetConnected())
246       {
247         aNewSensitive->Set(anOwner);
248         theSelection->Add (aNewSensitive);
249       }
250     }
251   }
252 }
253
254 //=======================================================================
255 //function : ComputeSubShapeSelection 
256 //purpose  :
257 //=======================================================================
258 void AIS_ConnectedInteractive::computeSubShapeSelection (const Handle(SelectMgr_Selection)& theSelection, 
259                                                          const Standard_Integer theMode)
260 {
261   typedef NCollection_List<Handle(Select3D_SensitiveEntity)> SensitiveList;
262   typedef NCollection_DataMap<TopoDS_Shape, SensitiveList, TopTools_OrientedShapeMapHasher>
263     Shapes2EntitiesMap;
264
265   if (!myReference->HasSelection (theMode))
266   {
267     myReference->RecomputePrimitives (theMode);
268   }
269
270   const Handle(SelectMgr_Selection)& aRefSel = myReference->Selection (theMode);
271   if (aRefSel->IsEmpty() || aRefSel->UpdateStatus() == SelectMgr_TOU_Full)
272   {
273     myReference->RecomputePrimitives (theMode);
274   }
275
276   // Fill in the map of subshapes and corresponding sensitive entities associated with aMode
277   Shapes2EntitiesMap aShapes2EntitiesMap;
278   for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aRefSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
279   {
280     if (const Handle(Select3D_SensitiveEntity)& aSE = aSelEntIter.Value()->BaseSensitive())
281     {
282       if (Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast (aSE->OwnerId()))
283       {
284         const TopoDS_Shape& aSubShape = anOwner->Shape();
285         if(!aShapes2EntitiesMap.IsBound (aSubShape))
286         {
287           aShapes2EntitiesMap.Bind (aSubShape, SensitiveList());
288         }
289         aShapes2EntitiesMap (aSubShape).Append (aSE);
290       }
291     }
292   }
293
294   // Fill in selection from aShapes2EntitiesMap
295   for (Shapes2EntitiesMap::Iterator aMapIt (aShapes2EntitiesMap); aMapIt.More(); aMapIt.Next())
296   {
297     const SensitiveList& aSEList = aMapIt.Value();
298     Handle(StdSelect_BRepOwner) anOwner = new StdSelect_BRepOwner (aMapIt.Key(), this, aSEList.First()->OwnerId()->Priority(), Standard_True);
299     anOwner->SetLocation (Transformation());
300     for (SensitiveList::Iterator aListIt (aSEList); aListIt.More(); aListIt.Next())
301     {
302       if (Handle(Select3D_SensitiveEntity) aNewSE = aListIt.Value()->GetConnected())
303       {
304         aNewSE->Set (anOwner);
305         theSelection->Add (aNewSE);
306       }
307     }
308   }
309
310   StdSelect::SetDrawerForBRepOwner (theSelection, myDrawer);  
311 }