0031425: Visualization - free Edge has selection sensitivity inconsistent to presentation
[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
42cf5bc1 17#include <AIS_ConnectedInteractive.hxx>
1f7f5a90 18
42cf5bc1 19#include <AIS_InteractiveContext.hxx>
42cf5bc1 20#include <AIS_Shape.hxx>
21#include <BRepTools.hxx>
42cf5bc1 22#include <NCollection_DataMap.hxx>
23#include <Precision.hxx>
24#include <Prs3d_Drawer.hxx>
42cf5bc1 25#include <Prs3d_Projector.hxx>
42cf5bc1 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>
5ad8c033 33#include <StdPrs_WFShape.hxx>
0717ddc1 34#include <StdSelect.hxx>
42cf5bc1 35#include <StdSelect_BRepOwner.hxx>
36#include <TopAbs_ShapeEnum.hxx>
37#include <TopoDS_Shape.hxx>
0717ddc1 38#include <TopTools_IndexedMapOfShape.hxx>
39#include <TopTools_OrientedShapeMapHasher.hxx>
40
92efcf78 41IMPLEMENT_STANDARD_RTTIEXT(AIS_ConnectedInteractive,AIS_InteractiveObject)
42
7fd59977 43//=======================================================================
44//function : AIS_ConnectedInteractive
45//purpose :
46//=======================================================================
47AIS_ConnectedInteractive::AIS_ConnectedInteractive(const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d):
48AIS_InteractiveObject(aTypeOfPresentation3d)
0717ddc1 49{
f838dac4 50 //
7fd59977 51}
52
53//=======================================================================
1f7f5a90 54//function : connect
55//purpose :
7fd59977 56//=======================================================================
1f7f5a90 57void AIS_ConnectedInteractive::connect (const Handle(AIS_InteractiveObject)& theAnotherObj,
58 const Handle(Geom_Transformation)& theLocation)
7fd59977 59{
1f7f5a90 60 if (myReference == theAnotherObj)
61 {
62 setLocalTransformation (theLocation);
63 return;
64 }
0717ddc1 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 }
40f70ac9 75 else
76 {
9775fa61 77 throw Standard_ProgramError("AIS_ConnectedInteractive::Connect() - object without own presentation can not be connected");
40f70ac9 78 }
0717ddc1 79
80 if (!myReference.IsNull())
81 {
cc99be36 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 }
0717ddc1 88 myTypeOfPresentation3d = myReference->TypeOfPresentation3d();
89 }
1f7f5a90 90 setLocalTransformation (theLocation);
7fd59977 91}
92
93//=======================================================================
7fd59977 94//function : Disconnect
af324faa 95//purpose :
7fd59977 96//=======================================================================
97
98void AIS_ConnectedInteractive::Disconnect()
99{
7dd7c146 100 for (PrsMgr_Presentations::Iterator aPrsIter (myPresentations); aPrsIter.More(); aPrsIter.Next())
af324faa 101 {
7dd7c146 102 const Handle(PrsMgr_Presentation)& aPrs = aPrsIter.Value();
af324faa 103 if (!aPrs.IsNull())
7fd59977 104 {
7dd7c146 105 aPrs->DisconnectAll (Graphic3d_TOC_DESCENDANT);
7fd59977 106 }
af324faa 107 }
7fd59977 108}
109//=======================================================================
110//function : Compute
792c785c 111//purpose :
7fd59977 112//=======================================================================
792c785c 113void AIS_ConnectedInteractive::Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
114 const Handle(Prs3d_Presentation)& thePrs,
115 const Standard_Integer theMode)
7fd59977 116{
792c785c 117 if (HasConnection())
118 {
119 thePrs->Clear (Standard_False);
7dd7c146 120 thePrs->DisconnectAll (Graphic3d_TOC_DESCENDANT);
792c785c 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
0717ddc1 133 if (!thePrs.IsNull())
792c785c 134 {
0717ddc1 135 thePrs->ReCompute();
7fd59977 136 }
7fd59977 137}
138
0717ddc1 139//=======================================================================
140//function : Compute
141//purpose :
142//=======================================================================
143void AIS_ConnectedInteractive::Compute (const Handle(Prs3d_Projector)& theProjector,
144 const Handle(Geom_Transformation)& theTransformation,
145 const Handle(Prs3d_Presentation)& thePresentation)
7fd59977 146{
0717ddc1 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);
7fd59977 155}
156
0717ddc1 157//=======================================================================
158//function : Compute
159//purpose :
160//=======================================================================
857ffd5e 161void AIS_ConnectedInteractive::Compute(const Handle(Prs3d_Projector)& aProjector, const Handle(Prs3d_Presentation)& aPresentation)
7fd59977 162{
0717ddc1 163 updateShape (Standard_True);
164 Compute (aProjector, aPresentation, myShape);
7fd59977 165}
166
7fd59977 167//=======================================================================
0717ddc1 168//function : Compute
169//purpose :
7fd59977 170//=======================================================================
0717ddc1 171void AIS_ConnectedInteractive::Compute (const Handle(Prs3d_Projector)& theProjector,
c7ba4578 172 const Handle(Prs3d_Presentation)& thePrs,
0717ddc1 173 const TopoDS_Shape& theShape)
7fd59977 174{
c7ba4578 175 AIS_Shape::computeHlrPresentation (theProjector, thePrs, theShape, myDrawer);
7fd59977 176}
177
0717ddc1 178//=======================================================================
179//function : updateShape
180//purpose :
181//=======================================================================
182void AIS_ConnectedInteractive::updateShape (const Standard_Boolean isWithLocation)
7fd59977 183{
0717ddc1 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 }
7fd59977 204}
0717ddc1 205
206//=======================================================================
207//function : ComputeSelection
208//purpose :
209//=======================================================================
210void AIS_ConnectedInteractive::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
211 const Standard_Integer theMode)
7fd59977 212{
0717ddc1 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 {
f751596e 226 myReference->RecomputePrimitives (theMode);
0717ddc1 227 }
228
229 const Handle(SelectMgr_Selection)& TheRefSel = myReference->Selection (theMode);
230 Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
f751596e 231
232 TopLoc_Location aLocation (Transformation());
233 anOwner->SetLocation (aLocation);
234
0717ddc1 235 if (TheRefSel->IsEmpty())
236 {
f751596e 237 myReference->RecomputePrimitives (theMode);
0717ddc1 238 }
239
b5cce1ab 240 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (TheRefSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
0717ddc1 241 {
0ef04197 242 if (const Handle(Select3D_SensitiveEntity)& aSensitive = aSelEntIter.Value()->BaseSensitive())
0717ddc1 243 {
0717ddc1 244 // Get the copy of SE3D
834f2897 245 if (Handle(Select3D_SensitiveEntity) aNewSensitive = aSensitive->GetConnected())
246 {
247 aNewSensitive->Set(anOwner);
248 theSelection->Add (aNewSensitive);
249 }
0717ddc1 250 }
251 }
7fd59977 252}
0717ddc1 253
254//=======================================================================
255//function : ComputeSubShapeSelection
256//purpose :
257//=======================================================================
258void AIS_ConnectedInteractive::computeSubShapeSelection (const Handle(SelectMgr_Selection)& theSelection,
259 const Standard_Integer theMode)
7fd59977 260{
0717ddc1 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))
b5cce1ab 266 {
f751596e 267 myReference->RecomputePrimitives (theMode);
b5cce1ab 268 }
0717ddc1 269
b5cce1ab 270 const Handle(SelectMgr_Selection)& aRefSel = myReference->Selection (theMode);
0717ddc1 271 if (aRefSel->IsEmpty() || aRefSel->UpdateStatus() == SelectMgr_TOU_Full)
272 {
f751596e 273 myReference->RecomputePrimitives (theMode);
0717ddc1 274 }
0717ddc1 275
b5cce1ab 276 // Fill in the map of subshapes and corresponding sensitive entities associated with aMode
0717ddc1 277 Shapes2EntitiesMap aShapes2EntitiesMap;
b5cce1ab 278 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aRefSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
0717ddc1 279 {
0ef04197 280 if (const Handle(Select3D_SensitiveEntity)& aSE = aSelEntIter.Value()->BaseSensitive())
0717ddc1 281 {
b5cce1ab 282 if (Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast (aSE->OwnerId()))
0717ddc1 283 {
b5cce1ab 284 const TopoDS_Shape& aSubShape = anOwner->Shape();
0717ddc1 285 if(!aShapes2EntitiesMap.IsBound (aSubShape))
286 {
b5cce1ab 287 aShapes2EntitiesMap.Bind (aSubShape, SensitiveList());
0717ddc1 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 {
b5cce1ab 297 const SensitiveList& aSEList = aMapIt.Value();
298 Handle(StdSelect_BRepOwner) anOwner = new StdSelect_BRepOwner (aMapIt.Key(), this, aSEList.First()->OwnerId()->Priority(), Standard_True);
f751596e 299 anOwner->SetLocation (Transformation());
0717ddc1 300 for (SensitiveList::Iterator aListIt (aSEList); aListIt.More(); aListIt.Next())
f751596e 301 {
834f2897 302 if (Handle(Select3D_SensitiveEntity) aNewSE = aListIt.Value()->GetConnected())
303 {
304 aNewSE->Set (anOwner);
305 theSelection->Add (aNewSE);
306 }
0717ddc1 307 }
308 }
309
310 StdSelect::SetDrawerForBRepOwner (theSelection, myDrawer);
311}