bef05e1b6c9bc49b29ad6468a90435f7b61f505b
[occt.git] / src / AIS / AIS_ConnectedShape.cxx
1 // Created on: 1996-04-10
2 // Created by: Guest Design
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
5 //
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
10 //
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 //
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
20
21 //              <g_design>
22
23
24 #include <Standard_NotImplemented.hxx>
25
26 #include <AIS_ConnectedShape.ixx>
27
28 #include <AIS_InteractiveContext.hxx>
29 #include <AIS_Drawer.hxx>
30 #include <TopAbs_ShapeEnum.hxx>
31 #include <StdPrs_WFDeflectionShape.hxx>
32 #include <StdPrs_HLRPolyShape.hxx>
33 #include <Prs3d_Drawer.hxx>
34 #include <Aspect_TypeOfDeflection.hxx>
35 #include <BRepTools.hxx>
36 #include <OSD_Timer.hxx>
37 #include <StdSelect_BRepSelectionTool.hxx>
38 #include <StdSelect_BRepOwner.hxx>
39 #include <StdSelect.hxx>
40 #include <TopTools_IndexedMapOfShape.hxx>
41 #include <TopExp.hxx>
42 #include <Select3D_SensitiveEntity.hxx>
43 #include <SelectMgr_EntityOwner.hxx>
44 #include <SelectBasics_EntityOwner.hxx>
45 #include <AIS_MultipleConnectedShape.hxx>
46 #include <Precision.hxx>
47 #include <NCollection_DataMap.hxx>
48 #include <NCollection_List.hxx>
49
50 //=======================================================================
51 //function : AIS_ConnectedShape
52 //purpose  : 
53 //=======================================================================
54
55 AIS_ConnectedShape::AIS_ConnectedShape (const Handle(AIS_Shape)& TheAISShape,
56                                         const PrsMgr_TypeOfPresentation3d TheType): 
57 AIS_ConnectedInteractive(TheType)
58 {
59   myReference = TheAISShape;
60 }
61
62 AIS_ConnectedShape::AIS_ConnectedShape (const Handle(AIS_ConnectedShape)& TheConnectedShape,
63                                         const PrsMgr_TypeOfPresentation3d TheType): 
64 AIS_ConnectedInteractive(TheType)
65 {
66   myReference = TheConnectedShape;
67 }
68
69
70 //=======================================================================
71 //function : Type
72 //purpose  : 
73 //=======================================================================
74
75 AIS_KindOfInteractive AIS_ConnectedShape::Type() const
76 {return AIS_KOI_Shape;}
77
78 //=======================================================================
79 //function : Signature
80 //purpose  : 
81 //=======================================================================
82 Standard_Integer AIS_ConnectedShape::Signature() const
83 {return 1;}
84
85 //=======================================================================
86 //function : AcceptShapeDecomposition
87 //purpose  : 
88 //=======================================================================
89 Standard_Boolean AIS_ConnectedShape::AcceptShapeDecomposition() const 
90 {return Standard_True;}
91
92 //=======================================================================
93 //function : Compute Hidden Lines
94 //purpose  : 
95 //=======================================================================
96
97 void AIS_ConnectedShape::Compute(const Handle(Prs3d_Projector)& aProjector, 
98                                  const Handle(Prs3d_Presentation)& aPresentation)
99 {
100   UpdateShape(Standard_True);
101   Compute(aProjector,aPresentation,myOwnSh);
102 }
103
104
105 //=======================================================================
106 //function : Compute
107 //purpose  : 
108 //=======================================================================
109 void AIS_ConnectedShape::Compute(const Handle(Prs3d_Projector)& aProjector, 
110                                  const Handle(Geom_Transformation)& TheTrsf,
111                                  const Handle(Prs3d_Presentation)& aPresentation)
112 {
113   UpdateShape(Standard_False);
114   const TopLoc_Location& loc = myOwnSh.Location();
115   TopoDS_Shape shbis = myOwnSh.Located(TopLoc_Location(TheTrsf->Trsf())*loc);
116   Compute(aProjector,aPresentation,shbis);
117 }
118
119
120 //=======================================================================
121 //function : Compute
122 //purpose  : 
123 //=======================================================================
124
125 void AIS_ConnectedShape::Compute(const Handle(Prs3d_Projector)& aProjector, 
126                                  const Handle(Prs3d_Presentation)& aPresentation,
127                                  const TopoDS_Shape& SH)
128 {
129 //  Standard_Boolean recompute = Standard_False;
130 //  Standard_Boolean myFirstCompute = Standard_True;
131   switch (SH.ShapeType()){
132   case TopAbs_VERTEX:
133   case TopAbs_EDGE:
134   case TopAbs_WIRE:
135     {
136       aPresentation->SetDisplayPriority(4);
137       StdPrs_WFDeflectionShape::Add(aPresentation,SH,myDrawer);
138       break;
139     }
140   default:
141     {
142       Handle (Prs3d_Drawer) defdrawer = GetContext()->DefaultDrawer();
143       if (defdrawer->DrawHiddenLine()) 
144         {myDrawer->EnableDrawHiddenLine();}
145       else {myDrawer->DisableDrawHiddenLine();}
146       
147       Aspect_TypeOfDeflection prevdef = defdrawer->TypeOfDeflection();
148       defdrawer->SetTypeOfDeflection(Aspect_TOD_RELATIVE);
149
150       // process HLRAngle and HLRDeviationCoefficient()
151       Standard_Real prevangl = myDrawer->HLRAngle();
152       Standard_Real newangl = defdrawer->HLRAngle();
153       if (Abs(newangl- prevangl) > Precision::Angular()) {
154 #ifdef DEB
155         cout << "AIS_MultipleConnectedShape : compute"<<endl;
156         cout << "newangl   : " << newangl << " # de " << "prevangl  : " << prevangl << endl;
157 #endif  
158         BRepTools::Clean(SH);
159       }
160       myDrawer->SetHLRAngle(newangl);
161       myDrawer->SetHLRDeviationCoefficient(defdrawer->HLRDeviationCoefficient());
162       StdPrs_HLRPolyShape::Add(aPresentation,SH,myDrawer,aProjector);
163       defdrawer->SetTypeOfDeflection (prevdef);
164     }
165   }
166 }
167
168 //=======================================================================
169 //function : Compute
170 //purpose  : 
171 //=======================================================================
172
173 void AIS_ConnectedShape::Compute(const Handle_PrsMgr_PresentationManager2d& aPresentationManager2d,
174                                  const Handle_Graphic2d_GraphicObject& aGraphicObject,
175                                  const int anInteger)
176 {
177 // Standard_NotImplemented::Raise("AIS_ConnectedShape::Compute(const Handle_PrsMgr_PresentationManager2d&, const Handle_Graphic2d_GraphicObject&, const int)");
178  AIS_ConnectedInteractive::Compute( aPresentationManager2d ,aGraphicObject,anInteger) ; 
179 }
180
181 //=======================================================================
182 //function : ComputeSelection 
183 //purpose  : Attention fragile...
184 //=======================================================================
185 static Standard_Boolean IsEqual( const TopoDS_Shape& theLeft, 
186                                  const TopoDS_Shape& theRight )
187 {
188   return theLeft.IsEqual(theRight);
189 }
190
191 void AIS_ConnectedShape::ComputeSelection (const Handle(SelectMgr_Selection)& aSelection, 
192                                            const Standard_Integer aMode)
193 {
194   typedef NCollection_List<Handle(Select3D_SensitiveEntity)> SensitiveList;
195   typedef NCollection_DataMap<TopoDS_Shape, SensitiveList > Shapes2EntitiesMap; 
196
197   UpdateShape();
198   aSelection->Clear();
199   // It is checked if there is nothing to do with the reference
200   // of type update...
201   
202   if(!myReference->HasSelection(aMode))
203     myReference->UpdateSelection(aMode);
204   const Handle(SelectMgr_Selection)& aRefSel = myReference->Selection(aMode);
205   if(aRefSel->IsEmpty())
206     myReference->UpdateSelection(aMode);
207
208   if(aRefSel->UpdateStatus()==SelectMgr_TOU_Full)
209     myReference->UpdateSelection(aMode);
210   
211   Handle(StdSelect_BRepOwner) anOwner;
212   TopLoc_Location aBidLoc;
213   Handle(Select3D_SensitiveEntity) aSE, aNewSE;
214   Shapes2EntitiesMap aShapes2EntitiesMap;
215   SensitiveList aSEList;
216   TopoDS_Shape aSubShape;
217
218   // Fill in the map of subshapes and corresponding 
219   // sensitive entities associated with aMode 
220   for(aRefSel->Init(); aRefSel->More(); aRefSel->Next())
221   {
222     aSE = Handle(Select3D_SensitiveEntity)::DownCast(aRefSel->Sensitive()); 
223     if(!aSE.IsNull())
224     {
225       anOwner = Handle(StdSelect_BRepOwner)::DownCast(aSE->OwnerId());
226       if(!anOwner.IsNull())
227       {
228         aSubShape = anOwner->Shape(); 
229         if(!aShapes2EntitiesMap.IsBound(aSubShape))
230         {
231           aShapes2EntitiesMap.Bind(aSubShape, aSEList);
232         }
233         aShapes2EntitiesMap(aSubShape).Append(aSE);
234       }
235     }
236   }
237
238   // Fill in selection from aShapes2EntitiesMap
239   Shapes2EntitiesMap::Iterator aMapIt(aShapes2EntitiesMap);
240   for(; aMapIt.More(); aMapIt.Next())
241   {
242     aSEList = aMapIt.Value();
243     anOwner = new StdSelect_BRepOwner(aMapIt.Key(), 
244                                       this, 
245                                       aSEList.First()->OwnerId()->Priority(), 
246                                       Standard_True);
247     
248     SensitiveList::Iterator aListIt(aSEList);
249     for(; aListIt.More(); aListIt.Next())
250     {
251       aSE = aListIt.Value();
252       if(myLocation.IsIdentity())
253       {
254         aNewSE = aSE->GetConnected(aBidLoc);
255         aNewSE->Set(anOwner);
256         // In case if aSE caches some location-dependent data 
257         // that must be updated after setting anOwner
258         aNewSE->SetLocation(aBidLoc);
259       }
260       else
261       {
262         aNewSE = aSE->GetConnected(myLocation); 
263         aNewSE->Set(anOwner); 
264         // In case if aSE caches some location-dependent data 
265         // that must be updated after setting anOwner
266         aNewSE->SetLocation(myLocation);
267       }
268       aSelection->Add(aNewSE);
269     }
270   }
271
272   StdSelect::SetDrawerForBRepOwner(aSelection,myDrawer);  
273 }
274
275 //=======================================================================
276 //function : Shape
277 //purpose  : 
278 //=======================================================================
279
280 const TopoDS_Shape& AIS_ConnectedShape::Shape()
281
282   UpdateShape(); 
283   return myOwnSh;
284 }
285 AIS_ConnectedShape::AIS_ConnectedShape(const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d):
286 AIS_ConnectedInteractive(aTypeOfPresentation3d)
287 {    
288   SetHilightMode(0);
289 }
290   
291 //=======================================================================
292 //function : UpdateShape
293 //purpose  : if<WithLocation=False> computes only the deducted shape
294 //           from reference; does not put "myLocation"
295 //=======================================================================
296 void AIS_ConnectedShape::UpdateShape(const Standard_Boolean WithTheLocation)
297 {
298   if(myReference.IsNull()) return;
299
300   // attention great line...
301   if(myReference->Type()!=AIS_KOI_Shape) return;
302
303   Standard_Integer Sig = myReference->Signature();
304   
305   TopoDS_Shape S ;
306   switch(Sig){
307   case 0:
308     S = (*((Handle(AIS_Shape)*) &myReference))->Shape();
309     break;
310   case 1:
311     S = (*((Handle(AIS_ConnectedShape)*) &myReference))->Shape();
312     break;
313   case 2:
314     S=(*((Handle(AIS_MultipleConnectedShape)*) &myReference))->Shape();
315     break;
316   default:
317     S = myOwnSh;
318   }
319   if(S.IsNull()) return;
320   if(myLocation.IsIdentity() || !WithTheLocation) 
321     myOwnSh = S;
322   else
323     myOwnSh = S.Moved(myLocation);
324 }
325
326
327 //=======================================================================
328 //function : Connect
329 //purpose  : 
330 //=======================================================================
331 void AIS_ConnectedShape::
332 Connect(const Handle(AIS_InteractiveObject)& anotherIObj)
333 {
334   if(anotherIObj->Type()== AIS_KOI_Shape){
335     Standard_Integer Sig = anotherIObj->Signature();
336     if(Sig <=2)
337       AIS_ConnectedInteractive::Connect(anotherIObj);
338   }
339 }
340
341 //=======================================================================
342 //function : Connect
343 //purpose  : 
344 //=======================================================================
345 void AIS_ConnectedShape::
346 Connect(const Handle(AIS_InteractiveObject)& anotherIObj, 
347         const TopLoc_Location& aLocation)
348 {
349   if(anotherIObj->Type()== AIS_KOI_Shape){
350     Standard_Integer Sig = anotherIObj->Signature();
351     if(Sig <=2)
352       AIS_ConnectedInteractive::Connect(anotherIObj,aLocation);
353   }
354 }
355