0024623: Visualization - improve selection mechanism
[occt.git] / src / AIS / AIS_ConnectedInteractive.cxx
CommitLineData
b311480e 1// Created on: 1997-01-08
2// Created by: Robert COUBLANC
3// Copyright (c) 1997-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <Standard_NotImplemented.hxx>
18
19#include <AIS_ConnectedInteractive.ixx>
20#include <SelectMgr_EntityOwner.hxx>
f751596e 21#include <SelectMgr_Selection.hxx>
7fd59977 22#include <Select3D_SensitiveEntity.hxx>
23#include <Geom_Transformation.hxx>
24
25#include <PrsMgr_ModedPresentation.hxx>
af324faa 26#include <PrsMgr_Presentation.hxx>
0717ddc1 27
28#include <StdSelect_BRepOwner.hxx>
29
30#include <StdSelect.hxx>
31#include <TopTools_IndexedMapOfShape.hxx>
32#include <TopTools_OrientedShapeMapHasher.hxx>
33
34#include <AIS_InteractiveContext.hxx>
35#include <BRepTools.hxx>
36#include <Precision.hxx>
0717ddc1 37#include <TopAbs_ShapeEnum.hxx>
40f70ac9 38#include <Standard_ProgramError.hxx>
0717ddc1 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>
7fd59977 46
47
48//=======================================================================
49//function : AIS_ConnectedInteractive
50//purpose :
51//=======================================================================
52AIS_ConnectedInteractive::AIS_ConnectedInteractive(const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d):
53AIS_InteractiveObject(aTypeOfPresentation3d)
0717ddc1 54{
7fd59977 55 SetHilightMode(0);
56}
57
58//=======================================================================
59//function : Type
60//purpose :
61//=======================================================================
62AIS_KindOfInteractive AIS_ConnectedInteractive::Type() const
0717ddc1 63{
64 return AIS_KOI_Object;
65}
7fd59977 66
67Standard_Integer AIS_ConnectedInteractive::Signature() const
0717ddc1 68{
69 return 0;
70}
7fd59977 71
72
73//=======================================================================
74//function : Connect
75//purpose :
76//=======================================================================
0717ddc1 77void AIS_ConnectedInteractive::Connect (const Handle(AIS_InteractiveObject)& theAnotherObj)
7fd59977 78{
0717ddc1 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 }
40f70ac9 90 else
91 {
92 Standard_ProgramError::Raise ("AIS_ConnectedInteractive::Connect() - object without own presentation can not be connected");
93 }
0717ddc1 94
95 if (!myReference.IsNull())
96 {
97 myTypeOfPresentation3d = myReference->TypeOfPresentation3d();
98 }
7fd59977 99}
100
101//=======================================================================
102//function : Connect
103//purpose :
104//=======================================================================
0717ddc1 105void AIS_ConnectedInteractive::Connect (const Handle(AIS_InteractiveObject)& theAnotherObj,
106 const gp_Trsf& theLocation)
7fd59977 107{
0717ddc1 108 Connect (theAnotherObj);
109
110 SetLocalTransformation (theLocation);
7fd59977 111}
112
113
114//=======================================================================
115//function : Disconnect
af324faa 116//purpose :
7fd59977 117//=======================================================================
118
119void AIS_ConnectedInteractive::Disconnect()
120{
af324faa 121 for(Standard_Integer aPrsIter = 1; aPrsIter <= myPresentations.Length(); ++aPrsIter)
122 {
123 const Handle(PrsMgr_Presentation)& aPrs = myPresentations (aPrsIter).Presentation();
124 if (!aPrs.IsNull())
7fd59977 125 {
af324faa 126 aPrs->Presentation()->DisconnectAll (Graphic3d_TOC_DESCENDANT);
7fd59977 127 }
af324faa 128 }
7fd59977 129}
130//=======================================================================
131//function : Compute
792c785c 132//purpose :
7fd59977 133//=======================================================================
792c785c 134void AIS_ConnectedInteractive::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
135 const Handle(Prs3d_Presentation)& thePrs,
136 const Standard_Integer theMode)
7fd59977 137{
792c785c 138 if (HasConnection())
139 {
140 thePrs->Clear (Standard_False);
141 thePrs->RemoveAll();
142
143 if (!myReference->HasInteractiveContext())
144 {
145 myReference->SetContext (GetContext());
146 }
147 thePrsMgr->Connect (this, myReference, theMode, theMode);
148 if (thePrsMgr->Presentation (myReference, theMode)->MustBeUpdated())
149 {
150 thePrsMgr->Update (myReference, theMode);
151 }
152 }
153
0717ddc1 154 if (!thePrs.IsNull())
792c785c 155 {
0717ddc1 156 thePrs->ReCompute();
7fd59977 157 }
7fd59977 158}
159
0717ddc1 160//=======================================================================
161//function : Compute
162//purpose :
163//=======================================================================
164void AIS_ConnectedInteractive::Compute (const Handle(Prs3d_Projector)& theProjector,
165 const Handle(Geom_Transformation)& theTransformation,
166 const Handle(Prs3d_Presentation)& thePresentation)
7fd59977 167{
0717ddc1 168 updateShape (Standard_False);
169 if (myShape.IsNull())
170 {
171 return;
172 }
173 const TopLoc_Location& aLocation = myShape.Location();
174 TopoDS_Shape aShape = myShape.Located (TopLoc_Location (theTransformation->Trsf()) * aLocation);
175 Compute (theProjector, thePresentation, aShape);
7fd59977 176}
177
0717ddc1 178//=======================================================================
179//function : Compute
180//purpose :
181//=======================================================================
857ffd5e 182void AIS_ConnectedInteractive::Compute(const Handle(Prs3d_Projector)& aProjector, const Handle(Prs3d_Presentation)& aPresentation)
7fd59977 183{
0717ddc1 184 updateShape (Standard_True);
185 Compute (aProjector, aPresentation, myShape);
7fd59977 186}
187
7fd59977 188//=======================================================================
0717ddc1 189//function : Compute
190//purpose :
7fd59977 191//=======================================================================
0717ddc1 192void AIS_ConnectedInteractive::Compute (const Handle(Prs3d_Projector)& theProjector,
193 const Handle(Prs3d_Presentation)& thePresentation,
194 const TopoDS_Shape& theShape)
7fd59977 195{
0717ddc1 196 if (myShape.IsNull())
197 {
198 return;
199 }
ac04d101 200
0717ddc1 201 switch (theShape.ShapeType())
ac04d101 202 {
0717ddc1 203 case TopAbs_VERTEX:
204 case TopAbs_EDGE:
205 case TopAbs_WIRE:
ac04d101 206 {
0717ddc1 207 thePresentation->SetDisplayPriority (4);
208 StdPrs_WFDeflectionShape::Add (thePresentation, theShape, myDrawer);
209 break;
210 }
211 default:
212 {
213 Handle(Prs3d_Drawer) aDefaultDrawer = GetContext()->DefaultDrawer();
214 if (aDefaultDrawer->DrawHiddenLine())
215 {
216 myDrawer->EnableDrawHiddenLine();
217 }
218 else
219 {
220 myDrawer->DisableDrawHiddenLine();
221 }
222
223 Aspect_TypeOfDeflection aPrevDeflection = aDefaultDrawer->TypeOfDeflection();
224 aDefaultDrawer->SetTypeOfDeflection(Aspect_TOD_RELATIVE);
225
226 // process HLRAngle and HLRDeviationCoefficient()
227 Standard_Real aPrevAngle = myDrawer->HLRAngle();
228 Standard_Real aNewAngle = aDefaultDrawer->HLRAngle();
4c513386 229 if (myDrawer->IsAutoTriangulation() &&
230 Abs (aNewAngle - aPrevAngle) > Precision::Angular())
ac04d101 231 {
0717ddc1 232 BRepTools::Clean (theShape);
ac04d101 233 }
0717ddc1 234
235 myDrawer->SetHLRAngle (aNewAngle);
236 myDrawer->SetHLRDeviationCoefficient (aDefaultDrawer->HLRDeviationCoefficient());
237 StdPrs_HLRPolyShape::Add (thePresentation, theShape, myDrawer, theProjector);
238 aDefaultDrawer->SetTypeOfDeflection (aPrevDeflection);
7fd59977 239 }
240 }
7fd59977 241}
242
0717ddc1 243//=======================================================================
244//function : updateShape
245//purpose :
246//=======================================================================
247void AIS_ConnectedInteractive::updateShape (const Standard_Boolean isWithLocation)
7fd59977 248{
0717ddc1 249 Handle(AIS_Shape) anAisShape = Handle(AIS_Shape)::DownCast (myReference);
250 if (anAisShape.IsNull())
251 {
252 return;
253 }
254
255 TopoDS_Shape aShape = anAisShape->Shape();
256 if (aShape.IsNull())
257 {
258 return;
259 }
260
261 if(!isWithLocation)
262 {
263 myShape = aShape;
264 }
265 else
266 {
267 myShape = aShape.Moved (TopLoc_Location (Transformation()));
268 }
7fd59977 269}
0717ddc1 270
271//=======================================================================
272//function : ComputeSelection
273//purpose :
274//=======================================================================
275void AIS_ConnectedInteractive::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
276 const Standard_Integer theMode)
7fd59977 277{
0717ddc1 278 if (!HasConnection())
279 {
280 return;
281 }
282
283 if (theMode != 0 && myReference->AcceptShapeDecomposition())
284 {
285 computeSubShapeSelection (theSelection, theMode);
286 return;
287 }
288
289 if (!myReference->HasSelection (theMode))
290 {
f751596e 291 myReference->RecomputePrimitives (theMode);
0717ddc1 292 }
293
294 const Handle(SelectMgr_Selection)& TheRefSel = myReference->Selection (theMode);
295 Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
296 Handle(Select3D_SensitiveEntity) aSensitive, aNewSensitive;
f751596e 297
298 TopLoc_Location aLocation (Transformation());
299 anOwner->SetLocation (aLocation);
300
0717ddc1 301 if (TheRefSel->IsEmpty())
302 {
f751596e 303 myReference->RecomputePrimitives (theMode);
0717ddc1 304 }
305
306 for (TheRefSel->Init(); TheRefSel->More(); TheRefSel->Next())
307 {
f751596e 308 aSensitive = Handle(Select3D_SensitiveEntity)::DownCast (TheRefSel->Sensitive()->BaseSensitive());
0717ddc1 309 if (!aSensitive.IsNull())
310 {
0717ddc1 311 // Get the copy of SE3D
f751596e 312 aNewSensitive = aSensitive->GetConnected();
0717ddc1 313
314 aNewSensitive->Set(anOwner);
0717ddc1 315
316 theSelection->Add (aNewSensitive);
317 }
318 }
7fd59977 319}
0717ddc1 320
321//=======================================================================
322//function : ComputeSubShapeSelection
323//purpose :
324//=======================================================================
325void AIS_ConnectedInteractive::computeSubShapeSelection (const Handle(SelectMgr_Selection)& theSelection,
326 const Standard_Integer theMode)
7fd59977 327{
0717ddc1 328 typedef NCollection_List<Handle(Select3D_SensitiveEntity)> SensitiveList;
329 typedef NCollection_DataMap<TopoDS_Shape, SensitiveList, TopTools_OrientedShapeMapHasher>
330 Shapes2EntitiesMap;
331
332 if (!myReference->HasSelection (theMode))
f751596e 333 myReference->RecomputePrimitives (theMode);
0717ddc1 334
335 const Handle(SelectMgr_Selection)& aRefSel = myReference->Selection (theMode);
336
337 if (aRefSel->IsEmpty() || aRefSel->UpdateStatus() == SelectMgr_TOU_Full)
338 {
f751596e 339 myReference->RecomputePrimitives (theMode);
0717ddc1 340 }
341
342 Handle(StdSelect_BRepOwner) anOwner;
343 TopLoc_Location aDummyLoc;
344
345 Handle(Select3D_SensitiveEntity) aSE, aNewSE;
346 Shapes2EntitiesMap aShapes2EntitiesMap;
347
348 SensitiveList aSEList;
349 TopoDS_Shape aSubShape;
350
351 // Fill in the map of subshapes and corresponding
352 // sensitive entities associated with aMode
353 for (aRefSel->Init(); aRefSel->More(); aRefSel->Next())
354 {
f751596e 355 aSE = Handle(Select3D_SensitiveEntity)::DownCast (aRefSel->Sensitive()->BaseSensitive());
0717ddc1 356 if(!aSE.IsNull())
357 {
358 anOwner = Handle(StdSelect_BRepOwner)::DownCast (aSE->OwnerId());
359 if(!anOwner.IsNull())
360 {
361 aSubShape = anOwner->Shape();
362 if(!aShapes2EntitiesMap.IsBound (aSubShape))
363 {
364 aShapes2EntitiesMap.Bind (aSubShape, aSEList);
365 }
366 aShapes2EntitiesMap (aSubShape).Append (aSE);
367 }
368 }
369 }
370
371 // Fill in selection from aShapes2EntitiesMap
372 for (Shapes2EntitiesMap::Iterator aMapIt (aShapes2EntitiesMap); aMapIt.More(); aMapIt.Next())
373 {
374 aSEList = aMapIt.Value();
375 anOwner = new StdSelect_BRepOwner (aMapIt.Key(),
376 this,
377 aSEList.First()->OwnerId()->Priority(),
378 Standard_True);
f751596e 379 anOwner->SetLocation (Transformation());
0717ddc1 380
381 for (SensitiveList::Iterator aListIt (aSEList); aListIt.More(); aListIt.Next())
f751596e 382 {
0717ddc1 383 aSE = aListIt.Value();
384
f751596e 385 aNewSE = aSE->GetConnected();
0717ddc1 386 aNewSE->Set (anOwner);
0717ddc1 387
388 theSelection->Add (aNewSE);
389 }
390 }
391
392 StdSelect::SetDrawerForBRepOwner (theSelection, myDrawer);
393}