0031322: Visualization, Select3D_SensitiveEntity - method NbSubElements() should...
[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(SelectMgr_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() const
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_PickResult& thePickResult,
116                                                           SelectBasics_SelectingVolumeManager& theMgr,
117                                                           Standard_Integer theElemIdx,
118                                                           Standard_Boolean )
119 {
120   const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (theElemIdx);
121   const Handle(SelectBasics_SensitiveEntity)& aSeg = myEntities.Value (aSensitiveIdx);
122   return aSeg->Matches (theMgr, thePickResult);
123 }
124
125 // =======================================================================
126 // function : elementIsInside
127 // purpose  :
128 // =======================================================================
129 Standard_Boolean Select3D_SensitiveWire::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr,
130                                                           Standard_Integer theElemIdx,
131                                                           Standard_Boolean )
132 {
133   SelectBasics_PickResult aMatchResult;
134   return myEntities.Value (myEntityIndexes.Value (theElemIdx))->Matches (theMgr, aMatchResult);
135 }
136
137 // =======================================================================
138 // function : distanceToCOG
139 // purpose  : Calculates distance from the 3d projection of used-picked
140 //            screen point to center of the geometry
141 // =======================================================================
142 Standard_Real Select3D_SensitiveWire::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr)
143 {
144   return theMgr.DistToGeometryCenter (myCenter);
145 }
146
147 //=======================================================================
148 //function : GetConnected
149 //purpose  :
150 //=======================================================================
151
152 Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetConnected()
153 {
154   Handle(Select3D_SensitiveWire) aNewEntity = new Select3D_SensitiveWire (myOwnerId);
155   for (Standard_Integer anEntityIdx = 0; anEntityIdx < myEntities.Length(); anEntityIdx++)
156     aNewEntity->Add (myEntities(anEntityIdx)->GetConnected());
157
158   return aNewEntity;
159 }
160
161 //=======================================================================
162 //function : GetEdges
163 //purpose  : returns the sensitive edges stored in this wire
164 //=======================================================================
165 const NCollection_Vector<Handle(Select3D_SensitiveEntity)>& Select3D_SensitiveWire::GetEdges()
166 {
167   return myEntities;
168 }
169
170 //=============================================================================
171 // Function : GetLastDetected
172 // Purpose  :
173 //=============================================================================
174 Handle(Select3D_SensitiveEntity) Select3D_SensitiveWire::GetLastDetected() const
175 {
176   Handle(Select3D_SensitiveEntity) aRes;
177
178   if (myDetectedIdx >= 0 && myDetectedIdx < myEntities.Length())
179   {
180     const Standard_Integer aSensitiveIdx = myEntityIndexes.Value (myDetectedIdx);
181     aRes = myEntities.Value (aSensitiveIdx);
182   }
183
184   return aRes;
185 }
186
187 //=======================================================================
188 //function : Set
189 //purpose  :
190 //=======================================================================
191 void Select3D_SensitiveWire::Set (const Handle(SelectMgr_EntityOwner)& theOwnerId)
192 {
193   Select3D_SensitiveEntity::Set (theOwnerId);
194
195   // Set TheOwnerId for each element of sensitive wire
196   for (Standard_Integer anEntityIdx = 0; anEntityIdx < myEntities.Length(); ++anEntityIdx)
197   {
198     myEntities.Value (anEntityIdx)->Set (theOwnerId);
199   }
200 }
201
202 //=======================================================================
203 // function : BoundingBox
204 // purpose  : Returns bounding box of the wire. If location
205 //            transformation is set, it will be applied
206 //=======================================================================
207 Select3D_BndBox3d Select3D_SensitiveWire::BoundingBox()
208 {
209   if (myBndBox.IsValid())
210     return myBndBox;
211
212   for (Standard_Integer aSensitiveIdx = 0; aSensitiveIdx < myEntities.Length(); ++aSensitiveIdx)
213   {
214     myBndBox.Combine (myEntities.Value (aSensitiveIdx)->BoundingBox());
215   }
216
217   return myBndBox;
218 }
219
220 //=======================================================================
221 // function : CenterOfGeometry
222 // purpose  : Returns center of the wire. If location transformation
223 //            is set, it will be applied
224 //=======================================================================
225 gp_Pnt Select3D_SensitiveWire::CenterOfGeometry() const
226 {
227   return myCenter;
228 }