0029938: Visualization - SelectMgr_ViewerSelector::PickedPoint() should return point...
[occt.git] / src / Select3D / Select3D_SensitiveWire.cxx
1 // Created on: 1996-10-17
2 // Created by: Odile OLIVIER
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <Select3D_SensitiveWire.hxx>
18 #include <Select3D_SensitiveEntity.hxx>
19 #include <Precision.hxx>
20 #include <TopLoc_Location.hxx>
21
22 #include <Select3D_SensitiveSegment.hxx>
23
24
25 IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveWire,Select3D_SensitiveSet)
26
27 //=====================================================
28 // Function : Select3D_SensitiveWire
29 // Purpose  :
30 //=====================================================
31 Select3D_SensitiveWire::Select3D_SensitiveWire (const Handle(SelectBasics_EntityOwner)& theOwnerId)
32 : Select3D_SensitiveSet (theOwnerId),
33   myCenter (0.0, 0.0, 0.0)
34 {}
35
36 //=====================================================
37 // Function : Add
38 // Purpose  :
39 //=====================================================
40 void Select3D_SensitiveWire::Add (const Handle(Select3D_SensitiveEntity)& theSensitive)
41 {
42   if (!theSensitive.IsNull())
43     myEntities.Append (theSensitive);
44
45   Select3D_BndBox3d aBndBox = theSensitive->BoundingBox();
46   myBndBox.Combine (aBndBox);
47   myCenter.ChangeCoord() += theSensitive->CenterOfGeometry().XYZ();
48   if (myEntities.Length() != 1)
49     myCenter.ChangeCoord().Divide (2.0);
50   myEntityIndexes.Append (myEntities.Length() - 1);
51 }
52
53 //=======================================================================
54 // function : NbSubElements
55 // purpose  : Returns the amount of sub-entities
56 //=======================================================================
57 Standard_Integer Select3D_SensitiveWire::NbSubElements()
58 {
59   return myEntities.Length();
60 }
61
62 //=======================================================================
63 // function : Size
64 // purpose  : Returns the length of vector of sensitive entities
65 //=======================================================================
66 Standard_Integer Select3D_SensitiveWire::Size() const
67 {
68   return myEntities.Length();
69 }
70
71 //=======================================================================
72 // function : Box
73 // purpose  : Returns bounding box of sensitive entity with index theIdx
74 //=======================================================================
75 Select3D_BndBox3d Select3D_SensitiveWire::Box (const Standard_Integer theIdx) const
76 {
77   const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (theIdx);
78   return myEntities.Value (aSensitiveIdx)->BoundingBox();
79 }
80
81 //=======================================================================
82 // function : Center
83 // purpose  : Returns geometry center of sensitive entity with index
84 //            theIdx in the vector along the given axis theAxis
85 //=======================================================================
86 Standard_Real Select3D_SensitiveWire::Center (const Standard_Integer theIdx,
87                                               const Standard_Integer theAxis) const
88 {
89   const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (theIdx);
90   const gp_Pnt& aCenter = myEntities.Value (aSensitiveIdx)->CenterOfGeometry();
91   Standard_Real aCenterCoord = 0.0;
92   aCenterCoord = theAxis == 0 ? aCenter.X() : (theAxis == 1 ? aCenter.Y() : aCenter.Z());
93
94   return aCenterCoord;
95 }
96
97 //=======================================================================
98 // function : Swap
99 // purpose  : Swaps items with indexes theIdx1 and theIdx2 in the vector
100 //=======================================================================
101 void Select3D_SensitiveWire::Swap (const Standard_Integer theIdx1,
102                                    const Standard_Integer theIdx2)
103 {
104   const Standard_Integer aSensitiveIdx1 = myEntityIndexes.Value (theIdx1);
105   const Standard_Integer aSensitiveIdx2 = myEntityIndexes.Value (theIdx2);
106   myEntityIndexes.ChangeValue (theIdx1) = aSensitiveIdx2;
107   myEntityIndexes.ChangeValue (theIdx2) = aSensitiveIdx1;
108 }
109
110 // =======================================================================
111 // function : overlapsElement
112 // purpose  : Checks whether the entity with index theIdx overlaps the
113 //            current selecting volume
114 // =======================================================================
115 Standard_Boolean Select3D_SensitiveWire::overlapsElement (SelectBasics_SelectingVolumeManager& theMgr,
116                                                           Standard_Integer theElemIdx,
117                                                           SelectBasics_PickResult& thePickResult)
118 {
119   const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (theElemIdx);
120   const Handle(SelectBasics_SensitiveEntity)& aSeg = myEntities.Value (aSensitiveIdx);
121   return aSeg->Matches (theMgr, thePickResult);
122 }
123
124 // =======================================================================
125 // function : elementIsInside
126 // purpose  :
127 // =======================================================================
128 Standard_Boolean Select3D_SensitiveWire::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
129                                                           const Standard_Integer               theElemIdx)
130 {
131   SelectBasics_PickResult aMatchResult;
132   return myEntities.Value (myEntityIndexes.Value (theElemIdx))->Matches (theMgr, aMatchResult);
133 }
134
135 // =======================================================================
136 // function : distanceToCOG
137 // purpose  : Calculates distance from the 3d projection of used-picked
138 //            screen point to center of the geometry
139 // =======================================================================
140 Standard_Real Select3D_SensitiveWire::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
141 {
142   return theMgr.DistToGeometryCenter (myCenter);
143 }
144
145 //=======================================================================
146 //function : GetConnected
147 //purpose  :
148 //=======================================================================
149
150 Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetConnected()
151 {
152   Handle(Select3D_SensitiveWire) aNewEntity = new Select3D_SensitiveWire (myOwnerId);
153   for (Standard_Integer anEntityIdx = 0; anEntityIdx < myEntities.Length(); anEntityIdx++)
154     aNewEntity->Add (myEntities(anEntityIdx)->GetConnected());
155
156   return aNewEntity;
157 }
158
159 //=======================================================================
160 //function : GetEdges
161 //purpose  : returns the sensitive edges stored in this wire
162 //=======================================================================
163 const NCollection_Vector<Handle(Select3D_SensitiveEntity)>& Select3D_SensitiveWire::GetEdges()
164 {
165   return myEntities;
166 }
167
168 //=============================================================================
169 // Function : GetLastDetected
170 // Purpose  :
171 //=============================================================================
172 Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetLastDetected() const
173 {
174   Handle(Select3D_SensitiveEntity) aRes;
175
176   if (myDetectedIdx >= 0 && myDetectedIdx < myEntities.Length())
177   {
178     const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (myDetectedIdx);
179     aRes = myEntities.Value (aSensitiveIdx);
180   }
181
182   return aRes;
183 }
184
185 //=======================================================================
186 //function : Set
187 //purpose  :
188 //=======================================================================
189 void Select3D_SensitiveWire::Set (const Handle(SelectBasics_EntityOwner)& theOwnerId)
190 {
191   Select3D_SensitiveEntity::Set (theOwnerId);
192
193   // Set TheOwnerId for each element of sensitive wire
194   for (Standard_Integer anEntityIdx = 0; anEntityIdx < myEntities.Length(); ++anEntityIdx)
195   {
196     myEntities.Value (anEntityIdx)->Set (theOwnerId);
197   }
198 }
199
200 //=======================================================================
201 // function : BoundingBox
202 // purpose  : Returns bounding box of the wire. If location
203 //            transformation is set, it will be applied
204 //=======================================================================
205 Select3D_BndBox3d Select3D_SensitiveWire::BoundingBox()
206 {
207   if (myBndBox.IsValid())
208     return myBndBox;
209
210   for (Standard_Integer aSensitiveIdx = 0; aSensitiveIdx < myEntities.Length(); ++aSensitiveIdx)
211   {
212     myBndBox.Combine (myEntities.Value (aSensitiveIdx)->BoundingBox());
213   }
214
215   return myBndBox;
216 }
217
218 //=======================================================================
219 // function : CenterOfGeometry
220 // purpose  : Returns center of the wire. If location transformation
221 //            is set, it will be applied
222 //=======================================================================
223 gp_Pnt Select3D_SensitiveWire::CenterOfGeometry() const
224 {
225   return myCenter;
226 }