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 |
27 | IMPLEMENT_STANDARD_HANDLE( IVtkOCC_SelectableObject, SelectMgr_SelectableObject ) |
28 | IMPLEMENT_STANDARD_RTTIEXT( IVtkOCC_SelectableObject, SelectMgr_SelectableObject ) |
29 | |
30 | //============================================================================ |
31 | // Method: Constructor |
32 | // Purpose: Constructs a selectable object initalized by the given shape |
33 | //============================================================================ |
34 | IVtkOCC_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 | //============================================================================ |
53 | IVtkOCC_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 | //============================================================================ |
62 | void 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 | //============================================================================ |
79 | void 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 | //============================================================================ |
145 | const 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 | } |