Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1996-02-06 |
2 | // Created by: Robert COUBLANC | |
3 | // Copyright (c) 1996-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
d5f74e42 | 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 | |
973c2be1 | 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. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
b311480e | 16 | |
f751596e | 17 | #include <Geom_Circle.hxx> |
7fd59977 | 18 | |
f751596e | 19 | #include <Select3D_Pnt.hxx> |
20 | #include <Select3D_SensitiveTriangle.hxx> | |
7fd59977 | 21 | #include <Precision.hxx> |
7fd59977 | 22 | |
f751596e | 23 | #include <Select3D_SensitiveCircle.hxx> |
7fd59977 | 24 | |
ac04d101 | 25 | |
92efcf78 | 26 | IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveCircle,Select3D_SensitivePoly) |
27 | ||
f751596e | 28 | static Standard_Integer GetCircleNbPoints (const Handle(Geom_Circle)& theCircle, |
29 | const Standard_Integer theNbPnts) | |
ceae62f0 A |
30 | { |
31 | // Check if number of points is invalid. | |
f751596e | 32 | // In this case myPolyg raises Standard_ConstructionError |
ceae62f0 | 33 | // exception (look constructor bellow). |
f751596e | 34 | if (theNbPnts <= 0) |
ceae62f0 A |
35 | return 0; |
36 | ||
f751596e | 37 | if (theCircle->Radius() > Precision::Confusion()) |
38 | return 2 * theNbPnts + 1; | |
39 | ||
ceae62f0 | 40 | // The radius is too small and circle degenerates into point |
7fd59977 | 41 | return 1; |
42 | } | |
ac04d101 | 43 | |
f751596e | 44 | static Standard_Integer GetArcNbPoints (const Handle(Geom_Circle)& theCircle, |
45 | const Standard_Integer theNbPnts) | |
ceae62f0 A |
46 | { |
47 | // There is no need to check number of points here. | |
48 | // In case of invalid number of points this method returns | |
49 | // -1 or smaller value. | |
f751596e | 50 | if (theCircle->Radius() > Precision::Confusion()) |
51 | return 2 * theNbPnts - 1; | |
ceae62f0 A |
52 | |
53 | // The radius is too small and circle degenerates into point | |
7fd59977 | 54 | return 1; |
55 | } | |
ac04d101 SA |
56 | |
57 | //======================================================================= | |
58 | //function : Select3D_SensitiveCircle (constructor) | |
59 | //purpose : Definition of a sensitive circle | |
60 | //======================================================================= | |
f751596e | 61 | Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& theOwnerId, |
62 | const Handle(Geom_Circle)& theCircle, | |
63 | const Standard_Boolean theIsFilled, | |
64 | const Standard_Integer theNbPnts) | |
65 | : Select3D_SensitivePoly (theOwnerId, !theIsFilled, GetCircleNbPoints (theCircle, theNbPnts)), | |
66 | myCircle (theCircle), | |
67 | myStart (0), | |
68 | myEnd (0) | |
7fd59977 | 69 | { |
f751596e | 70 | mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY; |
71 | if (myPolyg.Size() != 1) | |
ac04d101 | 72 | { |
f751596e | 73 | gp_Pnt aP1, aP2; |
74 | gp_Vec aV1; | |
75 | Standard_Real anUStart = theCircle->FirstParameter(); | |
76 | Standard_Real anUEnd = theCircle->LastParameter(); | |
77 | Standard_Real aStep = (anUEnd - anUStart) / theNbPnts; | |
78 | Standard_Real aRadius = theCircle->Radius(); | |
79 | Standard_Integer aPntIdx = 1; | |
80 | Standard_Real aCurU = anUStart; | |
81 | for (Standard_Integer anIndex = 1; anIndex <= theNbPnts; anIndex++) | |
7fd59977 | 82 | { |
f751596e | 83 | theCircle->D1 (aCurU, aP1, aV1); |
84 | ||
85 | aV1.Normalize(); | |
86 | myPolyg.SetPnt (aPntIdx - 1, aP1); | |
87 | aPntIdx++; | |
88 | aP2 = gp_Pnt (aP1.X() + aV1.X() * tan (aStep / 2.0) * aRadius, | |
89 | aP1.Y() + aV1.Y() * tan (aStep / 2.0) * aRadius, | |
90 | aP1.Z() + aV1.Z() * tan (aStep / 2.0) * aRadius); | |
91 | myPolyg.SetPnt (aPntIdx - 1, aP2); | |
92 | aPntIdx++; | |
93 | aCurU += aStep; | |
7fd59977 | 94 | } |
ceae62f0 | 95 | |
f751596e | 96 | // Copy the first point to the last point of myPolyg |
97 | myPolyg.SetPnt (theNbPnts * 2, myPolyg.Pnt (0)); | |
ceae62f0 | 98 | // Get myCenter3D |
f751596e | 99 | myCenter3D = theCircle->Location(); |
7fd59977 | 100 | } |
101 | // Radius = 0.0 | |
102 | else | |
329843e2 | 103 | { |
f751596e | 104 | myPolyg.SetPnt (0, theCircle->Location()); |
329843e2 | 105 | // Get myCenter3D |
f751596e | 106 | myCenter3D = myPolyg.Pnt (0); |
107 | } | |
108 | ||
109 | if (mySensType == Select3D_TOS_BOUNDARY) | |
110 | { | |
3bf9a45f | 111 | SetSensitivityFactor (6); |
329843e2 | 112 | } |
7fd59977 | 113 | } |
114 | ||
115 | //======================================================================= | |
ac04d101 | 116 | //function : Select3D_SensitiveCircle (constructor) |
81bba717 | 117 | //purpose : Definition of a sensitive arc |
7fd59977 | 118 | //======================================================================= |
f751596e | 119 | Select3D_SensitiveCircle::Select3D_SensitiveCircle (const Handle(SelectBasics_EntityOwner)& theOwnerId, |
120 | const Handle(Geom_Circle)& theCircle, | |
121 | const Standard_Real theU1, | |
122 | const Standard_Real theU2, | |
123 | const Standard_Boolean theIsFilled, | |
124 | const Standard_Integer theNbPnts) | |
125 | : Select3D_SensitivePoly (theOwnerId, !theIsFilled, GetArcNbPoints (theCircle, theNbPnts)), | |
126 | myCircle (theCircle), | |
127 | myStart (Min (theU1, theU2)), | |
128 | myEnd (Max (theU1, theU2)) | |
7fd59977 | 129 | { |
f751596e | 130 | mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY; |
aec37c15 | 131 | |
f751596e | 132 | if (myPolyg.Size() != 1) |
133 | { | |
134 | gp_Pnt aP1, aP2; | |
135 | gp_Vec aV1; | |
aec37c15 | 136 | |
f751596e | 137 | Standard_Real aStep = (myEnd - myStart) / (theNbPnts - 1); |
138 | Standard_Real aRadius = theCircle->Radius(); | |
139 | Standard_Integer aPntIdx = 1; | |
140 | Standard_Real aCurU = myStart; | |
aec37c15 | 141 | |
f751596e | 142 | for (Standard_Integer anIndex = 1; anIndex <= theNbPnts - 1; anIndex++) |
7fd59977 | 143 | { |
f751596e | 144 | theCircle->D1 (aCurU, aP1, aV1); |
145 | aV1.Normalize(); | |
146 | myPolyg.SetPnt (aPntIdx - 1, aP1); | |
147 | aPntIdx++; | |
148 | aP2 = gp_Pnt (aP1.X() + aV1.X() * tan (aStep /2.0) * aRadius, | |
149 | aP1.Y() + aV1.Y() * tan (aStep /2.0) * aRadius, | |
150 | aP1.Z() + aV1.Z() * tan (aStep /2.0) * aRadius); | |
151 | myPolyg.SetPnt (aPntIdx - 1, aP2); | |
152 | aPntIdx++; | |
153 | aCurU += aStep; | |
7fd59977 | 154 | } |
f751596e | 155 | theCircle->D0 (myEnd, aP1); |
156 | myPolyg.SetPnt (theNbPnts * 2 - 2, aP1); | |
aec37c15 | 157 | // Get myCenter3D |
f751596e | 158 | myCenter3D = theCircle->Location(); |
7fd59977 | 159 | } |
160 | else | |
329843e2 | 161 | { |
f751596e | 162 | myPolyg.SetPnt (0, theCircle->Location()); |
329843e2 | 163 | // Get myCenter3D |
f751596e | 164 | myCenter3D = myPolyg.Pnt (0); |
329843e2 | 165 | } |
7fd59977 | 166 | |
f751596e | 167 | if (mySensType == Select3D_TOS_BOUNDARY) |
168 | { | |
3bf9a45f | 169 | SetSensitivityFactor (6); |
f751596e | 170 | } |
7fd59977 | 171 | } |
329843e2 | 172 | |
ac04d101 SA |
173 | //======================================================================= |
174 | //function : Select3D_SensitiveCircle | |
aec37c15 | 175 | //purpose : |
ac04d101 | 176 | //======================================================================= |
f751596e | 177 | Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& theOwnerId, |
178 | const Handle(TColgp_HArray1OfPnt)& thePnts3d, | |
179 | const Standard_Boolean theIsFilled) | |
3bf9a45f | 180 | : Select3D_SensitivePoly (theOwnerId, thePnts3d, static_cast<Standard_Boolean> (!theIsFilled)), |
f751596e | 181 | myStart (0), |
182 | myEnd (0) | |
ceae62f0 | 183 | { |
f751596e | 184 | mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY; |
185 | ||
186 | if (myPolyg.Size() != 1) | |
187 | computeCenter3D(); | |
ceae62f0 | 188 | else |
f751596e | 189 | myCenter3D = myPolyg.Pnt (0); |
190 | ||
191 | if (mySensType == Select3D_TOS_BOUNDARY) | |
192 | { | |
3bf9a45f | 193 | SetSensitivityFactor (6); |
f751596e | 194 | } |
7fd59977 | 195 | } |
196 | ||
ac04d101 | 197 | //======================================================================= |
f751596e | 198 | //function : Select3D_SensitiveCircle |
aec37c15 | 199 | //purpose : |
ac04d101 SA |
200 | //======================================================================= |
201 | ||
f751596e | 202 | Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& theOwnerId, |
203 | const TColgp_Array1OfPnt& thePnts3d, | |
204 | const Standard_Boolean theIsFilled) | |
205 | : Select3D_SensitivePoly (theOwnerId, thePnts3d, !theIsFilled), | |
206 | myStart (0), | |
207 | myEnd (0) | |
7fd59977 | 208 | { |
f751596e | 209 | mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY; |
4269bd1b | 210 | |
f751596e | 211 | if (myPolyg.Size() != 1) |
212 | computeCenter3D(); | |
213 | else | |
214 | myCenter3D = myPolyg.Pnt (0); | |
4269bd1b | 215 | |
f751596e | 216 | if (mySensType == Select3D_TOS_BOUNDARY) |
4269bd1b | 217 | { |
3bf9a45f | 218 | SetSensitivityFactor (6); |
4269bd1b | 219 | } |
7fd59977 | 220 | } |
329843e2 | 221 | |
ac04d101 | 222 | //======================================================================= |
f751596e | 223 | // function : BVH |
224 | // purpose : Builds BVH tree for a circle's edge segments if needed | |
ac04d101 | 225 | //======================================================================= |
f751596e | 226 | void Select3D_SensitiveCircle::BVH() |
7fd59977 | 227 | { |
f751596e | 228 | if (mySensType == Select3D_TOS_BOUNDARY) |
ceae62f0 | 229 | { |
f751596e | 230 | Select3D_SensitivePoly::BVH(); |
ceae62f0 | 231 | } |
7fd59977 | 232 | } |
233 | ||
7fd59977 | 234 | //======================================================================= |
f751596e | 235 | // function : Matches |
236 | // purpose : Checks whether the circle overlaps current selecting volume | |
7fd59977 | 237 | //======================================================================= |
f751596e | 238 | Standard_Boolean Select3D_SensitiveCircle::Matches (SelectBasics_SelectingVolumeManager& theMgr, |
239 | SelectBasics_PickResult& thePickResult) | |
ceae62f0 | 240 | { |
f751596e | 241 | Standard_Real aDepth = RealLast(); |
242 | Standard_Real aDistToCOG = RealLast(); | |
7fd59977 | 243 | |
f751596e | 244 | if (mySensType == Select3D_TOS_BOUNDARY) |
ac04d101 | 245 | { |
2157d6ac | 246 | if (!Select3D_SensitivePoly::Matches (theMgr, thePickResult)) |
247 | { | |
248 | thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG); | |
249 | return Standard_False; | |
250 | } | |
f751596e | 251 | } |
252 | else if (mySensType == Select3D_TOS_INTERIOR) | |
253 | { | |
254 | Handle(TColgp_HArray1OfPnt) anArrayOfPnt; | |
255 | Points3D (anArrayOfPnt); | |
2157d6ac | 256 | if (!theMgr.IsOverlapAllowed()) |
257 | { | |
258 | thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG); | |
14cda02f | 259 | for (Standard_Integer aPntIdx = anArrayOfPnt->Lower(); aPntIdx <= anArrayOfPnt->Upper(); ++aPntIdx) |
2157d6ac | 260 | { |
3bf9a45f | 261 | if (!theMgr.Overlaps (anArrayOfPnt->Value (aPntIdx))) |
14cda02f | 262 | return Standard_False; |
2157d6ac | 263 | } |
264 | return Standard_True; | |
265 | } | |
7fd59977 | 266 | |
2157d6ac | 267 | if (!theMgr.Overlaps (anArrayOfPnt, Select3D_TOS_INTERIOR, aDepth)) |
268 | { | |
269 | thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG); | |
270 | return Standard_False; | |
271 | } | |
f751596e | 272 | } |
7fd59977 | 273 | |
274 | ||
2157d6ac | 275 | aDistToCOG = theMgr.DistToGeometryCenter (myCenter3D); |
276 | thePickResult = SelectBasics_PickResult (aDepth, aDistToCOG); | |
277 | return Standard_True; | |
7fd59977 | 278 | } |
279 | ||
f751596e | 280 | void Select3D_SensitiveCircle::ArrayBounds (Standard_Integer & theLow, |
281 | Standard_Integer & theUp) const | |
7fd59977 | 282 | { |
f751596e | 283 | theLow = 0; |
284 | theUp = myPolyg.Size() - 1; | |
7fd59977 | 285 | } |
ac04d101 SA |
286 | |
287 | //======================================================================= | |
f751596e | 288 | //function : GetPoint3d |
aec37c15 | 289 | //purpose : |
ac04d101 | 290 | //======================================================================= |
f751596e | 291 | gp_Pnt Select3D_SensitiveCircle::GetPoint3d (const Standard_Integer thePntIdx) const |
7fd59977 | 292 | { |
f751596e | 293 | if (thePntIdx >= 0 && thePntIdx < myPolyg.Size()) |
294 | return myPolyg.Pnt (thePntIdx); | |
4269bd1b | 295 | |
f751596e | 296 | return gp_Pnt(); |
7fd59977 | 297 | } |
329843e2 | 298 | |
ac04d101 SA |
299 | //======================================================================= |
300 | //function : GetConnected | |
aec37c15 | 301 | //purpose : |
ceae62f0 | 302 | //======================================================================= |
ac04d101 | 303 | |
f751596e | 304 | Handle(Select3D_SensitiveEntity) Select3D_SensitiveCircle::GetConnected() |
ac04d101 | 305 | { |
f751596e | 306 | Standard_Boolean isFilled = mySensType == Select3D_TOS_INTERIOR; |
aec37c15 | 307 | // Create a copy of this |
ac04d101 SA |
308 | Handle(Select3D_SensitiveEntity) aNewEntity; |
309 | // this was constructed using Handle(Geom_Circle) | |
310 | if(!myCircle.IsNull()) | |
311 | { | |
f751596e | 312 | if ((myEnd - myStart) > Precision::Confusion()) |
ac04d101 SA |
313 | { |
314 | // Arc | |
f751596e | 315 | aNewEntity = new Select3D_SensitiveCircle (myOwnerId, myCircle, myStart, myEnd, isFilled); |
ac04d101 SA |
316 | } |
317 | else | |
318 | { | |
319 | // Circle | |
f751596e | 320 | aNewEntity = new Select3D_SensitiveCircle (myOwnerId, myCircle, isFilled); |
ac04d101 SA |
321 | } |
322 | } | |
323 | // this was constructed using TColgp_Array1OfPnt | |
aec37c15 | 324 | else |
ac04d101 | 325 | { |
f751596e | 326 | Standard_Integer aSize = myPolyg.Size(); |
327 | TColgp_Array1OfPnt aPolyg (1, aSize); | |
ceae62f0 | 328 | for(Standard_Integer anIndex = 1; anIndex <= aSize; ++anIndex) |
ac04d101 | 329 | { |
f751596e | 330 | aPolyg.SetValue(anIndex, myPolyg.Pnt (anIndex-1)); |
ac04d101 | 331 | } |
f751596e | 332 | aNewEntity = new Select3D_SensitiveCircle (myOwnerId, aPolyg, isFilled); |
ac04d101 SA |
333 | } |
334 | ||
ac04d101 SA |
335 | return aNewEntity; |
336 | } | |
337 | ||
338 | //======================================================================= | |
f751596e | 339 | //function : computeCenter3D |
aec37c15 | 340 | //purpose : |
ac04d101 | 341 | //======================================================================= |
f751596e | 342 | void Select3D_SensitiveCircle::computeCenter3D() |
329843e2 | 343 | { |
ceae62f0 | 344 | gp_XYZ aCenter; |
f751596e | 345 | Standard_Integer aNbPnts = myPolyg.Size(); |
346 | if (aNbPnts != 1) | |
329843e2 A |
347 | { |
348 | // The mass of points system | |
f751596e | 349 | Standard_Integer aMass = aNbPnts - 1; |
329843e2 | 350 | // Find the circle barycenter |
f751596e | 351 | for (Standard_Integer anIndex = 0; anIndex < aNbPnts - 1; ++anIndex) |
329843e2 | 352 | { |
f751596e | 353 | aCenter += myPolyg.Pnt(anIndex); |
329843e2 A |
354 | } |
355 | myCenter3D = aCenter / aMass; | |
356 | } | |
ac04d101 SA |
357 | else |
358 | { | |
f751596e | 359 | myCenter3D = myPolyg.Pnt(0); |
329843e2 A |
360 | } |
361 | } | |
f751596e | 362 | |
363 | //======================================================================= | |
364 | // function : CenterOfGeometry | |
365 | // purpose : Returns center of the circle. If location transformation | |
366 | // is set, it will be applied | |
367 | //======================================================================= | |
368 | gp_Pnt Select3D_SensitiveCircle::CenterOfGeometry() const | |
369 | { | |
370 | return myCenter3D; | |
371 | } |