0024623: Visualization - improve selection mechanism
[occt.git] / src / IVtkOCC / IVtkOCC_SelectableObject.cxx
CommitLineData
913a4c4a 1// Created on: 2011-10-20
2// Created by: Roman KOZLOV
3// Copyright (c) 2011-2014 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16#include <AIS_Shape.hxx>
17#include <BRepBndLib.hxx>
18#include <IVtkOCC_SelectableObject.hxx>
19#include <Select3D_SensitiveBox.hxx>
20#include <SelectMgr_Selection.hxx>
21#include <Standard_ErrorHandler.hxx>
22#include <StdSelect_BRepOwner.hxx>
23#include <StdSelect_BRepSelectionTool.hxx>
24#include <TopoDS_Iterator.hxx>
25
26// Handle implementation
27IMPLEMENT_STANDARD_HANDLE( IVtkOCC_SelectableObject, SelectMgr_SelectableObject )
28IMPLEMENT_STANDARD_RTTIEXT( IVtkOCC_SelectableObject, SelectMgr_SelectableObject )
29
30//============================================================================
31// Method: Constructor
32// Purpose: Constructs a selectable object initalized by the given shape
33//============================================================================
34IVtkOCC_SelectableObject::IVtkOCC_SelectableObject (const IVtkOCC_Shape::Handle& theShape)
35: SelectMgr_SelectableObject (PrsMgr_TOP_AllView),
36 myShape (theShape)
37{
38 if (!myShape.IsNull())
39 {
40 myShape->SetSelectableObject (this);
41 }
42
43 // Minor stuff - but it facilitates usage of OCCT selection
44 // classes dealing with deflection, see ComputeSelection() below
45 myOCCTDrawer = new Prs3d_Drawer();
46}
47
48//============================================================================
49// Method: Constructor
50// Purpose: Constructs uninitialized selectable object.
51// setShape() should be called later.
52//============================================================================
53IVtkOCC_SelectableObject::IVtkOCC_SelectableObject()
54: SelectMgr_SelectableObject (PrsMgr_TOP_AllView),
55 myShape (0)
56{ }
57
58//============================================================================
59// Method: SetShape
60// Purpose: Sets the selectable shape
61//============================================================================
62void IVtkOCC_SelectableObject::SetShape (const IVtkOCC_Shape::Handle& theShape)
63{
64 myShape = theShape;
65 if (myShape)
66 {
67 myShape->SetSelectableObject (this);
68 }
69
70 // Shape has changed -> Clear all internal data
71 myBndBox.SetVoid();
72 myselections.Clear();
73}
74
75//============================================================================
76// Method: ComputeSelection
77// Purpose: Internal method, computes selection data for viewer selector
78//============================================================================
79void IVtkOCC_SelectableObject::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
80 const Standard_Integer theMode)
81{
82 if (!myShape)
83 {
84 return;
85 }
86
87 TopoDS_Shape anOcctShape = myShape->GetShape();
88
89 if (anOcctShape.ShapeType() == TopAbs_COMPOUND)
90 {
91 TopoDS_Iterator anExplor (anOcctShape);
92 if (!anExplor.More()) // Shape empty -> go away
93 {
94 return;
95 }
96 }
97
98 TopAbs_ShapeEnum aTypeOfSel = AIS_Shape::SelectionType (theMode);
99
100 Standard_Real aDeflection = myOCCTDrawer->MaximalChordialDeviation();
101 if (myOCCTDrawer->TypeOfDeflection() == Aspect_TOD_RELATIVE)
102 {
103 Bnd_Box aBndBox;
104 BRepBndLib::Add (anOcctShape, aBndBox);
105 if (!aBndBox.IsVoid())
106 {
107 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
108 aBndBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
109 aDeflection = Max (aXmax - aXmin, Max (aYmax - aYmin, aZmax - aZmin)) *
110 myOCCTDrawer->DeviationCoefficient();
111 }
112 }
113
114 // Assume the shape has been displayed already -> triangulation should exist
115 Standard_Boolean isAutoTriangulation = Standard_False;
116
117 try
118 {
119 OCC_CATCH_SIGNALS
120 StdSelect_BRepSelectionTool::Load (theSelection,
121 this,
122 anOcctShape,
123 aTypeOfSel,
124 aDeflection,
125 myOCCTDrawer->DeviationAngle(),
126 isAutoTriangulation);
127 }
128 catch (Standard_Failure)
129 {
130 if (theMode == 0)
131 {
132 Bnd_Box aBndBox = BoundingBox();
133 Handle(StdSelect_BRepOwner) aOwner = new StdSelect_BRepOwner (anOcctShape, this);
134 Handle(Select3D_SensitiveBox) aSensitiveBox =
135 new Select3D_SensitiveBox (aOwner, aBndBox);
136 theSelection->Add (aSensitiveBox);
137 }
138 }
139}
140
141//============================================================================
142// Method: BoundingBox
143// Purpose:
144//============================================================================
145const Bnd_Box& IVtkOCC_SelectableObject::BoundingBox()
146{
147 if (!myShape)
148 {
149 myBndBox.SetVoid();
150 return myBndBox;
151 }
152
153 TopoDS_Shape anOcctShape = myShape->GetShape();
154
155 if (anOcctShape.ShapeType() == TopAbs_COMPOUND)
156 {
157 TopoDS_Iterator anExplor (anOcctShape);
158 if (!anExplor.More())
159 { // Shape empty -> nothing to do
160 myBndBox.SetVoid();
161 return myBndBox;
162 }
163 }
164
165 if (myBndBox.IsVoid())
166 {
167 // Add only edges and vertices, in case of troubles this should work anyway
168 BRepBndLib::AddClose (anOcctShape, myBndBox);
169 }
170
171 return myBndBox;
172}
f751596e 173
174//============================================================================
175// Method: BoundingBox
176// Purpose:
177//============================================================================
178void IVtkOCC_SelectableObject::BoundingBox (Bnd_Box& theBndBox)
179{
180 BoundingBox();
181 theBndBox = myBndBox;
182}