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 <Select3D_SensitiveCircle.hxx> |
7fd59977 | 18 | |
7f24b768 | 19 | #include <ElCLib.hxx> |
0609d8ee | 20 | #include <Precision.hxx> |
21 | #include <Select3D_SensitiveTriangle.hxx> | |
ac04d101 | 22 | |
92efcf78 | 23 | IMPLEMENT_STANDARD_RTTIEXT(Select3D_SensitiveCircle,Select3D_SensitivePoly) |
24 | ||
0609d8ee | 25 | namespace |
ceae62f0 | 26 | { |
7f24b768 | 27 | static Standard_Integer GetCircleNbPoints (const gp_Circ& theCircle, |
0609d8ee | 28 | const Standard_Integer theNbPnts) |
29 | { | |
30 | // Check if number of points is invalid. | |
31 | // In this case myPolyg raises Standard_ConstructionError | |
32 | // exception (look constructor bellow). | |
33 | if (theNbPnts <= 0) | |
34 | return 0; | |
ceae62f0 | 35 | |
7f24b768 | 36 | if (theCircle.Radius() > Precision::Confusion()) |
0609d8ee | 37 | return 2 * theNbPnts + 1; |
f751596e | 38 | |
0609d8ee | 39 | // The radius is too small and circle degenerates into point |
40 | return 1; | |
41 | } | |
ac04d101 | 42 | |
7f24b768 | 43 | //! Definition of circle polyline |
44 | static void initCircle (Select3D_PointData& thePolygon, | |
45 | const gp_Circ& theCircle, | |
46 | const Standard_Real theU1, | |
47 | const Standard_Real theU2, | |
48 | const Standard_Integer theNbPnts) | |
0609d8ee | 49 | { |
7f24b768 | 50 | const Standard_Real aStep = (theU2 - theU1) / theNbPnts; |
51 | const Standard_Real aRadius = theCircle.Radius(); | |
52 | Standard_Integer aPntIdx = 0; | |
53 | Standard_Real aCurU = theU1; | |
54 | gp_Pnt aP1; | |
55 | gp_Vec aV1; | |
56 | for (Standard_Integer anIndex = 1; anIndex <= theNbPnts; ++anIndex, aCurU += aStep) | |
57 | { | |
58 | ElCLib::CircleD1 (aCurU, theCircle.Position(), theCircle.Radius(), aP1, aV1); | |
59 | thePolygon.SetPnt (aPntIdx++, aP1); | |
ceae62f0 | 60 | |
7f24b768 | 61 | aV1.Normalize(); |
62 | const gp_Pnt aP2 = aP1.XYZ() + aV1.XYZ() * Tan (aStep * 0.5) * aRadius; | |
63 | thePolygon.SetPnt (aPntIdx++, aP2); | |
64 | } | |
65 | aP1 = ElCLib::CircleValue (theU2, theCircle.Position(), theCircle.Radius()); | |
66 | thePolygon.SetPnt (theNbPnts * 2, aP1); | |
0609d8ee | 67 | } |
7fd59977 | 68 | } |
ac04d101 SA |
69 | |
70 | //======================================================================= | |
71 | //function : Select3D_SensitiveCircle (constructor) | |
72 | //purpose : Definition of a sensitive circle | |
73 | //======================================================================= | |
0ef04197 | 74 | Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectMgr_EntityOwner)& theOwnerId, |
7f24b768 | 75 | const gp_Circ& theCircle, |
f751596e | 76 | const Standard_Boolean theIsFilled, |
77 | const Standard_Integer theNbPnts) | |
78 | : Select3D_SensitivePoly (theOwnerId, !theIsFilled, GetCircleNbPoints (theCircle, theNbPnts)), | |
79 | myCircle (theCircle), | |
7f24b768 | 80 | myStart (0.0), |
81 | myEnd (2.0 * M_PI) | |
7fd59977 | 82 | { |
f751596e | 83 | mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY; |
7f24b768 | 84 | myCenter3D = theCircle.Position().Location(); |
f751596e | 85 | if (myPolyg.Size() != 1) |
ac04d101 | 86 | { |
7f24b768 | 87 | initCircle (myPolyg, theCircle, myStart, myEnd, theNbPnts); |
7fd59977 | 88 | } |
89 | // Radius = 0.0 | |
90 | else | |
329843e2 | 91 | { |
7f24b768 | 92 | myPolyg.SetPnt (0, theCircle.Position().Location()); |
f751596e | 93 | } |
94 | ||
95 | if (mySensType == Select3D_TOS_BOUNDARY) | |
96 | { | |
3bf9a45f | 97 | SetSensitivityFactor (6); |
329843e2 | 98 | } |
7fd59977 | 99 | } |
100 | ||
101 | //======================================================================= | |
ac04d101 | 102 | //function : Select3D_SensitiveCircle (constructor) |
81bba717 | 103 | //purpose : Definition of a sensitive arc |
7fd59977 | 104 | //======================================================================= |
0ef04197 | 105 | Select3D_SensitiveCircle::Select3D_SensitiveCircle (const Handle(SelectMgr_EntityOwner)& theOwnerId, |
7f24b768 | 106 | const gp_Circ& theCircle, |
f751596e | 107 | const Standard_Real theU1, |
108 | const Standard_Real theU2, | |
109 | const Standard_Boolean theIsFilled, | |
110 | const Standard_Integer theNbPnts) | |
7f24b768 | 111 | : Select3D_SensitivePoly (theOwnerId, !theIsFilled, GetCircleNbPoints (theCircle, theNbPnts)), |
f751596e | 112 | myCircle (theCircle), |
113 | myStart (Min (theU1, theU2)), | |
114 | myEnd (Max (theU1, theU2)) | |
7fd59977 | 115 | { |
f751596e | 116 | mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY; |
7f24b768 | 117 | myCenter3D = theCircle.Position().Location(); |
f751596e | 118 | if (myPolyg.Size() != 1) |
119 | { | |
7f24b768 | 120 | initCircle (myPolyg, theCircle, myStart, myEnd, theNbPnts); |
7fd59977 | 121 | } |
122 | else | |
329843e2 | 123 | { |
7f24b768 | 124 | myPolyg.SetPnt (0, theCircle.Position().Location()); |
329843e2 | 125 | } |
7fd59977 | 126 | |
f751596e | 127 | if (mySensType == Select3D_TOS_BOUNDARY) |
128 | { | |
3bf9a45f | 129 | SetSensitivityFactor (6); |
f751596e | 130 | } |
7fd59977 | 131 | } |
329843e2 | 132 | |
ac04d101 SA |
133 | //======================================================================= |
134 | //function : Select3D_SensitiveCircle | |
aec37c15 | 135 | //purpose : |
ac04d101 | 136 | //======================================================================= |
0ef04197 | 137 | Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectMgr_EntityOwner)& theOwnerId, |
f751596e | 138 | const Handle(TColgp_HArray1OfPnt)& thePnts3d, |
139 | const Standard_Boolean theIsFilled) | |
3bf9a45f | 140 | : Select3D_SensitivePoly (theOwnerId, thePnts3d, static_cast<Standard_Boolean> (!theIsFilled)), |
f751596e | 141 | myStart (0), |
142 | myEnd (0) | |
ceae62f0 | 143 | { |
f751596e | 144 | mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY; |
145 | ||
146 | if (myPolyg.Size() != 1) | |
147 | computeCenter3D(); | |
ceae62f0 | 148 | else |
f751596e | 149 | myCenter3D = myPolyg.Pnt (0); |
150 | ||
151 | if (mySensType == Select3D_TOS_BOUNDARY) | |
152 | { | |
3bf9a45f | 153 | SetSensitivityFactor (6); |
f751596e | 154 | } |
7fd59977 | 155 | } |
156 | ||
ac04d101 | 157 | //======================================================================= |
f751596e | 158 | //function : Select3D_SensitiveCircle |
aec37c15 | 159 | //purpose : |
ac04d101 SA |
160 | //======================================================================= |
161 | ||
0ef04197 | 162 | Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectMgr_EntityOwner)& theOwnerId, |
f751596e | 163 | const TColgp_Array1OfPnt& thePnts3d, |
164 | const Standard_Boolean theIsFilled) | |
165 | : Select3D_SensitivePoly (theOwnerId, thePnts3d, !theIsFilled), | |
166 | myStart (0), | |
167 | myEnd (0) | |
7fd59977 | 168 | { |
f751596e | 169 | mySensType = theIsFilled ? Select3D_TOS_INTERIOR : Select3D_TOS_BOUNDARY; |
4269bd1b | 170 | |
f751596e | 171 | if (myPolyg.Size() != 1) |
172 | computeCenter3D(); | |
173 | else | |
174 | myCenter3D = myPolyg.Pnt (0); | |
4269bd1b | 175 | |
f751596e | 176 | if (mySensType == Select3D_TOS_BOUNDARY) |
4269bd1b | 177 | { |
3bf9a45f | 178 | SetSensitivityFactor (6); |
4269bd1b | 179 | } |
7fd59977 | 180 | } |
329843e2 | 181 | |
ac04d101 | 182 | //======================================================================= |
f751596e | 183 | // function : BVH |
184 | // purpose : Builds BVH tree for a circle's edge segments if needed | |
ac04d101 | 185 | //======================================================================= |
f751596e | 186 | void Select3D_SensitiveCircle::BVH() |
7fd59977 | 187 | { |
f751596e | 188 | if (mySensType == Select3D_TOS_BOUNDARY) |
ceae62f0 | 189 | { |
f751596e | 190 | Select3D_SensitivePoly::BVH(); |
ceae62f0 | 191 | } |
7fd59977 | 192 | } |
193 | ||
7fd59977 | 194 | //======================================================================= |
f751596e | 195 | // function : Matches |
196 | // purpose : Checks whether the circle overlaps current selecting volume | |
7fd59977 | 197 | //======================================================================= |
f751596e | 198 | Standard_Boolean Select3D_SensitiveCircle::Matches (SelectBasics_SelectingVolumeManager& theMgr, |
199 | SelectBasics_PickResult& thePickResult) | |
ceae62f0 | 200 | { |
f751596e | 201 | if (mySensType == Select3D_TOS_BOUNDARY) |
ac04d101 | 202 | { |
2157d6ac | 203 | if (!Select3D_SensitivePoly::Matches (theMgr, thePickResult)) |
204 | { | |
2157d6ac | 205 | return Standard_False; |
206 | } | |
f751596e | 207 | } |
208 | else if (mySensType == Select3D_TOS_INTERIOR) | |
209 | { | |
210 | Handle(TColgp_HArray1OfPnt) anArrayOfPnt; | |
211 | Points3D (anArrayOfPnt); | |
2157d6ac | 212 | if (!theMgr.IsOverlapAllowed()) |
213 | { | |
a24a7821 | 214 | if (theMgr.GetActiveSelectionType() == SelectBasics_SelectingVolumeManager::Polyline) |
215 | { | |
216 | SelectBasics_PickResult aDummy; | |
217 | return theMgr.Overlaps (anArrayOfPnt, mySensType, aDummy); | |
218 | } | |
14cda02f | 219 | for (Standard_Integer aPntIdx = anArrayOfPnt->Lower(); aPntIdx <= anArrayOfPnt->Upper(); ++aPntIdx) |
2157d6ac | 220 | { |
17017555 | 221 | if (!theMgr.Overlaps (anArrayOfPnt->Value(aPntIdx))) |
222 | { | |
14cda02f | 223 | return Standard_False; |
17017555 | 224 | } |
2157d6ac | 225 | } |
226 | return Standard_True; | |
227 | } | |
7fd59977 | 228 | |
17017555 | 229 | if (!theMgr.Overlaps (anArrayOfPnt, Select3D_TOS_INTERIOR, thePickResult)) |
2157d6ac | 230 | { |
2157d6ac | 231 | return Standard_False; |
232 | } | |
17017555 | 233 | thePickResult.SetDistToGeomCenter(distanceToCOG(theMgr)); |
f751596e | 234 | } |
7fd59977 | 235 | |
2157d6ac | 236 | return Standard_True; |
7fd59977 | 237 | } |
238 | ||
ac04d101 SA |
239 | //======================================================================= |
240 | //function : GetConnected | |
aec37c15 | 241 | //purpose : |
ceae62f0 | 242 | //======================================================================= |
ac04d101 | 243 | |
f751596e | 244 | Handle(Select3D_SensitiveEntity) Select3D_SensitiveCircle::GetConnected() |
ac04d101 | 245 | { |
f751596e | 246 | Standard_Boolean isFilled = mySensType == Select3D_TOS_INTERIOR; |
aec37c15 | 247 | // Create a copy of this |
ac04d101 SA |
248 | Handle(Select3D_SensitiveEntity) aNewEntity; |
249 | // this was constructed using Handle(Geom_Circle) | |
7f24b768 | 250 | if (!Precision::IsInfinite (myCircle.Radius())) |
ac04d101 | 251 | { |
f751596e | 252 | if ((myEnd - myStart) > Precision::Confusion()) |
ac04d101 SA |
253 | { |
254 | // Arc | |
f751596e | 255 | aNewEntity = new Select3D_SensitiveCircle (myOwnerId, myCircle, myStart, myEnd, isFilled); |
ac04d101 SA |
256 | } |
257 | else | |
258 | { | |
259 | // Circle | |
f751596e | 260 | aNewEntity = new Select3D_SensitiveCircle (myOwnerId, myCircle, isFilled); |
ac04d101 SA |
261 | } |
262 | } | |
263 | // this was constructed using TColgp_Array1OfPnt | |
aec37c15 | 264 | else |
ac04d101 | 265 | { |
f751596e | 266 | Standard_Integer aSize = myPolyg.Size(); |
267 | TColgp_Array1OfPnt aPolyg (1, aSize); | |
ceae62f0 | 268 | for(Standard_Integer anIndex = 1; anIndex <= aSize; ++anIndex) |
ac04d101 | 269 | { |
f751596e | 270 | aPolyg.SetValue(anIndex, myPolyg.Pnt (anIndex-1)); |
ac04d101 | 271 | } |
f751596e | 272 | aNewEntity = new Select3D_SensitiveCircle (myOwnerId, aPolyg, isFilled); |
ac04d101 SA |
273 | } |
274 | ||
ac04d101 SA |
275 | return aNewEntity; |
276 | } | |
277 | ||
278 | //======================================================================= | |
f751596e | 279 | //function : computeCenter3D |
aec37c15 | 280 | //purpose : |
ac04d101 | 281 | //======================================================================= |
f751596e | 282 | void Select3D_SensitiveCircle::computeCenter3D() |
329843e2 | 283 | { |
ceae62f0 | 284 | gp_XYZ aCenter; |
f751596e | 285 | Standard_Integer aNbPnts = myPolyg.Size(); |
286 | if (aNbPnts != 1) | |
329843e2 A |
287 | { |
288 | // The mass of points system | |
f751596e | 289 | Standard_Integer aMass = aNbPnts - 1; |
329843e2 | 290 | // Find the circle barycenter |
f751596e | 291 | for (Standard_Integer anIndex = 0; anIndex < aNbPnts - 1; ++anIndex) |
329843e2 | 292 | { |
f751596e | 293 | aCenter += myPolyg.Pnt(anIndex); |
329843e2 A |
294 | } |
295 | myCenter3D = aCenter / aMass; | |
296 | } | |
ac04d101 SA |
297 | else |
298 | { | |
f751596e | 299 | myCenter3D = myPolyg.Pnt(0); |
329843e2 A |
300 | } |
301 | } | |
f751596e | 302 | |
303 | //======================================================================= | |
304 | // function : CenterOfGeometry | |
305 | // purpose : Returns center of the circle. If location transformation | |
306 | // is set, it will be applied | |
307 | //======================================================================= | |
308 | gp_Pnt Select3D_SensitiveCircle::CenterOfGeometry() const | |
309 | { | |
310 | return myCenter3D; | |
311 | } | |
7d46a9ed | 312 | |
313 | //======================================================================= | |
314 | // function : distanceToCOG | |
315 | // purpose : | |
316 | //======================================================================= | |
317 | Standard_Real Select3D_SensitiveCircle::distanceToCOG (SelectBasics_SelectingVolumeManager& theMgr) | |
318 | { | |
319 | return theMgr.DistToGeometryCenter (myCenter3D); | |
320 | } |