| 1 | // Created on: 1991-07-05 |
| 2 | // Created by: JCV |
| 3 | // Copyright (c) 1991-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 | // 03-02-97 : pmn ->LocateU sur Periodic (PRO6963), |
| 18 | // bon appel a LocateParameter (PRO6973) et mise en conformite avec |
| 19 | // le cdl de LocateU, lorsque U est un noeud (PRO6988) |
| 20 | |
| 21 | #define No_Standard_OutOfRange |
| 22 | #define No_Standard_DimensionError |
| 23 | |
| 24 | #include <Geom_BSplineCurve.jxx> |
| 25 | #include <BSplCLib.hxx> |
| 26 | #include <gp.hxx> |
| 27 | |
| 28 | #include <Geom_UndefinedDerivative.hxx> |
| 29 | #include <Standard_DimensionError.hxx> |
| 30 | #include <Standard_OutOfRange.hxx> |
| 31 | #include <Standard_DomainError.hxx> |
| 32 | #include <Standard_RangeError.hxx> |
| 33 | #include <Standard_Mutex.hxx> |
| 34 | #include <Precision.hxx> |
| 35 | |
| 36 | #define POLES (poles->Array1()) |
| 37 | #define KNOTS (knots->Array1()) |
| 38 | #define FKNOTS (flatknots->Array1()) |
| 39 | #define FMULTS (BSplCLib::NoMults()) |
| 40 | |
| 41 | //======================================================================= |
| 42 | //function : IsCN |
| 43 | //purpose : |
| 44 | //======================================================================= |
| 45 | |
| 46 | Standard_Boolean Geom_BSplineCurve::IsCN ( const Standard_Integer N) const |
| 47 | { |
| 48 | Standard_RangeError_Raise_if |
| 49 | (N < 0, "Geom_BSplineCurve::IsCN"); |
| 50 | |
| 51 | switch (smooth) { |
| 52 | case GeomAbs_CN : return Standard_True; |
| 53 | case GeomAbs_C0 : return N <= 0; |
| 54 | case GeomAbs_G1 : return N <= 0; |
| 55 | case GeomAbs_C1 : return N <= 1; |
| 56 | case GeomAbs_G2 : return N <= 1; |
| 57 | case GeomAbs_C2 : return N <= 2; |
| 58 | case GeomAbs_C3 : |
| 59 | return N <= 3 ? Standard_True : |
| 60 | N <= deg - BSplCLib::MaxKnotMult (mults->Array1(), mults->Lower() + 1, mults->Upper() - 1); |
| 61 | default: |
| 62 | return Standard_False; |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | //======================================================================= |
| 67 | //function : IsClosed |
| 68 | //purpose : |
| 69 | //======================================================================= |
| 70 | |
| 71 | Standard_Boolean Geom_BSplineCurve::IsClosed () const |
| 72 | //-- { return (StartPoint().Distance (EndPoint())) <= gp::Resolution (); } |
| 73 | { return (StartPoint().SquareDistance(EndPoint())) <= 1e-16; } |
| 74 | |
| 75 | //======================================================================= |
| 76 | //function : IsPeriodic |
| 77 | //purpose : |
| 78 | //======================================================================= |
| 79 | |
| 80 | Standard_Boolean Geom_BSplineCurve::IsPeriodic () const |
| 81 | { return periodic; } |
| 82 | |
| 83 | //======================================================================= |
| 84 | //function : Continuity |
| 85 | //purpose : |
| 86 | //======================================================================= |
| 87 | |
| 88 | GeomAbs_Shape Geom_BSplineCurve::Continuity () const |
| 89 | { return smooth; } |
| 90 | |
| 91 | //======================================================================= |
| 92 | //function : Degree |
| 93 | //purpose : |
| 94 | //======================================================================= |
| 95 | |
| 96 | Standard_Integer Geom_BSplineCurve::Degree () const |
| 97 | { return deg; } |
| 98 | |
| 99 | //======================================================================= |
| 100 | //function : D0 |
| 101 | //purpose : |
| 102 | //======================================================================= |
| 103 | |
| 104 | void Geom_BSplineCurve::D0(const Standard_Real U, gp_Pnt& P) const |
| 105 | { |
| 106 | Standard_Real NewU(U); |
| 107 | PeriodicNormalization(NewU); |
| 108 | |
| 109 | Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this; |
| 110 | Standard_Mutex::Sentry aSentry(MyCurve->myMutex); |
| 111 | |
| 112 | if(!IsCacheValid(NewU)) |
| 113 | MyCurve->ValidateCache(NewU); |
| 114 | |
| 115 | if(rational) |
| 116 | { |
| 117 | BSplCLib::CacheD0(NewU, |
| 118 | deg, |
| 119 | parametercache, |
| 120 | spanlenghtcache, |
| 121 | cachepoles->Array1(), |
| 122 | cacheweights->Array1(), |
| 123 | P); |
| 124 | } |
| 125 | else |
| 126 | { |
| 127 | BSplCLib::CacheD0(NewU, |
| 128 | deg, |
| 129 | parametercache, |
| 130 | spanlenghtcache, |
| 131 | cachepoles->Array1(), |
| 132 | *((TColStd_Array1OfReal*) NULL), |
| 133 | P); |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | //======================================================================= |
| 138 | //function : D1 |
| 139 | //purpose : |
| 140 | //======================================================================= |
| 141 | |
| 142 | void Geom_BSplineCurve::D1 (const Standard_Real U, |
| 143 | gp_Pnt& P, |
| 144 | gp_Vec& V1) const |
| 145 | { |
| 146 | Standard_Real NewU(U); |
| 147 | PeriodicNormalization(NewU); |
| 148 | |
| 149 | Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this; |
| 150 | Standard_Mutex::Sentry aSentry(MyCurve->myMutex); |
| 151 | |
| 152 | if(!IsCacheValid(NewU)) |
| 153 | MyCurve->ValidateCache(NewU); |
| 154 | |
| 155 | if(rational) |
| 156 | { |
| 157 | BSplCLib::CacheD1(NewU, |
| 158 | deg, |
| 159 | parametercache, |
| 160 | spanlenghtcache, |
| 161 | cachepoles->Array1(), |
| 162 | cacheweights->Array1(), |
| 163 | P, |
| 164 | V1); |
| 165 | } |
| 166 | else |
| 167 | { |
| 168 | BSplCLib::CacheD1(NewU, |
| 169 | deg, |
| 170 | parametercache, |
| 171 | spanlenghtcache, |
| 172 | cachepoles->Array1(), |
| 173 | *((TColStd_Array1OfReal*) NULL), |
| 174 | P, |
| 175 | V1); |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | //======================================================================= |
| 180 | //function : D2 |
| 181 | //purpose : |
| 182 | //======================================================================= |
| 183 | |
| 184 | void Geom_BSplineCurve::D2(const Standard_Real U, |
| 185 | gp_Pnt& P, |
| 186 | gp_Vec& V1, |
| 187 | gp_Vec& V2) const |
| 188 | { |
| 189 | Standard_Real NewU(U); |
| 190 | PeriodicNormalization(NewU); |
| 191 | |
| 192 | Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this; |
| 193 | Standard_Mutex::Sentry aSentry(MyCurve->myMutex); |
| 194 | |
| 195 | if(!IsCacheValid(NewU)) |
| 196 | MyCurve->ValidateCache(NewU); |
| 197 | |
| 198 | if(rational) |
| 199 | { |
| 200 | BSplCLib::CacheD2(NewU, |
| 201 | deg, |
| 202 | parametercache, |
| 203 | spanlenghtcache, |
| 204 | (cachepoles->Array1()), |
| 205 | cacheweights->Array1(), |
| 206 | P, |
| 207 | V1, |
| 208 | V2); |
| 209 | } |
| 210 | else { |
| 211 | BSplCLib::CacheD2(NewU, |
| 212 | deg, |
| 213 | parametercache, |
| 214 | spanlenghtcache, |
| 215 | (cachepoles->Array1()), |
| 216 | *((TColStd_Array1OfReal*) NULL), |
| 217 | P, |
| 218 | V1, |
| 219 | V2); |
| 220 | } |
| 221 | } |
| 222 | |
| 223 | //======================================================================= |
| 224 | //function : D3 |
| 225 | //purpose : |
| 226 | //======================================================================= |
| 227 | |
| 228 | void Geom_BSplineCurve::D3(const Standard_Real U, |
| 229 | gp_Pnt& P, |
| 230 | gp_Vec& V1, |
| 231 | gp_Vec& V2, |
| 232 | gp_Vec& V3) const |
| 233 | { |
| 234 | |
| 235 | Standard_Real NewU(U); |
| 236 | PeriodicNormalization(NewU); |
| 237 | |
| 238 | Geom_BSplineCurve* MyCurve = (Geom_BSplineCurve *) this; |
| 239 | Standard_Mutex::Sentry aSentry(MyCurve->myMutex); |
| 240 | |
| 241 | if(!IsCacheValid(NewU)) |
| 242 | MyCurve->ValidateCache(NewU); |
| 243 | |
| 244 | if(rational) |
| 245 | { |
| 246 | BSplCLib::CacheD3(NewU, |
| 247 | deg, |
| 248 | parametercache, |
| 249 | spanlenghtcache, |
| 250 | (cachepoles->Array1()), |
| 251 | cacheweights->Array1(), |
| 252 | P, |
| 253 | V1, |
| 254 | V2, |
| 255 | V3) ; |
| 256 | } |
| 257 | else |
| 258 | { |
| 259 | BSplCLib::CacheD3(NewU, |
| 260 | deg, |
| 261 | parametercache, |
| 262 | spanlenghtcache, |
| 263 | cachepoles->Array1(), |
| 264 | *((TColStd_Array1OfReal*) NULL), |
| 265 | P, |
| 266 | V1, |
| 267 | V2, |
| 268 | V3) ; |
| 269 | } |
| 270 | } |
| 271 | |
| 272 | //======================================================================= |
| 273 | //function : DN |
| 274 | //purpose : |
| 275 | //======================================================================= |
| 276 | |
| 277 | gp_Vec Geom_BSplineCurve::DN (const Standard_Real U, |
| 278 | const Standard_Integer N ) const |
| 279 | { |
| 280 | gp_Vec V; |
| 281 | if (rational) { |
| 282 | BSplCLib::DN(U,N,0,deg,periodic,POLES, |
| 283 | weights->Array1(), |
| 284 | FKNOTS,FMULTS,V); |
| 285 | } |
| 286 | else { |
| 287 | BSplCLib::DN(U,N,0,deg,periodic,POLES, |
| 288 | *((TColStd_Array1OfReal*) NULL), |
| 289 | FKNOTS,FMULTS,V); |
| 290 | } |
| 291 | return V; |
| 292 | } |
| 293 | |
| 294 | //======================================================================= |
| 295 | //function : EndPoint |
| 296 | //purpose : |
| 297 | //======================================================================= |
| 298 | |
| 299 | gp_Pnt Geom_BSplineCurve::EndPoint () const |
| 300 | { |
| 301 | if (mults->Value (knots->Upper ()) == deg + 1) |
| 302 | return poles->Value (poles->Upper()); |
| 303 | else |
| 304 | return Value(LastParameter()); |
| 305 | } |
| 306 | |
| 307 | //======================================================================= |
| 308 | //function : FirstUKnotIndex |
| 309 | //purpose : |
| 310 | //======================================================================= |
| 311 | |
| 312 | Standard_Integer Geom_BSplineCurve::FirstUKnotIndex () const |
| 313 | { |
| 314 | if (periodic) return 1; |
| 315 | else return BSplCLib::FirstUKnotIndex (deg, mults->Array1()); |
| 316 | } |
| 317 | |
| 318 | //======================================================================= |
| 319 | //function : FirstParameter |
| 320 | //purpose : |
| 321 | //======================================================================= |
| 322 | |
| 323 | Standard_Real Geom_BSplineCurve::FirstParameter () const |
| 324 | { |
| 325 | return flatknots->Value (deg+1); |
| 326 | } |
| 327 | |
| 328 | //======================================================================= |
| 329 | //function : Knot |
| 330 | //purpose : |
| 331 | //======================================================================= |
| 332 | |
| 333 | Standard_Real Geom_BSplineCurve::Knot (const Standard_Integer Index) const |
| 334 | { |
| 335 | Standard_OutOfRange_Raise_if |
| 336 | (Index < 1 || Index > knots->Length(), "Geom_BSplineCurve::Knot"); |
| 337 | return knots->Value (Index); |
| 338 | } |
| 339 | |
| 340 | //======================================================================= |
| 341 | //function : KnotDistribution |
| 342 | //purpose : |
| 343 | //======================================================================= |
| 344 | |
| 345 | GeomAbs_BSplKnotDistribution Geom_BSplineCurve::KnotDistribution () const |
| 346 | { |
| 347 | return knotSet; |
| 348 | } |
| 349 | |
| 350 | //======================================================================= |
| 351 | //function : Knots |
| 352 | //purpose : |
| 353 | //======================================================================= |
| 354 | |
| 355 | void Geom_BSplineCurve::Knots (TColStd_Array1OfReal& K) const |
| 356 | { |
| 357 | Standard_DimensionError_Raise_if |
| 358 | (K.Length() != knots->Length(), "Geom_BSplineCurve::Knots"); |
| 359 | K = knots->Array1(); |
| 360 | } |
| 361 | |
| 362 | //======================================================================= |
| 363 | //function : KnotSequence |
| 364 | //purpose : |
| 365 | //======================================================================= |
| 366 | |
| 367 | void Geom_BSplineCurve::KnotSequence (TColStd_Array1OfReal& K) const |
| 368 | { |
| 369 | Standard_DimensionError_Raise_if |
| 370 | (K.Length() != flatknots->Length(), "Geom_BSplineCurve::KnotSequence"); |
| 371 | K = flatknots->Array1(); |
| 372 | } |
| 373 | |
| 374 | //======================================================================= |
| 375 | //function : LastUKnotIndex |
| 376 | //purpose : |
| 377 | //======================================================================= |
| 378 | |
| 379 | Standard_Integer Geom_BSplineCurve::LastUKnotIndex() const |
| 380 | { |
| 381 | if (periodic) return knots->Length(); |
| 382 | else return BSplCLib::LastUKnotIndex (deg, mults->Array1()); |
| 383 | } |
| 384 | |
| 385 | //======================================================================= |
| 386 | //function : LastParameter |
| 387 | //purpose : |
| 388 | //======================================================================= |
| 389 | |
| 390 | Standard_Real Geom_BSplineCurve::LastParameter () const |
| 391 | { |
| 392 | return flatknots->Value (flatknots->Upper()-deg); |
| 393 | } |
| 394 | |
| 395 | //======================================================================= |
| 396 | //function : LocalValue |
| 397 | //purpose : |
| 398 | //======================================================================= |
| 399 | |
| 400 | gp_Pnt Geom_BSplineCurve::LocalValue |
| 401 | (const Standard_Real U, |
| 402 | const Standard_Integer FromK1, |
| 403 | const Standard_Integer ToK2) const |
| 404 | { |
| 405 | gp_Pnt P; |
| 406 | LocalD0(U,FromK1,ToK2,P); |
| 407 | return P; |
| 408 | } |
| 409 | |
| 410 | //======================================================================= |
| 411 | //function : LocalD0 |
| 412 | //purpose : |
| 413 | //======================================================================= |
| 414 | |
| 415 | void Geom_BSplineCurve::LocalD0 |
| 416 | (const Standard_Real U, |
| 417 | const Standard_Integer FromK1, |
| 418 | const Standard_Integer ToK2, |
| 419 | gp_Pnt& P) const |
| 420 | { |
| 421 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
| 422 | "Geom_BSplineCurve::LocalValue"); |
| 423 | |
| 424 | Standard_Real u = U; |
| 425 | Standard_Integer index = 0; |
| 426 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic,FromK1,ToK2, index,u); |
| 427 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
| 428 | if (rational) { |
| 429 | BSplCLib::D0(u,index,deg,periodic,POLES, |
| 430 | weights->Array1(), |
| 431 | FKNOTS,FMULTS,P); |
| 432 | } |
| 433 | else { |
| 434 | BSplCLib::D0(u,index,deg,periodic,POLES, |
| 435 | *((TColStd_Array1OfReal*) NULL), |
| 436 | FKNOTS,FMULTS,P); |
| 437 | } |
| 438 | } |
| 439 | |
| 440 | //======================================================================= |
| 441 | //function : LocalD1 |
| 442 | //purpose : |
| 443 | //======================================================================= |
| 444 | |
| 445 | void Geom_BSplineCurve::LocalD1 (const Standard_Real U, |
| 446 | const Standard_Integer FromK1, |
| 447 | const Standard_Integer ToK2, |
| 448 | gp_Pnt& P, |
| 449 | gp_Vec& V1) const |
| 450 | { |
| 451 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
| 452 | "Geom_BSplineCurve::LocalD1"); |
| 453 | |
| 454 | Standard_Real u = U; |
| 455 | Standard_Integer index = 0; |
| 456 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u); |
| 457 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
| 458 | if (rational) { |
| 459 | BSplCLib::D1(u,index,deg,periodic,POLES, |
| 460 | weights->Array1(), |
| 461 | FKNOTS,FMULTS,P,V1); |
| 462 | } |
| 463 | else { |
| 464 | BSplCLib::D1(u,index,deg,periodic,POLES, |
| 465 | *((TColStd_Array1OfReal*) NULL), |
| 466 | FKNOTS,FMULTS,P,V1); |
| 467 | } |
| 468 | } |
| 469 | |
| 470 | //======================================================================= |
| 471 | //function : LocalD2 |
| 472 | //purpose : |
| 473 | //======================================================================= |
| 474 | |
| 475 | void Geom_BSplineCurve::LocalD2 |
| 476 | (const Standard_Real U, |
| 477 | const Standard_Integer FromK1, |
| 478 | const Standard_Integer ToK2, |
| 479 | gp_Pnt& P, |
| 480 | gp_Vec& V1, |
| 481 | gp_Vec& V2) const |
| 482 | { |
| 483 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
| 484 | "Geom_BSplineCurve::LocalD2"); |
| 485 | |
| 486 | Standard_Real u = U; |
| 487 | Standard_Integer index = 0; |
| 488 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u); |
| 489 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
| 490 | if (rational) { |
| 491 | BSplCLib::D2(u,index,deg,periodic,POLES, |
| 492 | weights->Array1(), |
| 493 | FKNOTS,FMULTS,P,V1,V2); |
| 494 | } |
| 495 | else { |
| 496 | BSplCLib::D2(u,index,deg,periodic,POLES, |
| 497 | *((TColStd_Array1OfReal*) NULL), |
| 498 | FKNOTS,FMULTS,P,V1,V2); |
| 499 | } |
| 500 | } |
| 501 | |
| 502 | //======================================================================= |
| 503 | //function : LocalD3 |
| 504 | //purpose : |
| 505 | //======================================================================= |
| 506 | |
| 507 | void Geom_BSplineCurve::LocalD3 |
| 508 | (const Standard_Real U, |
| 509 | const Standard_Integer FromK1, |
| 510 | const Standard_Integer ToK2, |
| 511 | gp_Pnt& P, |
| 512 | gp_Vec& V1, |
| 513 | gp_Vec& V2, |
| 514 | gp_Vec& V3) const |
| 515 | { |
| 516 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
| 517 | "Geom_BSplineCurve::LocalD3"); |
| 518 | |
| 519 | Standard_Real u = U; |
| 520 | Standard_Integer index = 0; |
| 521 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u); |
| 522 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
| 523 | if (rational) { |
| 524 | BSplCLib::D3(u,index,deg,periodic,POLES, |
| 525 | weights->Array1(), |
| 526 | FKNOTS,FMULTS,P,V1,V2,V3); |
| 527 | } |
| 528 | else { |
| 529 | BSplCLib::D3(u,index,deg,periodic,POLES, |
| 530 | *((TColStd_Array1OfReal*) NULL), |
| 531 | FKNOTS,FMULTS,P,V1,V2,V3); |
| 532 | } |
| 533 | } |
| 534 | |
| 535 | //======================================================================= |
| 536 | //function : LocalDN |
| 537 | //purpose : |
| 538 | //======================================================================= |
| 539 | |
| 540 | gp_Vec Geom_BSplineCurve::LocalDN |
| 541 | (const Standard_Real U, |
| 542 | const Standard_Integer FromK1, |
| 543 | const Standard_Integer ToK2, |
| 544 | const Standard_Integer N ) const |
| 545 | { |
| 546 | Standard_DomainError_Raise_if (FromK1 == ToK2, |
| 547 | "Geom_BSplineCurve::LocalD3"); |
| 548 | |
| 549 | Standard_Real u = U; |
| 550 | Standard_Integer index = 0; |
| 551 | BSplCLib::LocateParameter(deg, FKNOTS, U, periodic, FromK1,ToK2, index, u); |
| 552 | index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic); |
| 553 | |
| 554 | gp_Vec V; |
| 555 | if (rational) { |
| 556 | BSplCLib::DN(u,N,index,deg,periodic,POLES, |
| 557 | weights->Array1(), |
| 558 | FKNOTS,FMULTS,V); |
| 559 | } |
| 560 | else { |
| 561 | BSplCLib::DN(u,N,index,deg,periodic,POLES, |
| 562 | *((TColStd_Array1OfReal*) NULL), |
| 563 | FKNOTS,FMULTS,V); |
| 564 | } |
| 565 | return V; |
| 566 | } |
| 567 | |
| 568 | //======================================================================= |
| 569 | //function : Multiplicity |
| 570 | //purpose : |
| 571 | //======================================================================= |
| 572 | |
| 573 | Standard_Integer Geom_BSplineCurve::Multiplicity |
| 574 | (const Standard_Integer Index) const |
| 575 | { |
| 576 | Standard_OutOfRange_Raise_if (Index < 1 || Index > mults->Length(), |
| 577 | "Geom_BSplineCurve::Multiplicity"); |
| 578 | return mults->Value (Index); |
| 579 | } |
| 580 | |
| 581 | //======================================================================= |
| 582 | //function : Multiplicities |
| 583 | //purpose : |
| 584 | //======================================================================= |
| 585 | |
| 586 | void Geom_BSplineCurve::Multiplicities (TColStd_Array1OfInteger& M) const |
| 587 | { |
| 588 | Standard_DimensionError_Raise_if (M.Length() != mults->Length(), |
| 589 | "Geom_BSplineCurve::Multiplicities"); |
| 590 | M = mults->Array1(); |
| 591 | } |
| 592 | |
| 593 | //======================================================================= |
| 594 | //function : NbKnots |
| 595 | //purpose : |
| 596 | //======================================================================= |
| 597 | |
| 598 | Standard_Integer Geom_BSplineCurve::NbKnots () const |
| 599 | { return knots->Length(); } |
| 600 | |
| 601 | //======================================================================= |
| 602 | //function : NbPoles |
| 603 | //purpose : |
| 604 | //======================================================================= |
| 605 | |
| 606 | Standard_Integer Geom_BSplineCurve::NbPoles () const |
| 607 | { return poles->Length(); } |
| 608 | |
| 609 | //======================================================================= |
| 610 | //function : Pole |
| 611 | //purpose : |
| 612 | //======================================================================= |
| 613 | |
| 614 | gp_Pnt Geom_BSplineCurve::Pole (const Standard_Integer Index) const |
| 615 | { |
| 616 | Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(), |
| 617 | "Geom_BSplineCurve::Pole"); |
| 618 | return poles->Value (Index); |
| 619 | } |
| 620 | |
| 621 | //======================================================================= |
| 622 | //function : Poles |
| 623 | //purpose : |
| 624 | //======================================================================= |
| 625 | |
| 626 | void Geom_BSplineCurve::Poles (TColgp_Array1OfPnt& P) const |
| 627 | { |
| 628 | Standard_DimensionError_Raise_if (P.Length() != poles->Length(), |
| 629 | "Geom_BSplineCurve::Poles"); |
| 630 | P = poles->Array1(); |
| 631 | } |
| 632 | |
| 633 | //======================================================================= |
| 634 | //function : StartPoint |
| 635 | //purpose : |
| 636 | //======================================================================= |
| 637 | |
| 638 | gp_Pnt Geom_BSplineCurve::StartPoint () const |
| 639 | { |
| 640 | if (mults->Value (1) == deg + 1) |
| 641 | return poles->Value (1); |
| 642 | else |
| 643 | return Value(FirstParameter()); |
| 644 | } |
| 645 | |
| 646 | //======================================================================= |
| 647 | //function : Weight |
| 648 | //purpose : |
| 649 | //======================================================================= |
| 650 | |
| 651 | Standard_Real Geom_BSplineCurve::Weight |
| 652 | (const Standard_Integer Index) const |
| 653 | { |
| 654 | Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(), |
| 655 | "Geom_BSplineCurve::Weight"); |
| 656 | if (IsRational()) |
| 657 | return weights->Value (Index); |
| 658 | else |
| 659 | return 1.; |
| 660 | } |
| 661 | |
| 662 | //======================================================================= |
| 663 | //function : Weights |
| 664 | //purpose : |
| 665 | //======================================================================= |
| 666 | |
| 667 | void Geom_BSplineCurve::Weights |
| 668 | (TColStd_Array1OfReal& W) const |
| 669 | { |
| 670 | Standard_DimensionError_Raise_if (W.Length() != poles->Length(), |
| 671 | "Geom_BSplineCurve::Weights"); |
| 672 | if (IsRational()) |
| 673 | W = weights->Array1(); |
| 674 | else { |
| 675 | Standard_Integer i; |
| 676 | |
| 677 | for (i = W.Lower(); i <= W.Upper(); i++) |
| 678 | W(i) = 1.; |
| 679 | } |
| 680 | } |
| 681 | |
| 682 | //======================================================================= |
| 683 | //function : IsRational |
| 684 | //purpose : |
| 685 | //======================================================================= |
| 686 | |
| 687 | Standard_Boolean Geom_BSplineCurve::IsRational () const |
| 688 | { |
| 689 | return !weights.IsNull(); |
| 690 | } |
| 691 | |
| 692 | //======================================================================= |
| 693 | //function : Transform |
| 694 | //purpose : |
| 695 | //======================================================================= |
| 696 | |
| 697 | void Geom_BSplineCurve::Transform |
| 698 | (const gp_Trsf& T) |
| 699 | { |
| 700 | TColgp_Array1OfPnt & CPoles = poles->ChangeArray1(); |
| 701 | for (Standard_Integer I = 1; I <= CPoles.Length(); I++) |
| 702 | CPoles (I).Transform (T); |
| 703 | InvalidateCache() ; |
| 704 | maxderivinvok = 0; |
| 705 | } |
| 706 | |
| 707 | //======================================================================= |
| 708 | //function : LocateU |
| 709 | //purpose : |
| 710 | // pmn : 30/01/97 mise en conformite avec le cdl, lorsque U est un noeud |
| 711 | // (PRO6988) |
| 712 | //======================================================================= |
| 713 | |
| 714 | void Geom_BSplineCurve::LocateU |
| 715 | (const Standard_Real U, |
| 716 | const Standard_Real ParametricTolerance, |
| 717 | Standard_Integer& I1, |
| 718 | Standard_Integer& I2, |
| 719 | const Standard_Boolean WithKnotRepetition) const |
| 720 | { |
| 721 | Standard_Real NewU = U; |
| 722 | Handle(TColStd_HArray1OfReal) TheKnots; |
| 723 | if (WithKnotRepetition) TheKnots = flatknots; |
| 724 | else TheKnots = knots; |
| 725 | const TColStd_Array1OfReal & CKnots = TheKnots->Array1(); |
| 726 | |
| 727 | PeriodicNormalization(NewU); //Attention a la periode |
| 728 | |
| 729 | Standard_Real UFirst = CKnots (1); |
| 730 | Standard_Real ULast = CKnots (CKnots.Length()); |
| 731 | Standard_Real PParametricTolerance = Abs(ParametricTolerance); |
| 732 | if (Abs (NewU - UFirst) <= PParametricTolerance) { I1 = I2 = 1; } |
| 733 | else if (Abs (NewU - ULast) <= PParametricTolerance) { |
| 734 | I1 = I2 = CKnots.Length(); |
| 735 | } |
| 736 | else if (NewU < UFirst) { |
| 737 | I2 = 1; |
| 738 | I1 = 0; |
| 739 | } |
| 740 | else if (NewU > ULast) { |
| 741 | I1 = CKnots.Length(); |
| 742 | I2 = I1 + 1; |
| 743 | } |
| 744 | else { |
| 745 | I1 = 1; |
| 746 | BSplCLib::Hunt (CKnots, NewU, I1); |
| 747 | while ( Abs( CKnots(I1+1) - NewU) <= PParametricTolerance) I1++; |
| 748 | if ( Abs( CKnots(I1) - NewU) <= PParametricTolerance) { |
| 749 | I2 = I1; |
| 750 | } |
| 751 | else { |
| 752 | I2 = I1 + 1; |
| 753 | } |
| 754 | } |
| 755 | } |
| 756 | |
| 757 | //======================================================================= |
| 758 | //function : Resolution |
| 759 | //purpose : |
| 760 | //======================================================================= |
| 761 | |
| 762 | void Geom_BSplineCurve::Resolution(const Standard_Real Tolerance3D, |
| 763 | Standard_Real & UTolerance) |
| 764 | { |
| 765 | Standard_Integer ii; |
| 766 | if(!maxderivinvok){ |
| 767 | if ( periodic) { |
| 768 | Standard_Integer NbKnots, NbPoles; |
| 769 | BSplCLib::PrepareUnperiodize( deg, |
| 770 | mults->Array1(), |
| 771 | NbKnots, |
| 772 | NbPoles); |
| 773 | TColgp_Array1OfPnt new_poles(1,NbPoles) ; |
| 774 | TColStd_Array1OfReal new_weights(1,NbPoles) ; |
| 775 | for(ii = 1 ; ii <= NbPoles ; ii++) { |
| 776 | new_poles(ii) = poles->Array1()((ii-1) % poles->Length() + 1) ; |
| 777 | } |
| 778 | if (rational) { |
| 779 | for(ii = 1 ; ii <= NbPoles ; ii++) { |
| 780 | new_weights(ii) = weights->Array1()((ii-1) % poles->Length() + 1) ; |
| 781 | } |
| 782 | BSplCLib::Resolution(new_poles, |
| 783 | new_weights, |
| 784 | new_poles.Length(), |
| 785 | flatknots->Array1(), |
| 786 | deg, |
| 787 | 1., |
| 788 | maxderivinv) ; |
| 789 | } |
| 790 | else { |
| 791 | BSplCLib::Resolution(new_poles, |
| 792 | *((TColStd_Array1OfReal*) NULL), |
| 793 | new_poles.Length(), |
| 794 | flatknots->Array1(), |
| 795 | deg, |
| 796 | 1., |
| 797 | maxderivinv) ; |
| 798 | } |
| 799 | |
| 800 | } |
| 801 | else { |
| 802 | if (rational) { |
| 803 | BSplCLib::Resolution(poles->Array1(), |
| 804 | weights->Array1(), |
| 805 | poles->Length(), |
| 806 | flatknots->Array1(), |
| 807 | deg, |
| 808 | 1., |
| 809 | maxderivinv) ; |
| 810 | } |
| 811 | else { |
| 812 | BSplCLib::Resolution(poles->Array1(), |
| 813 | *((TColStd_Array1OfReal*) NULL), |
| 814 | poles->Length(), |
| 815 | flatknots->Array1(), |
| 816 | deg, |
| 817 | 1., |
| 818 | maxderivinv) ; |
| 819 | } |
| 820 | } |
| 821 | maxderivinvok = 1; |
| 822 | } |
| 823 | UTolerance = Tolerance3D * maxderivinv; |
| 824 | } |
| 825 | |
| 826 | //======================================================================= |
| 827 | //function : IsEqual |
| 828 | //purpose : |
| 829 | //======================================================================= |
| 830 | |
| 831 | Standard_Boolean Geom_BSplineCurve::IsEqual(const Handle(Geom_BSplineCurve)& theOther, |
| 832 | const Standard_Real thePreci) const |
| 833 | { |
| 834 | if( knots.IsNull() || poles.IsNull() || mults.IsNull() ) |
| 835 | return Standard_False; |
| 836 | if( deg != theOther->Degree()) |
| 837 | return Standard_False; |
| 838 | if( knots->Length() != theOther->NbKnots() || |
| 839 | poles->Length() != theOther->NbPoles()) |
| 840 | return Standard_False; |
| 841 | |
| 842 | Standard_Integer i = 1; |
| 843 | for( i = 1 ; i <= poles->Length(); i++ ) |
| 844 | { |
| 845 | const gp_Pnt& aPole1 = poles->Value(i); |
| 846 | const gp_Pnt& aPole2 =theOther->Pole(i); |
| 847 | if( fabs( aPole1.X() - aPole2.X() ) > thePreci || |
| 848 | fabs( aPole1.Y() - aPole2.Y() ) > thePreci || |
| 849 | fabs( aPole1.Z() - aPole2.Z() ) > thePreci ) |
| 850 | return Standard_False; |
| 851 | } |
| 852 | |
| 853 | for( ; i <= knots->Length(); i++ ) |
| 854 | { |
| 855 | if( fabs(knots->Value(i) - theOther->Knot(i)) > Precision::Parametric(thePreci) ) |
| 856 | return Standard_False; |
| 857 | } |
| 858 | |
| 859 | for( i = 1 ; i <= mults->Length(); i++ ) |
| 860 | { |
| 861 | if( mults->Value(i) != theOther->Multiplicity(i) ) |
| 862 | return Standard_False; |
| 863 | } |
| 864 | |
| 865 | if( rational != theOther->IsRational()) |
| 866 | return Standard_False; |
| 867 | |
| 868 | if(!rational) |
| 869 | return Standard_True; |
| 870 | |
| 871 | for( i = 1 ; i <= weights->Length(); i++ ) |
| 872 | { |
| 873 | if( fabs( Standard_Real(weights->Value(i) - theOther->Weight(i))) > Epsilon(weights->Value(i)) ) |
| 874 | return Standard_False; |
| 875 | } |
| 876 | return Standard_True; |
| 877 | } |