1 // Created on: 1993-03-09
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // xab : 30-Mar-95 introduced cache mechanism for surfaces
18 // xab : 21-Jun-95 in remove knots sync size of weights and poles
19 // pmn : 28-Jun-96 Distinction entre la continuite en U et V (bug PRO4625)
20 // pmn : 07-Jan-97 Centralisation des verif rational (PRO6834)
21 // et ajout des InvalideCache() dans les SetPole* (PRO6833)
22 // pmn : 03-Feb-97 Prise en compte de la periode dans Locate(U/V) (PRO6963)
23 // + bon appel a LocateParameter (PRO6973).
24 // RBD : 15/10/98 ; Le cache est desormais defini sur [-1,1] (pro15537).
26 #define No_Standard_OutOfRange
27 #define No_Standard_DimensionError
30 #include <BSplCLib.hxx>
31 #include <BSplSLib.hxx>
32 #include <Geom_BSplineCurve.hxx>
33 #include <Geom_BSplineSurface.hxx>
34 #include <Geom_Curve.hxx>
35 #include <Geom_Geometry.hxx>
36 #include <Geom_UndefinedDerivative.hxx>
39 #include <gp_Trsf.hxx>
41 #include <Precision.hxx>
42 #include <Standard_ConstructionError.hxx>
43 #include <Standard_DimensionError.hxx>
44 #include <Standard_DomainError.hxx>
45 #include <Standard_Mutex.hxx>
46 #include <Standard_NoSuchObject.hxx>
47 #include <Standard_NotImplemented.hxx>
48 #include <Standard_OutOfRange.hxx>
49 #include <Standard_RangeError.hxx>
50 #include <TColgp_Array1OfXYZ.hxx>
52 #define POLES (poles->Array2())
53 #define WEIGHTS (weights->Array2())
54 #define UKNOTS (uknots->Array1())
55 #define VKNOTS (vknots->Array1())
56 #define UFKNOTS (ufknots->Array1())
57 #define VFKNOTS (vfknots->Array1())
58 #define FMULTS (BSplCLib::NoMults())
60 //=======================================================================
63 //=======================================================================
65 Standard_Boolean Geom_BSplineSurface::IsCNu
66 (const Standard_Integer N) const
68 Standard_RangeError_Raise_if (N < 0, " ");
70 case GeomAbs_CN : return Standard_True;
71 case GeomAbs_C0 : return N <= 0;
72 case GeomAbs_G1 : return N <= 0;
73 case GeomAbs_C1 : return N <= 1;
74 case GeomAbs_G2 : return N <= 1;
75 case GeomAbs_C2 : return N <= 2;
77 return N <= 3 ? Standard_True :
78 N <= udeg - BSplCLib::MaxKnotMult (umults->Array1(), umults->Lower() + 1, umults->Upper() - 1);
80 return Standard_False;
84 //=======================================================================
87 //=======================================================================
89 Standard_Boolean Geom_BSplineSurface::IsCNv
90 (const Standard_Integer N) const
92 Standard_RangeError_Raise_if (N < 0, " ");
95 case GeomAbs_CN : return Standard_True;
96 case GeomAbs_C0 : return N <= 0;
97 case GeomAbs_G1 : return N <= 0;
98 case GeomAbs_C1 : return N <= 1;
99 case GeomAbs_G2 : return N <= 1;
100 case GeomAbs_C2 : return N <= 2;
102 return N <= 3 ? Standard_True :
103 N <= vdeg - BSplCLib::MaxKnotMult (vmults->Array1(), vmults->Lower() + 1, vmults->Upper() - 1);
105 return Standard_False;
109 //=======================================================================
112 //=======================================================================
114 void Geom_BSplineSurface::D0(const Standard_Real U,
115 const Standard_Real V,
118 Standard_Real aNewU = U;
119 Standard_Real aNewV = V;
120 PeriodicNormalization(aNewU, aNewV);
122 BSplSLib::D0(aNewU,aNewV,0,0,POLES,&WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
123 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
127 //=======================================================================
130 //=======================================================================
132 void Geom_BSplineSurface::D1(const Standard_Real U,
133 const Standard_Real V,
138 Standard_Real aNewU = U;
139 Standard_Real aNewV = V;
140 PeriodicNormalization(aNewU, aNewV);
142 Standard_Integer uindex = 0, vindex = 0;
144 BSplCLib::LocateParameter(udeg, uknots->Array1(), &umults->Array1(), U, uperiodic, uindex, aNewU);
145 uindex = BSplCLib::FlatIndex(udeg, uindex, umults->Array1(), uperiodic);
147 BSplCLib::LocateParameter(vdeg, vknots->Array1(), &vmults->Array1(), V, vperiodic, vindex, aNewV);
148 vindex = BSplCLib::FlatIndex(vdeg, vindex, vmults->Array1(), vperiodic);
150 BSplSLib::D1(aNewU,aNewV,uindex,vindex,POLES,&WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
151 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
155 //=======================================================================
158 //=======================================================================
160 void Geom_BSplineSurface::D2 (const Standard_Real U,
161 const Standard_Real V,
169 Standard_Real aNewU = U;
170 Standard_Real aNewV = V;
171 PeriodicNormalization(aNewU, aNewV);
173 Standard_Integer uindex = 0, vindex = 0;
175 BSplCLib::LocateParameter(udeg, uknots->Array1(), &umults->Array1(), U, uperiodic, uindex, aNewU);
176 uindex = BSplCLib::FlatIndex(udeg, uindex, umults->Array1(), uperiodic);
178 BSplCLib::LocateParameter(vdeg, vknots->Array1(), &vmults->Array1(), V, vperiodic, vindex, aNewV);
179 vindex = BSplCLib::FlatIndex(vdeg, vindex, vmults->Array1(), vperiodic);
181 BSplSLib::D2(aNewU,aNewV,uindex,vindex,POLES,&WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
182 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
183 P, D1U, D1V, D2U, D2V, D2UV);
186 //=======================================================================
189 //=======================================================================
191 void Geom_BSplineSurface::D3 (const Standard_Real U,
192 const Standard_Real V,
204 BSplSLib::D3(U,V,0,0,POLES,&WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
205 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
206 P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
209 //=======================================================================
212 //=======================================================================
214 gp_Vec Geom_BSplineSurface::DN (const Standard_Real U,
215 const Standard_Real V,
216 const Standard_Integer Nu,
217 const Standard_Integer Nv ) const
220 BSplSLib::DN(U,V,Nu,Nv,0,0,POLES,&WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
221 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
226 //=======================================================================
227 //function : LocalValue
229 //=======================================================================
231 gp_Pnt Geom_BSplineSurface::LocalValue (const Standard_Real U,
232 const Standard_Real V,
233 const Standard_Integer FromUK1,
234 const Standard_Integer ToUK2,
235 const Standard_Integer FromVK1,
236 const Standard_Integer ToVK2) const
239 LocalD0(U,V,FromUK1,ToUK2,FromVK1,ToVK2,P);
243 //=======================================================================
246 //=======================================================================
248 void Geom_BSplineSurface::LocalD0 (const Standard_Real U,
249 const Standard_Real V,
250 const Standard_Integer FromUK1,
251 const Standard_Integer ToUK2,
252 const Standard_Integer FromVK1,
253 const Standard_Integer ToVK2,
256 Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2,
257 "Geom_BSplineSurface::LocalD0");
259 Standard_Real u = U, v = V;
260 Standard_Integer uindex = 0, vindex = 0;
262 BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2,
264 uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic);
266 BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2,
268 vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic);
270 // BSplSLib::D0(U,V,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
271 BSplSLib::D0(u,v,uindex,vindex,POLES,&WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
272 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
276 //=======================================================================
279 //=======================================================================
281 void Geom_BSplineSurface::LocalD1 (const Standard_Real U,
282 const Standard_Real V,
283 const Standard_Integer FromUK1,
284 const Standard_Integer ToUK2,
285 const Standard_Integer FromVK1,
286 const Standard_Integer ToVK2,
291 Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2,
292 "Geom_BSplineSurface::LocalD1");
294 Standard_Real u = U, v = V;
295 Standard_Integer uindex = 0, vindex = 0;
297 BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2,
299 uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic);
301 BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2,
303 vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic);
305 BSplSLib::D1(u,v,uindex,vindex,POLES,&WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
306 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
310 //=======================================================================
313 //=======================================================================
315 void Geom_BSplineSurface::LocalD2 (const Standard_Real U,
316 const Standard_Real V,
317 const Standard_Integer FromUK1,
318 const Standard_Integer ToUK2,
319 const Standard_Integer FromVK1,
320 const Standard_Integer ToVK2,
328 Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2,
329 "Geom_BSplineSurface::LocalD2");
331 Standard_Real u = U, v = V;
332 Standard_Integer uindex = 0, vindex = 0;
334 BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2,
336 uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic);
338 BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2,
340 vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic);
342 BSplSLib::D2(u,v,uindex,vindex,POLES,&WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
343 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
344 P,D1U,D1V,D2U,D2V,D2UV);
347 //=======================================================================
350 //=======================================================================
352 void Geom_BSplineSurface::LocalD3 (const Standard_Real U,
353 const Standard_Real V,
354 const Standard_Integer FromUK1,
355 const Standard_Integer ToUK2,
356 const Standard_Integer FromVK1,
357 const Standard_Integer ToVK2,
369 Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2,
370 "Geom_BSplineSurface::LocalD3");
372 Standard_Real u = U, v = V;
373 Standard_Integer uindex = 0, vindex = 0;
375 BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2,
377 uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic);
379 BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2,
381 vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic);
383 BSplSLib::D3(u,v,uindex,vindex,POLES,&WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
384 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
385 P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
388 //=======================================================================
391 //=======================================================================
393 gp_Vec Geom_BSplineSurface::LocalDN (const Standard_Real U,
394 const Standard_Real V,
395 const Standard_Integer FromUK1,
396 const Standard_Integer ToUK2,
397 const Standard_Integer FromVK1,
398 const Standard_Integer ToVK2,
399 const Standard_Integer Nu,
400 const Standard_Integer Nv) const
402 Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2,
403 "Geom_BSplineSurface::LocalDN");
405 Standard_Real u = U, v = V;
406 Standard_Integer uindex = 0, vindex = 0;
408 BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2,
410 uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic);
412 BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2,
414 vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic);
417 BSplSLib::DN(u,v,Nu,Nv,uindex,vindex,
418 POLES,&WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
419 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
424 //=======================================================================
427 //=======================================================================
429 gp_Pnt Geom_BSplineSurface::Pole (const Standard_Integer UIndex,
430 const Standard_Integer VIndex) const
432 Standard_OutOfRange_Raise_if
433 (UIndex < 1 || UIndex > poles->ColLength() ||
434 VIndex < 1 || VIndex > poles->RowLength(), " ");
435 return poles->Value (UIndex, VIndex);
438 //=======================================================================
441 //=======================================================================
443 void Geom_BSplineSurface::Poles (TColgp_Array2OfPnt& P) const
445 Standard_DimensionError_Raise_if
446 (P.ColLength() != poles->ColLength() ||
447 P.RowLength() != poles->RowLength(), " ");
451 const TColgp_Array2OfPnt& Geom_BSplineSurface::Poles() const
453 return poles->Array2();
456 //=======================================================================
459 //=======================================================================
461 Handle(Geom_Curve) Geom_BSplineSurface::UIso (const Standard_Real U) const
463 TColgp_Array1OfPnt cpoles(1,poles->RowLength());
464 TColStd_Array1OfReal cweights(1,poles->RowLength());
466 Handle(Geom_BSplineCurve) C;
468 if ( urational || vrational) {
469 BSplSLib::Iso(U,Standard_True,POLES,&WEIGHTS,UFKNOTS,FMULTS,udeg,uperiodic,
471 C = new Geom_BSplineCurve(cpoles,cweights,
477 BSplSLib::Iso(U,Standard_True,POLES,
478 BSplSLib::NoWeights(),
479 UFKNOTS,FMULTS,udeg,uperiodic,
481 C = new Geom_BSplineCurve(cpoles,
490 //=======================================================================
492 //purpose : If CheckRational=False, no try to make it non-rational
493 //=======================================================================
495 Handle(Geom_Curve) Geom_BSplineSurface::UIso (const Standard_Real U,
496 const Standard_Boolean CheckRational) const
498 TColgp_Array1OfPnt cpoles(1,poles->RowLength());
499 TColStd_Array1OfReal cweights(1,poles->RowLength());
501 Handle(Geom_BSplineCurve) C;
503 if ( urational || vrational) {
504 BSplSLib::Iso(U,Standard_True,POLES,&WEIGHTS,UFKNOTS,FMULTS,udeg,uperiodic,
506 C = new Geom_BSplineCurve(cpoles,cweights,
513 BSplSLib::Iso(U,Standard_True,POLES,
514 BSplSLib::NoWeights(),
515 UFKNOTS,FMULTS,udeg,uperiodic,
517 C = new Geom_BSplineCurve(cpoles,
526 //=======================================================================
529 //=======================================================================
531 Standard_Real Geom_BSplineSurface::UKnot(const Standard_Integer UIndex) const
533 Standard_OutOfRange_Raise_if (UIndex < 1 || UIndex > uknots->Length(), " ");
534 return uknots->Value (UIndex);
537 //=======================================================================
540 //=======================================================================
542 Standard_Real Geom_BSplineSurface::VKnot(const Standard_Integer VIndex) const
544 Standard_OutOfRange_Raise_if (VIndex < 1 || VIndex > vknots->Length(), " ");
545 return vknots->Value (VIndex);
548 //=======================================================================
551 //=======================================================================
553 void Geom_BSplineSurface::UKnots (TColStd_Array1OfReal& Ku) const
555 Standard_DimensionError_Raise_if (Ku.Length() != uknots->Length(), " ");
556 Ku = uknots->Array1();
559 const TColStd_Array1OfReal& Geom_BSplineSurface::UKnots() const
561 return uknots->Array1();
564 //=======================================================================
567 //=======================================================================
569 void Geom_BSplineSurface::VKnots (TColStd_Array1OfReal& Kv) const
571 Standard_DimensionError_Raise_if (Kv.Length() != vknots->Length(), " ");
572 Kv = vknots->Array1();
575 const TColStd_Array1OfReal& Geom_BSplineSurface::VKnots() const
577 return vknots->Array1();
580 //=======================================================================
581 //function : UKnotSequence
583 //=======================================================================
585 void Geom_BSplineSurface::UKnotSequence (TColStd_Array1OfReal& Ku) const
587 Standard_DimensionError_Raise_if (Ku.Length() != ufknots->Length(), " ");
588 Ku = ufknots->Array1();
591 const TColStd_Array1OfReal& Geom_BSplineSurface::UKnotSequence() const
593 return ufknots->Array1();
596 //=======================================================================
597 //function : VKnotSequence
599 //=======================================================================
601 void Geom_BSplineSurface::VKnotSequence (TColStd_Array1OfReal& Kv) const
603 Standard_DimensionError_Raise_if (Kv.Length() != vfknots->Length(), " ");
604 Kv = vfknots->Array1();
607 const TColStd_Array1OfReal& Geom_BSplineSurface::VKnotSequence() const
609 return vfknots->Array1();
612 //=======================================================================
613 //function : UMultiplicity
615 //=======================================================================
617 Standard_Integer Geom_BSplineSurface::UMultiplicity
618 (const Standard_Integer UIndex) const
620 Standard_OutOfRange_Raise_if (UIndex < 1 || UIndex > umults->Length()," ");
621 return umults->Value (UIndex);
624 //=======================================================================
625 //function : UMultiplicities
627 //=======================================================================
629 void Geom_BSplineSurface::UMultiplicities (TColStd_Array1OfInteger& Mu) const
631 Standard_DimensionError_Raise_if (Mu.Length() != umults->Length(), " ");
632 Mu = umults->Array1();
635 const TColStd_Array1OfInteger& Geom_BSplineSurface::UMultiplicities() const
637 return umults->Array1();
640 //=======================================================================
643 //=======================================================================
645 Handle(Geom_Curve) Geom_BSplineSurface::VIso (const Standard_Real V) const
647 TColgp_Array1OfPnt cpoles(1,poles->ColLength());
648 TColStd_Array1OfReal cweights(1,poles->ColLength());
650 Handle(Geom_BSplineCurve) C;
652 if ( urational || vrational) {
653 BSplSLib::Iso(V,Standard_False,POLES,
655 VFKNOTS,FMULTS,vdeg,vperiodic,
657 C = new Geom_BSplineCurve(cpoles,cweights,
663 BSplSLib::Iso(V,Standard_False,POLES,
664 BSplSLib::NoWeights(),
665 VFKNOTS,FMULTS,vdeg,vperiodic,
667 C = new Geom_BSplineCurve(cpoles,
676 //=======================================================================
678 //purpose : If CheckRational=False, no try to make it non-rational
679 //=======================================================================
681 Handle(Geom_Curve) Geom_BSplineSurface::VIso (const Standard_Real V,
682 const Standard_Boolean CheckRational) const
684 TColgp_Array1OfPnt cpoles(1,poles->ColLength());
685 TColStd_Array1OfReal cweights(1,poles->ColLength());
687 Handle(Geom_BSplineCurve) C;
689 if ( urational || vrational) {
690 BSplSLib::Iso(V,Standard_False,POLES,
692 VFKNOTS,FMULTS,vdeg,vperiodic,
694 C = new Geom_BSplineCurve(cpoles,cweights,
701 BSplSLib::Iso(V,Standard_False,POLES,
702 BSplSLib::NoWeights(),
703 VFKNOTS,FMULTS,vdeg,vperiodic,
705 C = new Geom_BSplineCurve(cpoles,
714 //=======================================================================
715 //function : VMultiplicity
717 //=======================================================================
719 Standard_Integer Geom_BSplineSurface::VMultiplicity
720 (const Standard_Integer VIndex) const
722 Standard_OutOfRange_Raise_if (VIndex < 1 || VIndex > vmults->Length()," ");
723 return vmults->Value (VIndex);
726 //=======================================================================
727 //function : VMultiplicities
729 //=======================================================================
731 void Geom_BSplineSurface::VMultiplicities (TColStd_Array1OfInteger& Mv) const
733 Standard_DimensionError_Raise_if (Mv.Length() != vmults->Length(), " ");
734 Mv = vmults->Array1();
737 const TColStd_Array1OfInteger& Geom_BSplineSurface::VMultiplicities() const
739 return vmults->Array1();
742 //=======================================================================
745 //=======================================================================
747 Standard_Real Geom_BSplineSurface::Weight
748 (const Standard_Integer UIndex,
749 const Standard_Integer VIndex ) const
751 Standard_OutOfRange_Raise_if
752 (UIndex < 1 || UIndex > weights->ColLength() ||
753 VIndex < 1 || VIndex > weights->RowLength(), " ");
754 return weights->Value (UIndex, VIndex);
757 //=======================================================================
760 //=======================================================================
762 void Geom_BSplineSurface::Weights (TColStd_Array2OfReal& W) const
764 Standard_DimensionError_Raise_if
765 (W.ColLength() != weights->ColLength() ||
766 W.RowLength() != weights->RowLength(), " ");
767 W = weights->Array2();
770 const TColStd_Array2OfReal* Geom_BSplineSurface::Weights() const
772 if (urational || vrational)
773 return &weights->Array2();
774 return BSplSLib::NoWeights();
777 //=======================================================================
778 //function : Transform
780 //=======================================================================
782 void Geom_BSplineSurface::Transform (const gp_Trsf& T)
784 TColgp_Array2OfPnt & VPoles = poles->ChangeArray2();
785 for (Standard_Integer j = VPoles.LowerCol(); j <= VPoles.UpperCol(); j++) {
786 for (Standard_Integer i = VPoles.LowerRow(); i <= VPoles.UpperRow(); i++) {
787 VPoles (i, j).Transform (T);
792 //=======================================================================
793 //function : SetUPeriodic
795 //=======================================================================
797 void Geom_BSplineSurface::SetUPeriodic ()
799 Standard_Integer i,j;
801 Standard_Integer first = FirstUKnotIndex();
802 Standard_Integer last = LastUKnotIndex();
804 Handle(TColStd_HArray1OfReal) tk = uknots;
805 TColStd_Array1OfReal cknots((uknots->Array1())(first),first,last);
806 uknots = new TColStd_HArray1OfReal(1,cknots.Length());
807 uknots->ChangeArray1() = cknots;
809 Handle(TColStd_HArray1OfInteger) tm = umults;
810 TColStd_Array1OfInteger cmults((umults->Array1())(first),first,last);
811 // Modified by Sergey KHROMOV - Mon Feb 10 10:59:00 2003 Begin
812 // cmults(first) = cmults(last) = Max( cmults(first), cmults(last));
813 cmults(first) = cmults(last) = Min(udeg, Max( cmults(first), cmults(last)));
814 // Modified by Sergey KHROMOV - Mon Feb 10 10:59:00 2003 End
815 umults = new TColStd_HArray1OfInteger(1,cmults.Length());
816 umults->ChangeArray1() = cmults;
818 // compute new number of poles;
819 Standard_Integer nbp = BSplCLib::NbPoles(udeg,Standard_True,cmults);
821 TColgp_Array2OfPnt cpoles(1,nbp,poles->LowerCol(),poles->UpperCol());
822 for (i = 1; i <= nbp; i++) {
823 for (j = poles->LowerCol(); j <= poles->UpperCol(); j++) {
824 cpoles(i,j) = poles->Value(i,j);
828 new TColgp_HArray2OfPnt(1,nbp,cpoles.LowerCol(),cpoles.UpperCol());
829 poles->ChangeArray2() = cpoles;
832 cweights(1,nbp,weights->LowerCol(),weights->UpperCol());
833 if (urational || vrational) {
834 for (i = 1; i <= nbp; i++) {
835 for (j = weights->LowerCol(); j <= weights->UpperCol(); j++) {
836 cweights(i,j) = weights->Value(i,j);
841 for (i = 1; i <= nbp; i++) {
842 for (j = weights->LowerCol(); j <= weights->UpperCol(); j++) {
848 TColStd_HArray2OfReal(1,nbp,cweights.LowerCol(),cweights.UpperCol());
849 weights->ChangeArray2() = cweights;
852 uperiodic = Standard_True;
858 //=======================================================================
859 //function : SetVPeriodic
861 //=======================================================================
863 void Geom_BSplineSurface::SetVPeriodic ()
865 Standard_Integer i,j;
867 Standard_Integer first = FirstVKnotIndex();
868 Standard_Integer last = LastVKnotIndex();
870 Handle(TColStd_HArray1OfReal) tk = vknots;
871 TColStd_Array1OfReal cknots((vknots->Array1())(first),first,last);
872 vknots = new TColStd_HArray1OfReal(1,cknots.Length());
873 vknots->ChangeArray1() = cknots;
876 Handle(TColStd_HArray1OfInteger) tm = vmults;
877 TColStd_Array1OfInteger cmults((vmults->Array1())(first),first,last);
878 // Modified by Sergey KHROMOV - Mon Feb 10 11:00:33 2003 Begin
879 // cmults(first) = cmults(last) = Max( cmults(first), cmults(last));
880 cmults(first) = cmults(last) = Min(vdeg, Max( cmults(first), cmults(last)));
881 // Modified by Sergey KHROMOV - Mon Feb 10 11:00:34 2003 End
882 vmults = new TColStd_HArray1OfInteger(1,cmults.Length());
883 vmults->ChangeArray1() = cmults;
885 // compute new number of poles;
886 Standard_Integer nbp = BSplCLib::NbPoles(vdeg,Standard_True,cmults);
888 TColgp_Array2OfPnt cpoles(poles->LowerRow(),poles->UpperRow(),1,nbp);
889 for (i = poles->LowerRow(); i <= poles->UpperRow(); i++) {
890 for (j = 1; j <= nbp; j++) {
891 cpoles(i,j) = poles->Value(i,j);
895 new TColgp_HArray2OfPnt(cpoles.LowerRow(),cpoles.UpperRow(),1,nbp);
896 poles->ChangeArray2() = cpoles;
898 if (urational || vrational) {
900 cweights(weights->LowerRow(),weights->UpperRow(),1,nbp);
901 for (i = weights->LowerRow(); i <= weights->UpperRow(); i++) {
902 for (j = 1; j <= nbp; j++) {
903 cweights(i,j) = weights->Value(i,j);
907 TColStd_HArray2OfReal(cweights.LowerRow(),cweights.UpperRow(),1,nbp);
908 weights->ChangeArray2() = cweights;
911 vperiodic = Standard_True;
917 //=======================================================================
918 //function : SetUOrigin
920 //=======================================================================
922 void Geom_BSplineSurface::SetUOrigin(const Standard_Integer Index)
925 Standard_NoSuchObject::Raise("Geom_BSplineSurface::SetUOrigin");
927 Standard_Integer i,j,k;
928 Standard_Integer first = FirstUKnotIndex();
929 Standard_Integer last = LastUKnotIndex();
931 if ((Index < first) || (Index > last))
932 Standard_DomainError::Raise("Geom_BSplineCurve::SetUOrigin");
934 Standard_Integer nbknots = uknots->Length();
935 Standard_Integer nbpoles = poles->ColLength();
937 Handle(TColStd_HArray1OfReal) nknots =
938 new TColStd_HArray1OfReal(1,nbknots);
939 TColStd_Array1OfReal& newknots = nknots->ChangeArray1();
941 Handle(TColStd_HArray1OfInteger) nmults =
942 new TColStd_HArray1OfInteger(1,nbknots);
943 TColStd_Array1OfInteger& newmults = nmults->ChangeArray1();
945 // set the knots and mults
946 Standard_Real period = uknots->Value(last) - uknots->Value(first);
948 for ( i = Index; i <= last ; i++) {
949 newknots(k) = uknots->Value(i);
950 newmults(k) = umults->Value(i);
953 for ( i = first+1; i <= Index; i++) {
954 newknots(k) = uknots->Value(i) + period;
955 newmults(k) = umults->Value(i);
959 Standard_Integer index = 1;
960 for (i = first+1; i <= Index; i++)
961 index += umults->Value(i);
963 // set the poles and weights
964 Standard_Integer nbvp = poles->RowLength();
965 Handle(TColgp_HArray2OfPnt) npoles =
966 new TColgp_HArray2OfPnt(1,nbpoles,1,nbvp);
967 Handle(TColStd_HArray2OfReal) nweights =
968 new TColStd_HArray2OfReal(1,nbpoles,1,nbvp);
969 TColgp_Array2OfPnt & newpoles = npoles->ChangeArray2();
970 TColStd_Array2OfReal & newweights = nweights->ChangeArray2();
971 first = poles->LowerRow();
972 last = poles->UpperRow();
973 if ( urational || vrational) {
975 for ( i = index; i <= last; i++) {
976 for ( j = 1; j <= nbvp; j++) {
977 newpoles(k,j) = poles->Value(i,j);
978 newweights(k,j) = weights->Value(i,j);
982 for ( i = first; i < index; i++) {
983 for ( j = 1; j <= nbvp; j++) {
984 newpoles(k,j) = poles->Value(i,j);
985 newweights(k,j) = weights->Value(i,j);
992 for ( i = index; i <= last; i++) {
993 for ( j = 1; j <= nbvp; j++) {
994 newpoles(k,j) = poles->Value(i,j);
998 for ( i = first; i < index; i++) {
999 for ( j = 1; j <= nbvp; j++) {
1000 newpoles(k,j) = poles->Value(i,j);
1009 if (urational || vrational)
1015 //=======================================================================
1016 //function : SetVOrigin
1018 //=======================================================================
1020 void Geom_BSplineSurface::SetVOrigin(const Standard_Integer Index)
1023 Standard_NoSuchObject::Raise("Geom_BSplineSurface::SetVOrigin");
1025 Standard_Integer i,j,k;
1026 Standard_Integer first = FirstVKnotIndex();
1027 Standard_Integer last = LastVKnotIndex();
1029 if ((Index < first) || (Index > last))
1030 Standard_DomainError::Raise("Geom_BSplineCurve::SetVOrigin");
1032 Standard_Integer nbknots = vknots->Length();
1033 Standard_Integer nbpoles = poles->RowLength();
1035 Handle(TColStd_HArray1OfReal) nknots =
1036 new TColStd_HArray1OfReal(1,nbknots);
1037 TColStd_Array1OfReal& newknots = nknots->ChangeArray1();
1039 Handle(TColStd_HArray1OfInteger) nmults =
1040 new TColStd_HArray1OfInteger(1,nbknots);
1041 TColStd_Array1OfInteger& newmults = nmults->ChangeArray1();
1043 // set the knots and mults
1044 Standard_Real period = vknots->Value(last) - vknots->Value(first);
1046 for ( i = Index; i <= last ; i++) {
1047 newknots(k) = vknots->Value(i);
1048 newmults(k) = vmults->Value(i);
1051 for ( i = first+1; i <= Index; i++) {
1052 newknots(k) = vknots->Value(i) + period;
1053 newmults(k) = vmults->Value(i);
1057 Standard_Integer index = 1;
1058 for (i = first+1; i <= Index; i++)
1059 index += vmults->Value(i);
1061 // set the poles and weights
1062 Standard_Integer nbup = poles->ColLength();
1063 Handle(TColgp_HArray2OfPnt) npoles =
1064 new TColgp_HArray2OfPnt(1,nbup,1,nbpoles);
1065 Handle(TColStd_HArray2OfReal) nweights =
1066 new TColStd_HArray2OfReal(1,nbup,1,nbpoles);
1067 TColgp_Array2OfPnt & newpoles = npoles->ChangeArray2();
1068 TColStd_Array2OfReal & newweights = nweights->ChangeArray2();
1069 first = poles->LowerCol();
1070 last = poles->UpperCol();
1071 if ( urational || vrational) {
1073 for ( j = index; j <= last; j++) {
1074 for ( i = 1; i <= nbup; i++) {
1075 newpoles(i,k) = poles->Value(i,j);
1076 newweights(i,k) = weights->Value(i,j);
1080 for ( j = first; j < index; j++) {
1081 for ( i = 1; i <= nbup; i++) {
1082 newpoles(i,k) = poles->Value(i,j);
1083 newweights(i,k) = weights->Value(i,j);
1090 for ( j = index; j <= last; j++) {
1091 for ( i = 1; i <= nbup; i++) {
1092 newpoles(i,k) = poles->Value(i,j);
1096 for ( j = first; j < index; j++) {
1097 for ( i = 1; i <= nbup; i++) {
1098 newpoles(i,k) = poles->Value(i,j);
1107 if (urational || vrational)
1113 //=======================================================================
1114 //function : SetUNotPeriodic
1116 //=======================================================================
1118 void Geom_BSplineSurface::SetUNotPeriodic ()
1121 Standard_Integer NbKnots, NbPoles;
1122 BSplCLib::PrepareUnperiodize( udeg, umults->Array1(), NbKnots, NbPoles);
1124 Handle(TColgp_HArray2OfPnt) npoles =
1125 new TColgp_HArray2OfPnt(1,NbPoles, 1, poles->RowLength());
1127 Handle(TColStd_HArray1OfReal) nknots
1128 = new TColStd_HArray1OfReal(1,NbKnots);
1130 Handle(TColStd_HArray1OfInteger) nmults
1131 = new TColStd_HArray1OfInteger(1,NbKnots);
1133 Handle(TColStd_HArray2OfReal) nweights = new TColStd_HArray2OfReal(1,NbPoles, 1, poles->RowLength(), 0);
1135 if ( urational || vrational) {
1137 BSplSLib::Unperiodize(Standard_True , udeg,
1138 umults->Array1() , uknots->Array1(),
1139 poles->Array2() , &weights->Array2(),
1140 nmults->ChangeArray1(), nknots->ChangeArray1(),
1141 npoles->ChangeArray2(),
1142 &nweights->ChangeArray2());
1146 BSplSLib::Unperiodize(Standard_True , udeg,
1147 umults->Array1() , uknots->Array1(),
1148 poles->Array2() , BSplSLib::NoWeights(),
1149 nmults->ChangeArray1(), nknots->ChangeArray1(),
1150 npoles->ChangeArray2(),
1151 BSplSLib::NoWeights());
1157 uperiodic = Standard_False;
1165 //=======================================================================
1166 //function : SetVNotPeriodic
1168 //=======================================================================
1170 void Geom_BSplineSurface::SetVNotPeriodic ()
1173 Standard_Integer NbKnots, NbPoles;
1174 BSplCLib::PrepareUnperiodize( vdeg, vmults->Array1(), NbKnots, NbPoles);
1176 Handle(TColgp_HArray2OfPnt) npoles =
1177 new TColgp_HArray2OfPnt(1, poles->ColLength(), 1, NbPoles);
1179 Handle(TColStd_HArray1OfReal) nknots
1180 = new TColStd_HArray1OfReal(1,NbKnots);
1182 Handle(TColStd_HArray1OfInteger) nmults
1183 = new TColStd_HArray1OfInteger(1,NbKnots) ;
1185 Handle(TColStd_HArray2OfReal) nweights = new TColStd_HArray2OfReal(1, poles->ColLength(), 1, NbPoles, 0);
1187 if ( urational || vrational) {
1189 BSplSLib::Unperiodize(Standard_False , vdeg,
1190 vmults->Array1() , vknots->Array1(),
1191 poles->Array2() , &weights->Array2(),
1192 nmults->ChangeArray1(), nknots->ChangeArray1(),
1193 npoles->ChangeArray2(),
1194 &nweights->ChangeArray2());
1198 BSplSLib::Unperiodize(Standard_False , vdeg,
1199 vmults->Array1() , vknots->Array1(),
1200 poles->Array2() , BSplSLib::NoWeights(),
1201 nmults->ChangeArray1(), nknots->ChangeArray1(),
1202 npoles->ChangeArray2(),
1203 BSplSLib::NoWeights());
1209 vperiodic = Standard_False;
1217 //=======================================================================
1218 //function : IsUClosed
1220 //=======================================================================
1222 Standard_Boolean Geom_BSplineSurface::IsUClosed () const
1225 return Standard_True;
1227 Standard_Real aU1, aU2, aV1, aV2;
1228 Bounds( aU1, aU2, aV1, aV2 );
1229 Handle(Geom_Curve) aCUF = UIso( aU1 );
1230 Handle(Geom_Curve) aCUL = UIso( aU2 );
1231 if(aCUF.IsNull() || aCUL.IsNull())
1232 return Standard_False;
1233 Handle(Geom_BSplineCurve) aBsF = Handle(Geom_BSplineCurve)::DownCast(aCUF);
1234 Handle(Geom_BSplineCurve) aBsL = Handle(Geom_BSplineCurve)::DownCast(aCUL);
1235 return (!aBsF.IsNull() && !aBsL.IsNull() && aBsF->IsEqual( aBsL, Precision::Confusion()) );
1238 //=======================================================================
1239 //function : IsVClosed
1241 //=======================================================================
1243 Standard_Boolean Geom_BSplineSurface::IsVClosed () const
1246 return Standard_True;
1248 Standard_Real aU1, aU2, aV1, aV2;
1249 Bounds( aU1, aU2, aV1, aV2 );
1250 Handle(Geom_Curve) aCVF = VIso( aV1 );
1251 Handle(Geom_Curve) aCVL = VIso( aV2 );
1252 if(aCVF.IsNull() || aCVL.IsNull())
1253 return Standard_False;
1254 Handle(Geom_BSplineCurve) aBsF = Handle(Geom_BSplineCurve)::DownCast(aCVF);
1255 Handle(Geom_BSplineCurve) aBsL = Handle(Geom_BSplineCurve)::DownCast(aCVL);
1256 return (!aBsF.IsNull() && !aBsL.IsNull() && aBsF->IsEqual(aBsL, Precision::Confusion()));
1259 //=======================================================================
1260 //function : IsUPeriodic
1262 //=======================================================================
1264 Standard_Boolean Geom_BSplineSurface::IsUPeriodic () const
1269 //=======================================================================
1270 //function : IsVPeriodic
1272 //=======================================================================
1274 Standard_Boolean Geom_BSplineSurface::IsVPeriodic () const
1279 //=======================================================================
1280 //function : FirstUKnotIndex
1282 //=======================================================================
1284 Standard_Integer Geom_BSplineSurface::FirstUKnotIndex () const
1286 if (uperiodic) return 1;
1287 else return BSplCLib::FirstUKnotIndex(udeg,umults->Array1());
1290 //=======================================================================
1291 //function : FirstVKnotIndex
1293 //=======================================================================
1295 Standard_Integer Geom_BSplineSurface::FirstVKnotIndex () const
1297 if (vperiodic) return 1;
1298 else return BSplCLib::FirstUKnotIndex(vdeg,vmults->Array1());
1301 //=======================================================================
1302 //function : LastUKnotIndex
1304 //=======================================================================
1306 Standard_Integer Geom_BSplineSurface::LastUKnotIndex() const
1308 if (uperiodic) return uknots->Length();
1309 else return BSplCLib::LastUKnotIndex(udeg,umults->Array1());
1312 //=======================================================================
1313 //function : LastVKnotIndex
1315 //=======================================================================
1317 Standard_Integer Geom_BSplineSurface::LastVKnotIndex() const
1319 if (vperiodic) return vknots->Length();
1320 else return BSplCLib::LastUKnotIndex(vdeg,vmults->Array1());
1323 //=======================================================================
1324 //function : LocateU
1326 //=======================================================================
1328 void Geom_BSplineSurface::LocateU
1329 (const Standard_Real U,
1330 const Standard_Real ParametricTolerance,
1331 Standard_Integer& I1,
1332 Standard_Integer& I2,
1333 const Standard_Boolean WithKnotRepetition ) const
1335 Standard_Real NewU =U, vbid = vknots->Value(1);
1336 Handle(TColStd_HArray1OfReal) TheKnots;
1337 if (WithKnotRepetition) TheKnots = ufknots;
1338 else TheKnots = uknots;
1340 PeriodicNormalization(NewU, vbid); //Attention a la periode
1342 const TColStd_Array1OfReal & Knots = TheKnots->Array1();
1343 Standard_Real UFirst = Knots (1);
1344 Standard_Real ULast = Knots (Knots.Length());
1345 Standard_Real PParametricTolerance = Abs(ParametricTolerance);
1346 if (Abs (NewU - UFirst) <= PParametricTolerance) {
1349 else if (Abs (NewU - ULast) <= PParametricTolerance) {
1350 I1 = I2 = Knots.Length();
1352 else if (NewU < UFirst) {
1356 else if (NewU > ULast) {
1357 I1 = Knots.Length();
1362 BSplCLib::Hunt (Knots, NewU, I1);
1363 while ( Abs( Knots(I1+1) - NewU) <= PParametricTolerance) I1++;
1364 if ( Abs( Knots(I1) - NewU) <= PParametricTolerance) {
1373 //=======================================================================
1374 //function : LocateV
1376 //=======================================================================
1378 void Geom_BSplineSurface::LocateV
1379 (const Standard_Real V,
1380 const Standard_Real ParametricTolerance,
1381 Standard_Integer& I1,
1382 Standard_Integer& I2,
1383 const Standard_Boolean WithKnotRepetition ) const
1385 Standard_Real NewV =V, ubid = uknots->Value(1);
1386 Handle(TColStd_HArray1OfReal) TheKnots;
1387 if (WithKnotRepetition) TheKnots = vfknots;
1388 else TheKnots = vknots;
1390 PeriodicNormalization(ubid, NewV); //Attention a la periode
1392 const TColStd_Array1OfReal & Knots = TheKnots->Array1();
1393 Standard_Real VFirst = Knots (1);
1394 Standard_Real VLast = Knots (Knots.Length());
1395 Standard_Real PParametricTolerance = Abs(ParametricTolerance);
1396 if (Abs (NewV - VFirst) <= PParametricTolerance) { I1 = I2 = 1; }
1397 else if (Abs (NewV - VLast) <= PParametricTolerance) {
1398 I1 = I2 = Knots.Length();
1400 else if (NewV < VFirst - PParametricTolerance) {
1404 else if (NewV > VLast + PParametricTolerance) {
1405 I1 = Knots.Length();
1410 BSplCLib::Hunt (Knots, NewV, I1);
1411 while ( Abs( Knots(I1+1) - NewV) <= PParametricTolerance) I1++;
1412 if ( Abs( Knots(I1) - NewV) <= PParametricTolerance) {
1421 //=======================================================================
1422 //function : UReverse
1424 //=======================================================================
1426 void Geom_BSplineSurface::UReverse ()
1428 BSplCLib::Reverse(umults->ChangeArray1());
1429 BSplCLib::Reverse(uknots->ChangeArray1());
1430 Standard_Integer last;
1432 last = ufknots->Upper() - udeg -1;
1434 last = poles->UpperRow();
1435 BSplSLib::Reverse(poles->ChangeArray2(),last,Standard_True);
1436 if (urational || vrational)
1437 BSplSLib::Reverse(weights->ChangeArray2(),last,Standard_True);
1441 //=======================================================================
1442 //function : UReversedParameter
1444 //=======================================================================
1446 Standard_Real Geom_BSplineSurface::UReversedParameter
1447 ( const Standard_Real U) const
1449 return ( uknots->Value( 1) + uknots->Value( uknots->Length()) - U);
1452 //=======================================================================
1453 //function : VReverse
1455 //=======================================================================
1457 void Geom_BSplineSurface::VReverse ()
1459 BSplCLib::Reverse(vmults->ChangeArray1());
1460 BSplCLib::Reverse(vknots->ChangeArray1());
1461 Standard_Integer last;
1463 last = vfknots->Upper() - vdeg -1;
1465 last = poles->UpperCol();
1466 BSplSLib::Reverse(poles->ChangeArray2(),last,Standard_False);
1467 if (urational || vrational)
1468 BSplSLib::Reverse(weights->ChangeArray2(),last,Standard_False);
1472 //=======================================================================
1473 //function : VReversedParameter
1475 //=======================================================================
1477 Standard_Real Geom_BSplineSurface::VReversedParameter
1478 ( const Standard_Real V) const
1480 return ( vknots->Value( 1) + vknots->Value( vknots->Length()) - V);
1483 //=======================================================================
1484 //function : SetPoleCol
1486 //=======================================================================
1488 void Geom_BSplineSurface::SetPoleCol (const Standard_Integer VIndex,
1489 const TColgp_Array1OfPnt& CPoles)
1491 if (VIndex < 1 || VIndex > poles->RowLength()) {
1492 Standard_OutOfRange::Raise();
1494 if (CPoles.Lower() < 1 || CPoles.Lower() > poles->ColLength() ||
1495 CPoles.Upper() < 1 || CPoles.Upper() > poles->ColLength()) {
1496 Standard_ConstructionError::Raise();
1499 TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1501 for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
1502 Poles (I+Poles.LowerRow()-1, VIndex+Poles.LowerCol()-1) = CPoles(I);
1506 //=======================================================================
1507 //function : SetPoleCol
1509 //=======================================================================
1511 void Geom_BSplineSurface::SetPoleCol (const Standard_Integer VIndex,
1512 const TColgp_Array1OfPnt& CPoles,
1513 const TColStd_Array1OfReal& CPoleWeights)
1515 SetPoleCol (VIndex, CPoles);
1516 SetWeightCol(VIndex, CPoleWeights);
1519 //=======================================================================
1520 //function : SetPoleRow
1522 //=======================================================================
1524 void Geom_BSplineSurface::SetPoleRow (const Standard_Integer UIndex,
1525 const TColgp_Array1OfPnt& CPoles)
1527 if (UIndex < 1 || UIndex > poles->ColLength() ) {
1528 Standard_OutOfRange::Raise();
1530 if (CPoles.Lower() < 1 || CPoles.Lower() > poles->RowLength() ||
1531 CPoles.Upper() < 1 || CPoles.Upper() > poles->RowLength() ) {
1532 Standard_ConstructionError::Raise();
1535 TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1537 for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
1538 Poles (UIndex+Poles.LowerRow()-1, I+Poles.LowerCol()-1) = CPoles (I);
1542 //=======================================================================
1543 //function : SetPoleRow
1545 //=======================================================================
1547 void Geom_BSplineSurface::SetPoleRow(const Standard_Integer UIndex,
1548 const TColgp_Array1OfPnt & CPoles,
1549 const TColStd_Array1OfReal& CPoleWeights)
1551 SetPoleRow (UIndex, CPoles);
1552 SetWeightRow(UIndex, CPoleWeights);
1555 //=======================================================================
1556 //function : SetPole
1558 //=======================================================================
1560 void Geom_BSplineSurface::SetPole (const Standard_Integer UIndex,
1561 const Standard_Integer VIndex,
1564 poles->SetValue (UIndex+poles->LowerRow()-1, VIndex+poles->LowerCol()-1, P);
1567 //=======================================================================
1568 //function : SetPole
1570 //=======================================================================
1572 void Geom_BSplineSurface::SetPole (const Standard_Integer UIndex,
1573 const Standard_Integer VIndex,
1575 const Standard_Real Weight)
1577 SetWeight(UIndex, VIndex, Weight);
1578 SetPole (UIndex, VIndex, P);
1581 //=======================================================================
1582 //function : MovePoint
1584 //=======================================================================
1586 void Geom_BSplineSurface::MovePoint(const Standard_Real U,
1587 const Standard_Real V,
1589 const Standard_Integer UIndex1,
1590 const Standard_Integer UIndex2,
1591 const Standard_Integer VIndex1,
1592 const Standard_Integer VIndex2,
1593 Standard_Integer& UFirstModifiedPole,
1594 Standard_Integer& ULastmodifiedPole,
1595 Standard_Integer& VFirstModifiedPole,
1596 Standard_Integer& VLastmodifiedPole)
1598 if (UIndex1 < 1 || UIndex1 > poles->UpperRow() ||
1599 UIndex2 < 1 || UIndex2 > poles->UpperRow() || UIndex1 > UIndex2 ||
1600 VIndex1 < 1 || VIndex1 > poles->UpperCol() ||
1601 VIndex2 < 1 || VIndex2 > poles->UpperCol() || VIndex1 > VIndex2) {
1602 Standard_OutOfRange::Raise();
1605 TColgp_Array2OfPnt npoles(1, poles->UpperRow(), 1, poles->UpperCol());
1608 gp_Vec Displ(P0, P);
1609 Standard_Boolean rational = (urational || vrational);
1610 BSplSLib::MovePoint(U, V, Displ, UIndex1, UIndex2, VIndex1, VIndex2, udeg, vdeg,
1611 rational, poles->Array2(), weights->Array2(),
1612 ufknots->Array1(), vfknots->Array1(),
1613 UFirstModifiedPole, ULastmodifiedPole,
1614 VFirstModifiedPole, VLastmodifiedPole,
1616 if (UFirstModifiedPole) {
1617 poles->ChangeArray2() = npoles;
1622 //=======================================================================
1625 //=======================================================================
1627 void Geom_BSplineSurface::Bounds (Standard_Real& U1,
1630 Standard_Real& V2) const
1632 U1 = ufknots->Value (udeg+1);
1633 U2 = ufknots->Value (ufknots->Upper()-udeg);
1634 V1 = vfknots->Value (vdeg+1);
1635 V2 = vfknots->Value (vfknots->Upper()-vdeg);
1638 //=======================================================================
1639 //function : MaxDegree
1641 //=======================================================================
1643 Standard_Integer Geom_BSplineSurface::MaxDegree ()
1645 return BSplCLib::MaxDegree();
1648 //=======================================================================
1649 //function : IsURational
1651 //=======================================================================
1653 Standard_Boolean Geom_BSplineSurface::IsURational () const
1658 //=======================================================================
1659 //function : IsVRational
1661 //=======================================================================
1663 Standard_Boolean Geom_BSplineSurface::IsVRational () const
1668 //=======================================================================
1669 //function : Continuity
1671 //=======================================================================
1673 GeomAbs_Shape Geom_BSplineSurface::Continuity () const
1675 return ((Usmooth < Vsmooth) ? Usmooth : Vsmooth) ;
1678 //=======================================================================
1679 //function : NbUKnots
1681 //=======================================================================
1683 Standard_Integer Geom_BSplineSurface::NbUKnots () const
1685 return uknots->Length();
1688 //=======================================================================
1689 //function : NbUPoles
1691 //=======================================================================
1693 Standard_Integer Geom_BSplineSurface::NbUPoles () const
1695 return poles->ColLength();
1698 //=======================================================================
1699 //function : NbVKnots
1701 //=======================================================================
1703 Standard_Integer Geom_BSplineSurface::NbVKnots () const
1705 return vknots->Length();
1708 //=======================================================================
1709 //function : NbVPoles
1711 //=======================================================================
1713 Standard_Integer Geom_BSplineSurface::NbVPoles () const
1715 return poles->RowLength();
1718 //=======================================================================
1719 //function : UDegree
1721 //=======================================================================
1723 Standard_Integer Geom_BSplineSurface::UDegree () const
1728 //=======================================================================
1729 //function : VDegree
1731 //=======================================================================
1733 Standard_Integer Geom_BSplineSurface::VDegree () const
1738 //=======================================================================
1739 //function : UKnotDistribution
1741 //=======================================================================
1743 GeomAbs_BSplKnotDistribution Geom_BSplineSurface::UKnotDistribution() const
1749 //=======================================================================
1750 //function : VKnotDistribution
1752 //=======================================================================
1754 GeomAbs_BSplKnotDistribution Geom_BSplineSurface::VKnotDistribution() const
1759 //=======================================================================
1760 //function : InsertUKnots
1762 //=======================================================================
1764 void Geom_BSplineSurface::InsertUKnots
1765 (const TColStd_Array1OfReal& Knots,
1766 const TColStd_Array1OfInteger& Mults,
1767 const Standard_Real ParametricTolerance,
1768 const Standard_Boolean Add)
1770 // Check and compute new sizes
1771 Standard_Integer nbpoles, nbknots;
1773 if ( !BSplCLib::PrepareInsertKnots(udeg,uperiodic,
1774 uknots->Array1(),umults->Array1(),
1775 Knots,&Mults,nbpoles,nbknots,
1776 ParametricTolerance,Add))
1777 Standard_ConstructionError::Raise("Geom_BSplineSurface::InsertUKnots");
1779 if ( nbpoles == poles->ColLength()) return;
1781 Handle(TColgp_HArray2OfPnt) npoles
1782 = new TColgp_HArray2OfPnt(1,nbpoles, 1,poles->RowLength());
1783 Handle(TColStd_HArray2OfReal) nweights =
1784 new TColStd_HArray2OfReal(1,nbpoles,
1785 1,poles->RowLength(),
1787 Handle(TColStd_HArray1OfReal) nknots = uknots;
1788 Handle(TColStd_HArray1OfInteger) nmults = umults;
1790 if ( nbknots != uknots->Length()) {
1791 nknots = new TColStd_HArray1OfReal(1,nbknots);
1792 nmults = new TColStd_HArray1OfInteger(1,nbknots);
1795 if ( urational || vrational) {
1796 BSplSLib::InsertKnots(Standard_True,
1798 poles->Array2() , &weights->Array2(),
1799 uknots->Array1(), umults->Array1(),
1801 npoles->ChangeArray2(),
1802 &nweights->ChangeArray2(),
1803 nknots->ChangeArray1(), nmults->ChangeArray1(),
1804 ParametricTolerance, Add);
1807 BSplSLib::InsertKnots(Standard_True,
1809 poles->Array2() , BSplSLib::NoWeights(),
1810 uknots->Array1(), umults->Array1(),
1812 npoles->ChangeArray2(),
1813 BSplSLib::NoWeights(),
1814 nknots->ChangeArray1(), nmults->ChangeArray1(),
1815 ParametricTolerance, Add);
1826 //=======================================================================
1827 //function : InsertVKnots
1829 //=======================================================================
1831 void Geom_BSplineSurface::InsertVKnots
1832 (const TColStd_Array1OfReal& Knots,
1833 const TColStd_Array1OfInteger& Mults,
1834 const Standard_Real ParametricTolerance,
1835 const Standard_Boolean Add)
1837 // Check and compute new sizes
1838 Standard_Integer nbpoles, nbknots;
1840 if ( !BSplCLib::PrepareInsertKnots(vdeg,vperiodic,
1841 vknots->Array1(),vmults->Array1(),
1842 Knots,&Mults,nbpoles,nbknots,
1843 ParametricTolerance, Add))
1844 Standard_ConstructionError::Raise("Geom_BSplineSurface::InsertVKnots");
1846 if ( nbpoles == poles->RowLength()) return;
1848 Handle(TColgp_HArray2OfPnt) npoles
1849 = new TColgp_HArray2OfPnt(1,poles->ColLength(), 1,nbpoles);
1850 Handle(TColStd_HArray2OfReal) nweights =
1851 new TColStd_HArray2OfReal(1,poles->ColLength(),
1854 Handle(TColStd_HArray1OfReal) nknots = vknots;
1855 Handle(TColStd_HArray1OfInteger) nmults = vmults;
1857 if ( nbknots != vknots->Length()) {
1858 nknots = new TColStd_HArray1OfReal(1,nbknots);
1859 nmults = new TColStd_HArray1OfInteger(1,nbknots);
1862 if ( urational || vrational) {
1863 BSplSLib::InsertKnots(Standard_False,
1865 poles->Array2() , &weights->Array2(),
1866 vknots->Array1(), vmults->Array1(),
1868 npoles->ChangeArray2(),
1869 &nweights->ChangeArray2(),
1870 nknots->ChangeArray1(), nmults->ChangeArray1(),
1871 ParametricTolerance, Add);
1874 BSplSLib::InsertKnots(Standard_False,
1876 poles->Array2() , BSplSLib::NoWeights(),
1877 vknots->Array1(), vmults->Array1(),
1879 npoles->ChangeArray2(),
1880 BSplSLib::NoWeights(),
1881 nknots->ChangeArray1(), nmults->ChangeArray1(),
1882 ParametricTolerance, Add);
1893 //=======================================================================
1894 //function : RemoveUKnot
1896 //=======================================================================
1898 Standard_Boolean Geom_BSplineSurface::RemoveUKnot
1899 (const Standard_Integer Index,
1900 const Standard_Integer M,
1901 const Standard_Real Tolerance)
1903 if ( M < 0 ) return Standard_True;
1905 Standard_Integer I1 = FirstUKnotIndex ();
1906 Standard_Integer I2 = LastUKnotIndex ();
1908 if ( !uperiodic && (Index <= I1 || Index >= I2) ) {
1909 Standard_OutOfRange::Raise();
1911 else if ( uperiodic && (Index < I1 || Index > I2)) {
1912 Standard_OutOfRange::Raise();
1915 const TColgp_Array2OfPnt & oldpoles = poles->Array2();
1917 Standard_Integer step = umults->Value(Index) - M;
1918 if (step <= 0 ) return Standard_True;
1920 Handle(TColgp_HArray2OfPnt) npoles =
1921 new TColgp_HArray2OfPnt( 1, oldpoles.ColLength() - step,
1922 1, oldpoles.RowLength());
1923 Handle(TColStd_HArray1OfReal) nknots = uknots;
1924 Handle(TColStd_HArray1OfInteger) nmults = umults;
1927 nknots = new TColStd_HArray1OfReal(1,uknots->Length()-1);
1928 nmults = new TColStd_HArray1OfInteger(1,uknots->Length()-1);
1930 Handle(TColStd_HArray2OfReal) nweights ;
1931 if (urational || vrational) {
1933 new TColStd_HArray2OfReal( 1, npoles->ColLength(),
1934 1, npoles->RowLength());
1935 if (!BSplSLib::RemoveKnot(Standard_True,
1936 Index,M,udeg,uperiodic,
1937 poles->Array2(),&weights->Array2(),
1938 uknots->Array1(),umults->Array1(),
1939 npoles->ChangeArray2(),
1940 &nweights->ChangeArray2(),
1941 nknots->ChangeArray1(),nmults->ChangeArray1(),
1943 return Standard_False;
1947 // sync the size of the weights
1950 new TColStd_HArray2OfReal(1, npoles->ColLength(),
1951 1, npoles->RowLength(),
1953 if (!BSplSLib::RemoveKnot(Standard_True,
1954 Index,M,udeg,uperiodic,
1955 poles->Array2(),BSplSLib::NoWeights(),
1956 uknots->Array1(),umults->Array1(),
1957 npoles->ChangeArray2(),
1958 BSplSLib::NoWeights(),
1959 nknots->ChangeArray1(),nmults->ChangeArray1(),
1961 return Standard_False;
1971 return Standard_True;
1974 //=======================================================================
1975 //function : RemoveVKnot
1977 //=======================================================================
1979 Standard_Boolean Geom_BSplineSurface::RemoveVKnot
1980 (const Standard_Integer Index,
1981 const Standard_Integer M,
1982 const Standard_Real Tolerance)
1984 if ( M < 0 ) return Standard_True;
1986 Standard_Integer I1 = FirstVKnotIndex ();
1987 Standard_Integer I2 = LastVKnotIndex ();
1989 if ( !vperiodic && (Index <= I1 || Index >= I2) ) {
1990 Standard_OutOfRange::Raise();
1992 else if ( vperiodic && (Index < I1 || Index > I2)) {
1993 Standard_OutOfRange::Raise();
1996 const TColgp_Array2OfPnt & oldpoles = poles->Array2();
1998 Standard_Integer step = vmults->Value(Index) - M;
1999 if (step <= 0 ) return Standard_True;
2001 Handle(TColgp_HArray2OfPnt) npoles =
2002 new TColgp_HArray2OfPnt( 1, oldpoles.ColLength(),
2003 1, oldpoles.RowLength() - step);
2004 Handle(TColStd_HArray1OfReal) nknots = vknots;
2005 Handle(TColStd_HArray1OfInteger) nmults = vmults;
2008 nknots = new TColStd_HArray1OfReal(1,vknots->Length()-1);
2009 nmults = new TColStd_HArray1OfInteger(1,vknots->Length()-1);
2011 Handle(TColStd_HArray2OfReal) nweights ;
2012 if (urational || vrational) {
2014 new TColStd_HArray2OfReal( 1, npoles->ColLength(),
2015 1, npoles->RowLength()) ;
2018 if (!BSplSLib::RemoveKnot(Standard_False,
2019 Index,M,vdeg,vperiodic,
2020 poles->Array2(),&weights->Array2(),
2021 vknots->Array1(),vmults->Array1(),
2022 npoles->ChangeArray2(),
2023 &nweights->ChangeArray2(),
2024 nknots->ChangeArray1(),nmults->ChangeArray1(),
2026 return Standard_False;
2030 // sync the size of the weights array
2033 new TColStd_HArray2OfReal(1, npoles->ColLength(),
2034 1, npoles->RowLength(),
2036 if (!BSplSLib::RemoveKnot(Standard_False,
2037 Index,M,vdeg,vperiodic,
2038 poles->Array2(),BSplSLib::NoWeights(),
2039 vknots->Array1(),vmults->Array1(),
2040 npoles->ChangeArray2(),
2041 BSplSLib::NoWeights(),
2042 nknots->ChangeArray1(),nmults->ChangeArray1(),
2044 return Standard_False;
2053 return Standard_True;
2056 //=======================================================================
2057 //function : Resolution
2059 //=======================================================================
2061 void Geom_BSplineSurface::Resolution( const Standard_Real Tolerance3D,
2062 Standard_Real& UTolerance,
2063 Standard_Real& VTolerance)
2066 BSplSLib::Resolution(poles ->Array2(),
2083 UTolerance = Tolerance3D * umaxderivinv;
2084 VTolerance = Tolerance3D * vmaxderivinv;