973c2be1 |
1 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
2 | // |
973c2be1 |
3 | // This file is part of Open CASCADE Technology software library. |
b311480e |
4 | // |
d5f74e42 |
5 | // This library is free software; you can redistribute it and/or modify it under |
6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
7 | // by the Free Software Foundation, with special exception defined in the file |
8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
9 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
10 | // |
973c2be1 |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
b311480e |
13 | |
f751596e |
14 | #include <Select3D_SensitivePoly.hxx> |
15 | |
92efcf78 |
16 | IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitivePoly,Select3D_SensitiveSet) |
17 | |
7fd59977 |
18 | //================================================== |
f751596e |
19 | // Function: Select3D_SensitivePoly |
20 | // Purpose : |
7fd59977 |
21 | //================================================== |
0ef04197 |
22 | Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwner)& theOwnerId, |
f751596e |
23 | const TColgp_Array1OfPnt& thePoints, |
24 | const Standard_Boolean theIsBVHEnabled) |
25 | : Select3D_SensitiveSet (theOwnerId), |
26 | myPolyg (thePoints.Upper() - thePoints.Lower() + 1) |
27 | { |
28 | Standard_Integer aLowerIdx = thePoints.Lower(); |
29 | Standard_Integer anUpperIdx = thePoints.Upper(); |
30 | gp_XYZ aPntSum (0.0, 0.0, 0.0); |
31 | |
32 | Select3D_BndBox3d aBndBox; |
33 | for (Standard_Integer aIdx = aLowerIdx; aIdx <= anUpperIdx; ++aIdx) |
34 | { |
35 | aPntSum += thePoints.Value (aIdx).XYZ(); |
36 | const SelectMgr_Vec3 aPnt (thePoints.Value (aIdx).X(), |
37 | thePoints.Value (aIdx).Y(), |
38 | thePoints.Value (aIdx).Z()); |
39 | aBndBox.Add (aPnt); |
40 | myPolyg.SetPnt (aIdx - aLowerIdx, thePoints.Value (aIdx)); |
41 | } |
42 | |
43 | myBndBox = aBndBox; |
44 | myCOG = aPntSum / myPolyg.Size(); |
7fd59977 |
45 | |
f751596e |
46 | if (theIsBVHEnabled) |
47 | { |
48 | const Standard_Integer aPntsNum = myPolyg.Size(); |
49 | mySegmentIndexes = new TColStd_HArray1OfInteger (0, aPntsNum - 2); |
50 | for (Standard_Integer aSegmIter = 0; aSegmIter < aPntsNum - 1; ++aSegmIter) |
51 | { |
52 | mySegmentIndexes->SetValue (aSegmIter, aSegmIter); |
53 | } |
54 | } |
2157d6ac |
55 | |
56 | myIsComputed = Standard_True; |
f751596e |
57 | } |
58 | |
59 | //================================================== |
60 | // Function: Select3D_SensitivePoly |
61 | // Purpose : |
62 | //================================================== |
0ef04197 |
63 | Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwner)& theOwnerId, |
f751596e |
64 | const Handle(TColgp_HArray1OfPnt)& thePoints, |
65 | const Standard_Boolean theIsBVHEnabled) |
66 | : Select3D_SensitiveSet (theOwnerId), |
67 | myPolyg (thePoints->Upper() - thePoints->Lower() + 1) |
7fd59977 |
68 | { |
f751596e |
69 | Standard_Integer aLowerIdx = thePoints->Lower(); |
70 | Standard_Integer anUpperIdx = thePoints->Upper(); |
71 | gp_XYZ aPntSum (0.0, 0.0, 0.0); |
72 | |
73 | Select3D_BndBox3d aBndBox; |
74 | for (Standard_Integer aIdx = aLowerIdx; aIdx <= anUpperIdx; ++aIdx) |
75 | { |
76 | aPntSum += thePoints->Value (aIdx).XYZ(); |
77 | const SelectMgr_Vec3 aPnt (thePoints->Value (aIdx).X(), |
78 | thePoints->Value (aIdx).Y(), |
79 | thePoints->Value (aIdx).Z()); |
80 | aBndBox.Add (aPnt); |
81 | myPolyg.SetPnt (aIdx - aLowerIdx, thePoints->Value (aIdx)); |
82 | } |
83 | |
84 | myBndBox = aBndBox; |
85 | myCOG = aPntSum / myPolyg.Size(); |
86 | |
87 | if (theIsBVHEnabled) |
88 | { |
89 | const Standard_Integer aPntsNum = myPolyg.Size(); |
90 | mySegmentIndexes = new TColStd_HArray1OfInteger (0, aPntsNum - 2); |
91 | for (Standard_Integer aSegmIter = 0; aSegmIter < aPntsNum - 1; ++aSegmIter) |
92 | { |
93 | mySegmentIndexes->SetValue (aSegmIter, aSegmIter); |
94 | } |
95 | } |
2157d6ac |
96 | |
97 | myIsComputed = Standard_True; |
7fd59977 |
98 | } |
99 | |
100 | //================================================== |
ac04d101 |
101 | // Function: Creation |
7fd59977 |
102 | // Purpose : |
103 | //================================================== |
0ef04197 |
104 | Select3D_SensitivePoly::Select3D_SensitivePoly (const Handle(SelectMgr_EntityOwner)& theOwnerId, |
f751596e |
105 | const Standard_Boolean theIsBVHEnabled, |
106 | const Standard_Integer theNbPnts) |
107 | : Select3D_SensitiveSet (theOwnerId), |
108 | myPolyg (theNbPnts) |
109 | { |
110 | if (theIsBVHEnabled) |
111 | { |
112 | mySegmentIndexes = new TColStd_HArray1OfInteger (0, theNbPnts - 2); |
113 | for (Standard_Integer aIdx = 0; aIdx < theNbPnts - 1; ++aIdx) |
114 | { |
115 | mySegmentIndexes->SetValue (aIdx, aIdx); |
116 | } |
117 | } |
118 | myCOG = gp_Pnt (RealLast(), RealLast(), RealLast()); |
2157d6ac |
119 | myIsComputed = Standard_False; |
f751596e |
120 | } |
7fd59977 |
121 | |
f751596e |
122 | //================================================== |
123 | // function : BoundingBox |
124 | // purpose : Returns bounding box of a polygon. If location |
125 | // transformation is set, it will be applied |
126 | //================================================== |
127 | Select3D_BndBox3d Select3D_SensitivePoly::BoundingBox() |
7fd59977 |
128 | { |
f751596e |
129 | if (myBndBox.IsValid()) |
130 | return myBndBox; |
131 | |
132 | Select3D_BndBox3d aBndBox; |
133 | for (Standard_Integer aPntIter = 0; aPntIter < myPolyg.Size(); ++aPntIter) |
134 | { |
135 | SelectMgr_Vec3 aPnt (myPolyg.Pnt (aPntIter).x, |
136 | myPolyg.Pnt (aPntIter).y, |
137 | myPolyg.Pnt (aPntIter).z); |
138 | aBndBox.Add (aPnt); |
139 | } |
140 | |
141 | myBndBox = aBndBox; |
142 | |
143 | return myBndBox; |
7fd59977 |
144 | } |
145 | |
146 | //================================================== |
f751596e |
147 | // Function: Size |
148 | // Purpose : Returns the amount of segments of |
149 | // the poly |
7fd59977 |
150 | //================================================== |
f751596e |
151 | Standard_Integer Select3D_SensitivePoly::Size() const |
152 | { |
153 | if (!mySegmentIndexes.IsNull()) |
154 | return mySegmentIndexes->Length(); |
7fd59977 |
155 | |
f751596e |
156 | return -1; |
157 | } |
158 | |
159 | //================================================== |
160 | // Function: Box |
161 | // Purpose : Returns bounding box of segment with |
162 | // index theIdx |
163 | //================================================== |
164 | Select3D_BndBox3d Select3D_SensitivePoly::Box (const Standard_Integer theIdx) const |
7fd59977 |
165 | { |
f751596e |
166 | if (mySegmentIndexes.IsNull()) |
167 | return Select3D_BndBox3d (SelectMgr_Vec3 (RealLast())); |
168 | |
169 | const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theIdx); |
170 | gp_Pnt aPnt1 = myPolyg.Pnt3d (aSegmentIdx); |
171 | gp_Pnt aPnt2 = myPolyg.Pnt3d (aSegmentIdx + 1); |
172 | |
173 | const SelectMgr_Vec3 aMinPnt (Min (aPnt1.X(), aPnt2.X()), |
174 | Min (aPnt1.Y(), aPnt2.Y()), |
175 | Min (aPnt1.Z(), aPnt2.Z())); |
176 | const SelectMgr_Vec3 aMaxPnt (Max (aPnt1.X(), aPnt2.X()), |
177 | Max (aPnt1.Y(), aPnt2.Y()), |
178 | Max (aPnt1.Z(), aPnt2.Z())); |
179 | |
180 | return Select3D_BndBox3d (aMinPnt, aMaxPnt); |
7fd59977 |
181 | } |
182 | |
183 | //================================================== |
f751596e |
184 | // Function: Center |
185 | // Purpose : Returns geometry center of sensitive |
186 | // entity index theIdx in the vector along |
187 | // the given axis theAxis |
188 | //================================================== |
189 | Standard_Real Select3D_SensitivePoly::Center (const Standard_Integer theIdx, |
190 | const Standard_Integer theAxis) const |
191 | { |
192 | if (mySegmentIndexes.IsNull()) |
193 | return RealLast(); |
194 | |
195 | const Select3D_BndBox3d aBndBox = Box (theIdx); |
0609d8ee |
196 | const SelectMgr_Vec3 aCenter = (aBndBox.CornerMin() + aBndBox.CornerMax()) * 0.5; |
f751596e |
197 | return theAxis == 0 ? aCenter.x() : (theAxis == 1 ? aCenter.y() : aCenter.z()); |
198 | } |
199 | |
200 | //================================================== |
201 | // Function: Swap |
202 | // Purpose : Swaps items with indexes theIdx1 and |
203 | // theIdx2 in the vector |
7fd59977 |
204 | //================================================== |
f751596e |
205 | void Select3D_SensitivePoly::Swap (const Standard_Integer theIdx1, |
206 | const Standard_Integer theIdx2) |
207 | { |
208 | if (mySegmentIndexes.IsNull()) |
209 | return; |
210 | |
211 | const Standard_Integer aSegmentIdx1 = mySegmentIndexes->Value (theIdx1); |
212 | const Standard_Integer aSegmentIdx2 = mySegmentIndexes->Value (theIdx2); |
213 | mySegmentIndexes->ChangeValue (theIdx1) = aSegmentIdx2; |
214 | mySegmentIndexes->ChangeValue (theIdx2) = aSegmentIdx1; |
f751596e |
215 | } |
7fd59977 |
216 | |
f751596e |
217 | //================================================== |
218 | // Function: overlapsElement |
219 | // Purpose : Checks whether the segment with index |
220 | // theIdx overlaps the current selecting |
221 | // volume |
222 | //================================================== |
4a056d20 |
223 | Standard_Boolean Select3D_SensitivePoly::overlapsElement (SelectBasics_PickResult& thePickResult, |
224 | SelectBasics_SelectingVolumeManager& theMgr, |
f751596e |
225 | Standard_Integer theElemIdx, |
4a056d20 |
226 | Standard_Boolean theIsFullInside) |
7fd59977 |
227 | { |
f751596e |
228 | if (mySegmentIndexes.IsNull()) |
4a056d20 |
229 | { |
f751596e |
230 | return Standard_False; |
4a056d20 |
231 | } |
232 | else if (theIsFullInside) |
233 | { |
234 | return Standard_True; |
235 | } |
7fd59977 |
236 | |
f751596e |
237 | const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theElemIdx); |
238 | gp_Pnt aPnt1 = myPolyg.Pnt3d (aSegmentIdx); |
239 | gp_Pnt aPnt2 = myPolyg.Pnt3d (aSegmentIdx + 1); |
17017555 |
240 | return theMgr.Overlaps (aPnt1, aPnt2, thePickResult); |
f751596e |
241 | } |
242 | |
2157d6ac |
243 | //================================================== |
244 | // Function : elementIsInside |
245 | // Purpose : |
246 | //================================================== |
247 | Standard_Boolean Select3D_SensitivePoly::elementIsInside (SelectBasics_SelectingVolumeManager& theMgr, |
4a056d20 |
248 | Standard_Integer theElemIdx, |
249 | Standard_Boolean theIsFullInside) |
2157d6ac |
250 | { |
4a056d20 |
251 | if (theIsFullInside) |
252 | { |
253 | return Standard_True; |
254 | } |
2157d6ac |
255 | |
4a056d20 |
256 | const Standard_Integer aSegmentIdx = mySegmentIndexes->Value (theElemIdx); |
3bf9a45f |
257 | return theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 0)) |
258 | && theMgr.Overlaps (myPolyg.Pnt3d (aSegmentIdx + 1)); |
2157d6ac |
259 | } |
260 | |
f751596e |
261 | //================================================== |
262 | // Function: distanceToCOG |
263 | // Purpose : Calculates distance from the 3d |
264 | // projection of used-picked screen point |
265 | // to center of the geometry |
266 | //================================================== |
267 | Standard_Real Select3D_SensitivePoly::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) |
268 | { |
2157d6ac |
269 | if (!myIsComputed) |
ceae62f0 |
270 | { |
f751596e |
271 | gp_XYZ aCenter (0.0, 0.0, 0.0); |
272 | for (Standard_Integer aIdx = 0; aIdx < myPolyg.Size(); ++aIdx) |
ceae62f0 |
273 | { |
f751596e |
274 | aCenter += myPolyg.Pnt (aIdx); |
ceae62f0 |
275 | } |
f751596e |
276 | myCOG = aCenter / myPolyg.Size(); |
2157d6ac |
277 | myIsComputed = Standard_True; |
ceae62f0 |
278 | } |
f751596e |
279 | |
280 | return theMgr.DistToGeometryCenter (myCOG); |
7fd59977 |
281 | } |
282 | |
283 | //================================================== |
f751596e |
284 | // Function: NbSubElements |
285 | // Purpose : Returns the amount of segments in poly |
7fd59977 |
286 | //================================================== |
fe758dbe |
287 | Standard_Integer Select3D_SensitivePoly::NbSubElements() const |
7fd59977 |
288 | { |
f751596e |
289 | return myPolyg.Size(); |
7fd59977 |
290 | } |
291 | |
f751596e |
292 | //================================================== |
293 | // Function: CenterOfGeometry |
294 | // Purpose : Returns center of the point set. If |
295 | // location transformation is set, it will |
296 | // be applied |
297 | //================================================== |
298 | gp_Pnt Select3D_SensitivePoly::CenterOfGeometry() const |
299 | { |
2157d6ac |
300 | if (!myIsComputed) |
301 | { |
302 | gp_XYZ aCenter (0.0, 0.0, 0.0); |
303 | for (Standard_Integer aIdx = 0; aIdx < myPolyg.Size(); ++aIdx) |
304 | { |
305 | aCenter += myPolyg.Pnt (aIdx); |
306 | } |
307 | myCOG = aCenter / myPolyg.Size(); |
308 | myIsComputed = Standard_True; |
309 | } |
310 | |
f751596e |
311 | return myCOG; |
312 | } |
bc73b006 |
313 | |
314 | // ======================================================================= |
315 | // function : DumpJson |
316 | // purpose : |
317 | // ======================================================================= |
318 | void Select3D_SensitivePoly::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const |
319 | { |
320 | OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream) |
321 | OCCT_DUMP_BASE_CLASS (theOStream, theDepth, Select3D_SensitiveSet) |
322 | |
323 | OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myBndBox) |
324 | OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsComputed) |
325 | } |