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
29 #include <Geom_BSplineSurface.jxx>
32 #include <BSplSLib.hxx>
33 #include <BSplCLib.hxx>
34 #include <Precision.hxx>
35 #include <TColgp_Array1OfXYZ.hxx>
37 #include <Geom_BSplineCurve.hxx>
39 #include <Geom_UndefinedDerivative.hxx>
40 #include <Standard_OutOfRange.hxx>
41 #include <Standard_RangeError.hxx>
42 #include <Standard_DomainError.hxx>
43 #include <Standard_DimensionError.hxx>
44 #include <Standard_ConstructionError.hxx>
45 #include <Standard_NotImplemented.hxx>
46 #include <Standard_Mutex.hxx>
48 #define POLES (poles->Array2())
49 #define WEIGHTS (weights->Array2())
50 #define UKNOTS (uknots->Array1())
51 #define VKNOTS (vknots->Array1())
52 #define UFKNOTS (ufknots->Array1())
53 #define VFKNOTS (vfknots->Array1())
54 #define FMULTS (BSplCLib::NoMults())
56 //=======================================================================
59 //=======================================================================
61 Standard_Boolean Geom_BSplineSurface::IsCNu
62 (const Standard_Integer N) const
64 Standard_RangeError_Raise_if (N < 0, " ");
66 case GeomAbs_CN : return Standard_True;
67 case GeomAbs_C0 : return N <= 0;
68 case GeomAbs_G1 : return N <= 0;
69 case GeomAbs_C1 : return N <= 1;
70 case GeomAbs_G2 : return N <= 1;
71 case GeomAbs_C2 : return N <= 2;
73 return N <= 3 ? Standard_True :
74 N <= udeg - BSplCLib::MaxKnotMult (umults->Array1(), umults->Lower() + 1, umults->Upper() - 1);
76 return Standard_False;
80 //=======================================================================
83 //=======================================================================
85 Standard_Boolean Geom_BSplineSurface::IsCNv
86 (const Standard_Integer N) const
88 Standard_RangeError_Raise_if (N < 0, " ");
91 case GeomAbs_CN : return Standard_True;
92 case GeomAbs_C0 : return N <= 0;
93 case GeomAbs_G1 : return N <= 0;
94 case GeomAbs_C1 : return N <= 1;
95 case GeomAbs_G2 : return N <= 1;
96 case GeomAbs_C2 : return N <= 2;
98 return N <= 3 ? Standard_True :
99 N <= vdeg - BSplCLib::MaxKnotMult (vmults->Array1(), vmults->Lower() + 1, vmults->Upper() - 1);
101 return Standard_False;
105 //=======================================================================
108 //=======================================================================
110 void Geom_BSplineSurface::D0(const Standard_Real U,
111 const Standard_Real V,
114 Standard_Real aNewU = U;
115 Standard_Real aNewV = V;
116 PeriodicNormalization(aNewU, aNewV);
118 BSplSLib::D0(aNewU,aNewV,0,0,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
119 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
123 //=======================================================================
126 //=======================================================================
128 void Geom_BSplineSurface::D1(const Standard_Real U,
129 const Standard_Real V,
134 Standard_Real aNewU = U;
135 Standard_Real aNewV = V;
136 PeriodicNormalization(aNewU, aNewV);
138 Standard_Integer uindex = 0, vindex = 0;
140 BSplCLib::LocateParameter(udeg, uknots->Array1(), umults->Array1(), U, uperiodic, uindex, aNewU);
141 uindex = BSplCLib::FlatIndex(udeg, uindex, umults->Array1(), uperiodic);
143 BSplCLib::LocateParameter(vdeg, vknots->Array1(), vmults->Array1(), V, vperiodic, vindex, aNewV);
144 vindex = BSplCLib::FlatIndex(vdeg, vindex, vmults->Array1(), vperiodic);
146 BSplSLib::D1(aNewU,aNewV,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
147 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
151 //=======================================================================
154 //=======================================================================
156 void Geom_BSplineSurface::D2 (const Standard_Real U,
157 const Standard_Real V,
165 Standard_Real aNewU = U;
166 Standard_Real aNewV = V;
167 PeriodicNormalization(aNewU, aNewV);
169 Standard_Integer uindex = 0, vindex = 0;
171 BSplCLib::LocateParameter(udeg, uknots->Array1(), umults->Array1(), U, uperiodic, uindex, aNewU);
172 uindex = BSplCLib::FlatIndex(udeg, uindex, umults->Array1(), uperiodic);
174 BSplCLib::LocateParameter(vdeg, vknots->Array1(), vmults->Array1(), V, vperiodic, vindex, aNewV);
175 vindex = BSplCLib::FlatIndex(vdeg, vindex, vmults->Array1(), vperiodic);
177 BSplSLib::D2(aNewU,aNewV,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
178 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
179 P, D1U, D1V, D2U, D2V, D2UV);
182 //=======================================================================
185 //=======================================================================
187 void Geom_BSplineSurface::D3 (const Standard_Real U,
188 const Standard_Real V,
200 BSplSLib::D3(U,V,0,0,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
201 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
202 P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
205 //=======================================================================
208 //=======================================================================
210 gp_Vec Geom_BSplineSurface::DN (const Standard_Real U,
211 const Standard_Real V,
212 const Standard_Integer Nu,
213 const Standard_Integer Nv ) const
216 BSplSLib::DN(U,V,Nu,Nv,0,0,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
217 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
222 //=======================================================================
223 //function : LocalValue
225 //=======================================================================
227 gp_Pnt Geom_BSplineSurface::LocalValue (const Standard_Real U,
228 const Standard_Real V,
229 const Standard_Integer FromUK1,
230 const Standard_Integer ToUK2,
231 const Standard_Integer FromVK1,
232 const Standard_Integer ToVK2) const
235 LocalD0(U,V,FromUK1,ToUK2,FromVK1,ToVK2,P);
239 //=======================================================================
242 //=======================================================================
244 void Geom_BSplineSurface::LocalD0 (const Standard_Real U,
245 const Standard_Real V,
246 const Standard_Integer FromUK1,
247 const Standard_Integer ToUK2,
248 const Standard_Integer FromVK1,
249 const Standard_Integer ToVK2,
252 Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2,
253 "Geom_BSplineSurface::LocalD0");
255 Standard_Real u = U, v = V;
256 Standard_Integer uindex = 0, vindex = 0;
258 BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2,
260 uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic);
262 BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2,
264 vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic);
266 // BSplSLib::D0(U,V,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
267 BSplSLib::D0(u,v,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
268 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
272 //=======================================================================
275 //=======================================================================
277 void Geom_BSplineSurface::LocalD1 (const Standard_Real U,
278 const Standard_Real V,
279 const Standard_Integer FromUK1,
280 const Standard_Integer ToUK2,
281 const Standard_Integer FromVK1,
282 const Standard_Integer ToVK2,
287 Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2,
288 "Geom_BSplineSurface::LocalD1");
290 Standard_Real u = U, v = V;
291 Standard_Integer uindex = 0, vindex = 0;
293 BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2,
295 uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic);
297 BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2,
299 vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic);
301 BSplSLib::D1(u,v,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
302 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
306 //=======================================================================
309 //=======================================================================
311 void Geom_BSplineSurface::LocalD2 (const Standard_Real U,
312 const Standard_Real V,
313 const Standard_Integer FromUK1,
314 const Standard_Integer ToUK2,
315 const Standard_Integer FromVK1,
316 const Standard_Integer ToVK2,
324 Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2,
325 "Geom_BSplineSurface::LocalD2");
327 Standard_Real u = U, v = V;
328 Standard_Integer uindex = 0, vindex = 0;
330 BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2,
332 uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic);
334 BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2,
336 vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic);
338 BSplSLib::D2(u,v,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
339 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
340 P,D1U,D1V,D2U,D2V,D2UV);
343 //=======================================================================
346 //=======================================================================
348 void Geom_BSplineSurface::LocalD3 (const Standard_Real U,
349 const Standard_Real V,
350 const Standard_Integer FromUK1,
351 const Standard_Integer ToUK2,
352 const Standard_Integer FromVK1,
353 const Standard_Integer ToVK2,
365 Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2,
366 "Geom_BSplineSurface::LocalD3");
368 Standard_Real u = U, v = V;
369 Standard_Integer uindex = 0, vindex = 0;
371 BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2,
373 uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic);
375 BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2,
377 vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic);
379 BSplSLib::D3(u,v,uindex,vindex,POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
380 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
381 P,D1U,D1V,D2U,D2V,D2UV,D3U,D3V,D3UUV,D3UVV);
384 //=======================================================================
387 //=======================================================================
389 gp_Vec Geom_BSplineSurface::LocalDN (const Standard_Real U,
390 const Standard_Real V,
391 const Standard_Integer FromUK1,
392 const Standard_Integer ToUK2,
393 const Standard_Integer FromVK1,
394 const Standard_Integer ToVK2,
395 const Standard_Integer Nu,
396 const Standard_Integer Nv) const
398 Standard_DomainError_Raise_if (FromUK1 == ToUK2 || FromVK1 == ToVK2,
399 "Geom_BSplineSurface::LocalDN");
401 Standard_Real u = U, v = V;
402 Standard_Integer uindex = 0, vindex = 0;
404 BSplCLib::LocateParameter(udeg, UFKNOTS, U, uperiodic,FromUK1,ToUK2,
406 uindex = BSplCLib::FlatIndex(udeg,uindex,umults->Array1(),uperiodic);
408 BSplCLib::LocateParameter(vdeg, VFKNOTS, V, vperiodic,FromVK1,ToVK2,
410 vindex = BSplCLib::FlatIndex(vdeg,vindex,vmults->Array1(),vperiodic);
413 BSplSLib::DN(u,v,Nu,Nv,uindex,vindex,
414 POLES,WEIGHTS,UFKNOTS,VFKNOTS,FMULTS,FMULTS,
415 udeg,vdeg,urational,vrational,uperiodic,vperiodic,
420 //=======================================================================
423 //=======================================================================
425 gp_Pnt Geom_BSplineSurface::Pole (const Standard_Integer UIndex,
426 const Standard_Integer VIndex) const
428 Standard_OutOfRange_Raise_if
429 (UIndex < 1 || UIndex > poles->ColLength() ||
430 VIndex < 1 || VIndex > poles->RowLength(), " ");
431 return poles->Value (UIndex, VIndex);
434 //=======================================================================
437 //=======================================================================
439 void Geom_BSplineSurface::Poles (TColgp_Array2OfPnt& P) const
441 Standard_DimensionError_Raise_if
442 (P.ColLength() != poles->ColLength() ||
443 P.RowLength() != poles->RowLength(), " ");
447 const TColgp_Array2OfPnt& Geom_BSplineSurface::Poles() const
449 return poles->Array2();
452 //=======================================================================
455 //=======================================================================
457 Handle(Geom_Curve) Geom_BSplineSurface::UIso (const Standard_Real U) const
459 TColgp_Array1OfPnt cpoles(1,poles->RowLength());
460 TColStd_Array1OfReal cweights(1,poles->RowLength());
462 Handle(Geom_BSplineCurve) C;
464 if ( urational || vrational) {
465 BSplSLib::Iso(U,Standard_True,POLES,WEIGHTS,UFKNOTS,FMULTS,udeg,uperiodic,
467 C = new Geom_BSplineCurve(cpoles,cweights,
473 BSplSLib::Iso(U,Standard_True,POLES,
474 *((TColStd_Array2OfReal*) NULL),
475 UFKNOTS,FMULTS,udeg,uperiodic,
477 C = new Geom_BSplineCurve(cpoles,
486 //=======================================================================
488 //purpose : If CheckRational=False, no try to make it non-rational
489 //=======================================================================
491 Handle(Geom_Curve) Geom_BSplineSurface::UIso (const Standard_Real U,
492 const Standard_Boolean CheckRational) const
494 TColgp_Array1OfPnt cpoles(1,poles->RowLength());
495 TColStd_Array1OfReal cweights(1,poles->RowLength());
497 Handle(Geom_BSplineCurve) C;
499 if ( urational || vrational) {
500 BSplSLib::Iso(U,Standard_True,POLES,WEIGHTS,UFKNOTS,FMULTS,udeg,uperiodic,
502 C = new Geom_BSplineCurve(cpoles,cweights,
509 BSplSLib::Iso(U,Standard_True,POLES,
510 *((TColStd_Array2OfReal*) NULL),
511 UFKNOTS,FMULTS,udeg,uperiodic,
513 C = new Geom_BSplineCurve(cpoles,
522 //=======================================================================
525 //=======================================================================
527 Standard_Real Geom_BSplineSurface::UKnot(const Standard_Integer UIndex) const
529 Standard_OutOfRange_Raise_if (UIndex < 1 || UIndex > uknots->Length(), " ");
530 return uknots->Value (UIndex);
533 //=======================================================================
536 //=======================================================================
538 Standard_Real Geom_BSplineSurface::VKnot(const Standard_Integer VIndex) const
540 Standard_OutOfRange_Raise_if (VIndex < 1 || VIndex > vknots->Length(), " ");
541 return vknots->Value (VIndex);
544 //=======================================================================
547 //=======================================================================
549 void Geom_BSplineSurface::UKnots (TColStd_Array1OfReal& Ku) const
551 Standard_DimensionError_Raise_if (Ku.Length() != uknots->Length(), " ");
552 Ku = uknots->Array1();
555 const TColStd_Array1OfReal& Geom_BSplineSurface::UKnots() const
557 return uknots->Array1();
560 //=======================================================================
563 //=======================================================================
565 void Geom_BSplineSurface::VKnots (TColStd_Array1OfReal& Kv) const
567 Standard_DimensionError_Raise_if (Kv.Length() != vknots->Length(), " ");
568 Kv = vknots->Array1();
571 const TColStd_Array1OfReal& Geom_BSplineSurface::VKnots() const
573 return vknots->Array1();
576 //=======================================================================
577 //function : UKnotSequence
579 //=======================================================================
581 void Geom_BSplineSurface::UKnotSequence (TColStd_Array1OfReal& Ku) const
583 Standard_DimensionError_Raise_if (Ku.Length() != ufknots->Length(), " ");
584 Ku = ufknots->Array1();
587 const TColStd_Array1OfReal& Geom_BSplineSurface::UKnotSequence() const
589 return ufknots->Array1();
592 //=======================================================================
593 //function : VKnotSequence
595 //=======================================================================
597 void Geom_BSplineSurface::VKnotSequence (TColStd_Array1OfReal& Kv) const
599 Standard_DimensionError_Raise_if (Kv.Length() != vfknots->Length(), " ");
600 Kv = vfknots->Array1();
603 const TColStd_Array1OfReal& Geom_BSplineSurface::VKnotSequence() const
605 return vfknots->Array1();
608 //=======================================================================
609 //function : UMultiplicity
611 //=======================================================================
613 Standard_Integer Geom_BSplineSurface::UMultiplicity
614 (const Standard_Integer UIndex) const
616 Standard_OutOfRange_Raise_if (UIndex < 1 || UIndex > umults->Length()," ");
617 return umults->Value (UIndex);
620 //=======================================================================
621 //function : UMultiplicities
623 //=======================================================================
625 void Geom_BSplineSurface::UMultiplicities (TColStd_Array1OfInteger& Mu) const
627 Standard_DimensionError_Raise_if (Mu.Length() != umults->Length(), " ");
628 Mu = umults->Array1();
631 const TColStd_Array1OfInteger& Geom_BSplineSurface::UMultiplicities() const
633 return umults->Array1();
636 //=======================================================================
639 //=======================================================================
641 Handle(Geom_Curve) Geom_BSplineSurface::VIso (const Standard_Real V) const
643 TColgp_Array1OfPnt cpoles(1,poles->ColLength());
644 TColStd_Array1OfReal cweights(1,poles->ColLength());
646 Handle(Geom_BSplineCurve) C;
648 if ( urational || vrational) {
649 BSplSLib::Iso(V,Standard_False,POLES,
651 VFKNOTS,FMULTS,vdeg,vperiodic,
653 C = new Geom_BSplineCurve(cpoles,cweights,
659 BSplSLib::Iso(V,Standard_False,POLES,
660 *((TColStd_Array2OfReal*) NULL),
661 VFKNOTS,FMULTS,vdeg,vperiodic,
663 C = new Geom_BSplineCurve(cpoles,
672 //=======================================================================
674 //purpose : If CheckRational=False, no try to make it non-rational
675 //=======================================================================
677 Handle(Geom_Curve) Geom_BSplineSurface::VIso (const Standard_Real V,
678 const Standard_Boolean CheckRational) const
680 TColgp_Array1OfPnt cpoles(1,poles->ColLength());
681 TColStd_Array1OfReal cweights(1,poles->ColLength());
683 Handle(Geom_BSplineCurve) C;
685 if ( urational || vrational) {
686 BSplSLib::Iso(V,Standard_False,POLES,
688 VFKNOTS,FMULTS,vdeg,vperiodic,
690 C = new Geom_BSplineCurve(cpoles,cweights,
697 BSplSLib::Iso(V,Standard_False,POLES,
698 *((TColStd_Array2OfReal*) NULL),
699 VFKNOTS,FMULTS,vdeg,vperiodic,
701 C = new Geom_BSplineCurve(cpoles,
710 //=======================================================================
711 //function : VMultiplicity
713 //=======================================================================
715 Standard_Integer Geom_BSplineSurface::VMultiplicity
716 (const Standard_Integer VIndex) const
718 Standard_OutOfRange_Raise_if (VIndex < 1 || VIndex > vmults->Length()," ");
719 return vmults->Value (VIndex);
722 //=======================================================================
723 //function : VMultiplicities
725 //=======================================================================
727 void Geom_BSplineSurface::VMultiplicities (TColStd_Array1OfInteger& Mv) const
729 Standard_DimensionError_Raise_if (Mv.Length() != vmults->Length(), " ");
730 Mv = vmults->Array1();
733 const TColStd_Array1OfInteger& Geom_BSplineSurface::VMultiplicities() const
735 return vmults->Array1();
738 //=======================================================================
741 //=======================================================================
743 Standard_Real Geom_BSplineSurface::Weight
744 (const Standard_Integer UIndex,
745 const Standard_Integer VIndex ) const
747 Standard_OutOfRange_Raise_if
748 (UIndex < 1 || UIndex > weights->ColLength() ||
749 VIndex < 1 || VIndex > weights->RowLength(), " ");
750 return weights->Value (UIndex, VIndex);
753 //=======================================================================
756 //=======================================================================
758 void Geom_BSplineSurface::Weights (TColStd_Array2OfReal& W) const
760 Standard_DimensionError_Raise_if
761 (W.ColLength() != weights->ColLength() ||
762 W.RowLength() != weights->RowLength(), " ");
763 W = weights->Array2();
766 const TColStd_Array2OfReal& Geom_BSplineSurface::Weights() const
768 if (urational || vrational)
769 return weights->Array2();
770 return BSplSLib::NoWeights();
773 //=======================================================================
774 //function : Transform
776 //=======================================================================
778 void Geom_BSplineSurface::Transform (const gp_Trsf& T)
780 TColgp_Array2OfPnt & VPoles = poles->ChangeArray2();
781 for (Standard_Integer j = VPoles.LowerCol(); j <= VPoles.UpperCol(); j++) {
782 for (Standard_Integer i = VPoles.LowerRow(); i <= VPoles.UpperRow(); i++) {
783 VPoles (i, j).Transform (T);
788 //=======================================================================
789 //function : SetUPeriodic
791 //=======================================================================
793 void Geom_BSplineSurface::SetUPeriodic ()
795 Standard_Integer i,j;
797 Standard_Integer first = FirstUKnotIndex();
798 Standard_Integer last = LastUKnotIndex();
800 Handle(TColStd_HArray1OfReal) tk = uknots;
801 TColStd_Array1OfReal cknots((uknots->Array1())(first),first,last);
802 uknots = new TColStd_HArray1OfReal(1,cknots.Length());
803 uknots->ChangeArray1() = cknots;
805 Handle(TColStd_HArray1OfInteger) tm = umults;
806 TColStd_Array1OfInteger cmults((umults->Array1())(first),first,last);
807 // Modified by Sergey KHROMOV - Mon Feb 10 10:59:00 2003 Begin
808 // cmults(first) = cmults(last) = Max( cmults(first), cmults(last));
809 cmults(first) = cmults(last) = Min(udeg, Max( cmults(first), cmults(last)));
810 // Modified by Sergey KHROMOV - Mon Feb 10 10:59:00 2003 End
811 umults = new TColStd_HArray1OfInteger(1,cmults.Length());
812 umults->ChangeArray1() = cmults;
814 // compute new number of poles;
815 Standard_Integer nbp = BSplCLib::NbPoles(udeg,Standard_True,cmults);
817 TColgp_Array2OfPnt cpoles(1,nbp,poles->LowerCol(),poles->UpperCol());
818 for (i = 1; i <= nbp; i++) {
819 for (j = poles->LowerCol(); j <= poles->UpperCol(); j++) {
820 cpoles(i,j) = poles->Value(i,j);
824 new TColgp_HArray2OfPnt(1,nbp,cpoles.LowerCol(),cpoles.UpperCol());
825 poles->ChangeArray2() = cpoles;
828 cweights(1,nbp,weights->LowerCol(),weights->UpperCol());
829 if (urational || vrational) {
830 for (i = 1; i <= nbp; i++) {
831 for (j = weights->LowerCol(); j <= weights->UpperCol(); j++) {
832 cweights(i,j) = weights->Value(i,j);
837 for (i = 1; i <= nbp; i++) {
838 for (j = weights->LowerCol(); j <= weights->UpperCol(); j++) {
844 TColStd_HArray2OfReal(1,nbp,cweights.LowerCol(),cweights.UpperCol());
845 weights->ChangeArray2() = cweights;
848 uperiodic = Standard_True;
854 //=======================================================================
855 //function : SetVPeriodic
857 //=======================================================================
859 void Geom_BSplineSurface::SetVPeriodic ()
861 Standard_Integer i,j;
863 Standard_Integer first = FirstVKnotIndex();
864 Standard_Integer last = LastVKnotIndex();
866 Handle(TColStd_HArray1OfReal) tk = vknots;
867 TColStd_Array1OfReal cknots((vknots->Array1())(first),first,last);
868 vknots = new TColStd_HArray1OfReal(1,cknots.Length());
869 vknots->ChangeArray1() = cknots;
872 Handle(TColStd_HArray1OfInteger) tm = vmults;
873 TColStd_Array1OfInteger cmults((vmults->Array1())(first),first,last);
874 // Modified by Sergey KHROMOV - Mon Feb 10 11:00:33 2003 Begin
875 // cmults(first) = cmults(last) = Max( cmults(first), cmults(last));
876 cmults(first) = cmults(last) = Min(vdeg, Max( cmults(first), cmults(last)));
877 // Modified by Sergey KHROMOV - Mon Feb 10 11:00:34 2003 End
878 vmults = new TColStd_HArray1OfInteger(1,cmults.Length());
879 vmults->ChangeArray1() = cmults;
881 // compute new number of poles;
882 Standard_Integer nbp = BSplCLib::NbPoles(vdeg,Standard_True,cmults);
884 TColgp_Array2OfPnt cpoles(poles->LowerRow(),poles->UpperRow(),1,nbp);
885 for (i = poles->LowerRow(); i <= poles->UpperRow(); i++) {
886 for (j = 1; j <= nbp; j++) {
887 cpoles(i,j) = poles->Value(i,j);
891 new TColgp_HArray2OfPnt(cpoles.LowerRow(),cpoles.UpperRow(),1,nbp);
892 poles->ChangeArray2() = cpoles;
894 if (urational || vrational) {
896 cweights(weights->LowerRow(),weights->UpperRow(),1,nbp);
897 for (i = weights->LowerRow(); i <= weights->UpperRow(); i++) {
898 for (j = 1; j <= nbp; j++) {
899 cweights(i,j) = weights->Value(i,j);
903 TColStd_HArray2OfReal(cweights.LowerRow(),cweights.UpperRow(),1,nbp);
904 weights->ChangeArray2() = cweights;
907 vperiodic = Standard_True;
913 //=======================================================================
914 //function : SetUOrigin
916 //=======================================================================
918 void Geom_BSplineSurface::SetUOrigin(const Standard_Integer Index)
920 Standard_NoSuchObject_Raise_if( !uperiodic,
921 "Geom_BSplineSurface::SetUOrigin");
923 Standard_Integer i,j,k;
924 Standard_Integer first = FirstUKnotIndex();
925 Standard_Integer last = LastUKnotIndex();
927 Standard_DomainError_Raise_if( (Index < first) || (Index > last),
928 "Geom_BSplineCurve::SetUOrigine");
930 Standard_Integer nbknots = uknots->Length();
931 Standard_Integer nbpoles = poles->ColLength();
933 Handle(TColStd_HArray1OfReal) nknots =
934 new TColStd_HArray1OfReal(1,nbknots);
935 TColStd_Array1OfReal& newknots = nknots->ChangeArray1();
937 Handle(TColStd_HArray1OfInteger) nmults =
938 new TColStd_HArray1OfInteger(1,nbknots);
939 TColStd_Array1OfInteger& newmults = nmults->ChangeArray1();
941 // set the knots and mults
942 Standard_Real period = uknots->Value(last) - uknots->Value(first);
944 for ( i = Index; i <= last ; i++) {
945 newknots(k) = uknots->Value(i);
946 newmults(k) = umults->Value(i);
949 for ( i = first+1; i <= Index; i++) {
950 newknots(k) = uknots->Value(i) + period;
951 newmults(k) = umults->Value(i);
955 Standard_Integer index = 1;
956 for (i = first+1; i <= Index; i++)
957 index += umults->Value(i);
959 // set the poles and weights
960 Standard_Integer nbvp = poles->RowLength();
961 Handle(TColgp_HArray2OfPnt) npoles =
962 new TColgp_HArray2OfPnt(1,nbpoles,1,nbvp);
963 Handle(TColStd_HArray2OfReal) nweights =
964 new TColStd_HArray2OfReal(1,nbpoles,1,nbvp);
965 TColgp_Array2OfPnt & newpoles = npoles->ChangeArray2();
966 TColStd_Array2OfReal & newweights = nweights->ChangeArray2();
967 first = poles->LowerRow();
968 last = poles->UpperRow();
969 if ( urational || vrational) {
971 for ( i = index; i <= last; i++) {
972 for ( j = 1; j <= nbvp; j++) {
973 newpoles(k,j) = poles->Value(i,j);
974 newweights(k,j) = weights->Value(i,j);
978 for ( i = first; i < index; i++) {
979 for ( j = 1; j <= nbvp; j++) {
980 newpoles(k,j) = poles->Value(i,j);
981 newweights(k,j) = weights->Value(i,j);
988 for ( i = index; i <= last; i++) {
989 for ( j = 1; j <= nbvp; j++) {
990 newpoles(k,j) = poles->Value(i,j);
994 for ( i = first; i < index; i++) {
995 for ( j = 1; j <= nbvp; j++) {
996 newpoles(k,j) = poles->Value(i,j);
1005 if (urational || vrational)
1011 //=======================================================================
1012 //function : SetVOrigin
1014 //=======================================================================
1016 void Geom_BSplineSurface::SetVOrigin(const Standard_Integer Index)
1018 Standard_NoSuchObject_Raise_if( !vperiodic,
1019 "Geom_BSplineSurface::SetVOrigin");
1021 Standard_Integer i,j,k;
1022 Standard_Integer first = FirstVKnotIndex();
1023 Standard_Integer last = LastVKnotIndex();
1025 Standard_DomainError_Raise_if( (Index < first) || (Index > last),
1026 "Geom_BSplineCurve::SetVOrigine");
1028 Standard_Integer nbknots = vknots->Length();
1029 Standard_Integer nbpoles = poles->RowLength();
1031 Handle(TColStd_HArray1OfReal) nknots =
1032 new TColStd_HArray1OfReal(1,nbknots);
1033 TColStd_Array1OfReal& newknots = nknots->ChangeArray1();
1035 Handle(TColStd_HArray1OfInteger) nmults =
1036 new TColStd_HArray1OfInteger(1,nbknots);
1037 TColStd_Array1OfInteger& newmults = nmults->ChangeArray1();
1039 // set the knots and mults
1040 Standard_Real period = vknots->Value(last) - vknots->Value(first);
1042 for ( i = Index; i <= last ; i++) {
1043 newknots(k) = vknots->Value(i);
1044 newmults(k) = vmults->Value(i);
1047 for ( i = first+1; i <= Index; i++) {
1048 newknots(k) = vknots->Value(i) + period;
1049 newmults(k) = vmults->Value(i);
1053 Standard_Integer index = 1;
1054 for (i = first+1; i <= Index; i++)
1055 index += vmults->Value(i);
1057 // set the poles and weights
1058 Standard_Integer nbup = poles->ColLength();
1059 Handle(TColgp_HArray2OfPnt) npoles =
1060 new TColgp_HArray2OfPnt(1,nbup,1,nbpoles);
1061 Handle(TColStd_HArray2OfReal) nweights =
1062 new TColStd_HArray2OfReal(1,nbup,1,nbpoles);
1063 TColgp_Array2OfPnt & newpoles = npoles->ChangeArray2();
1064 TColStd_Array2OfReal & newweights = nweights->ChangeArray2();
1065 first = poles->LowerCol();
1066 last = poles->UpperCol();
1067 if ( urational || vrational) {
1069 for ( j = index; j <= last; j++) {
1070 for ( i = 1; i <= nbup; i++) {
1071 newpoles(i,k) = poles->Value(i,j);
1072 newweights(i,k) = weights->Value(i,j);
1076 for ( j = first; j < index; j++) {
1077 for ( i = 1; i <= nbup; i++) {
1078 newpoles(i,k) = poles->Value(i,j);
1079 newweights(i,k) = weights->Value(i,j);
1086 for ( j = index; j <= last; j++) {
1087 for ( i = 1; i <= nbup; i++) {
1088 newpoles(i,k) = poles->Value(i,j);
1092 for ( j = first; j < index; j++) {
1093 for ( i = 1; i <= nbup; i++) {
1094 newpoles(i,k) = poles->Value(i,j);
1103 if (urational || vrational)
1109 //=======================================================================
1110 //function : SetUNotPeriodic
1112 //=======================================================================
1114 void Geom_BSplineSurface::SetUNotPeriodic ()
1117 Standard_Integer NbKnots, NbPoles;
1118 BSplCLib::PrepareUnperiodize( udeg, umults->Array1(), NbKnots, NbPoles);
1120 Handle(TColgp_HArray2OfPnt) npoles =
1121 new TColgp_HArray2OfPnt(1,NbPoles, 1, poles->RowLength());
1123 Handle(TColStd_HArray1OfReal) nknots
1124 = new TColStd_HArray1OfReal(1,NbKnots);
1126 Handle(TColStd_HArray1OfInteger) nmults
1127 = new TColStd_HArray1OfInteger(1,NbKnots);
1129 Handle(TColStd_HArray2OfReal) nweights = new TColStd_HArray2OfReal(1,NbPoles, 1, poles->RowLength(), 0);
1131 if ( urational || vrational) {
1133 BSplSLib::Unperiodize(Standard_True , udeg,
1134 umults->Array1() , uknots->Array1(),
1135 poles->Array2() , weights->Array2(),
1136 nmults->ChangeArray1(), nknots->ChangeArray1(),
1137 npoles->ChangeArray2(),
1138 nweights->ChangeArray2());
1142 BSplSLib::Unperiodize(Standard_True , udeg,
1143 umults->Array1() , uknots->Array1(),
1144 poles->Array2() , BSplSLib::NoWeights(),
1145 nmults->ChangeArray1(), nknots->ChangeArray1(),
1146 npoles->ChangeArray2(),
1147 *((TColStd_Array2OfReal*) NULL));
1153 uperiodic = Standard_False;
1161 //=======================================================================
1162 //function : SetVNotPeriodic
1164 //=======================================================================
1166 void Geom_BSplineSurface::SetVNotPeriodic ()
1169 Standard_Integer NbKnots, NbPoles;
1170 BSplCLib::PrepareUnperiodize( vdeg, vmults->Array1(), NbKnots, NbPoles);
1172 Handle(TColgp_HArray2OfPnt) npoles =
1173 new TColgp_HArray2OfPnt(1, poles->ColLength(), 1, NbPoles);
1175 Handle(TColStd_HArray1OfReal) nknots
1176 = new TColStd_HArray1OfReal(1,NbKnots);
1178 Handle(TColStd_HArray1OfInteger) nmults
1179 = new TColStd_HArray1OfInteger(1,NbKnots) ;
1181 Handle(TColStd_HArray2OfReal) nweights = new TColStd_HArray2OfReal(1, poles->ColLength(), 1, NbPoles, 0);
1183 if ( urational || vrational) {
1185 BSplSLib::Unperiodize(Standard_False , vdeg,
1186 vmults->Array1() , vknots->Array1(),
1187 poles->Array2() , weights->Array2(),
1188 nmults->ChangeArray1(), nknots->ChangeArray1(),
1189 npoles->ChangeArray2(),
1190 nweights->ChangeArray2());
1194 BSplSLib::Unperiodize(Standard_False , vdeg,
1195 vmults->Array1() , vknots->Array1(),
1196 poles->Array2() , BSplSLib::NoWeights(),
1197 nmults->ChangeArray1(), nknots->ChangeArray1(),
1198 npoles->ChangeArray2(),
1199 *((TColStd_Array2OfReal*) NULL));
1205 vperiodic = Standard_False;
1213 //=======================================================================
1214 //function : IsUClosed
1216 //=======================================================================
1218 Standard_Boolean Geom_BSplineSurface::IsUClosed () const
1221 return Standard_True;
1223 Standard_Real aU1, aU2, aV1, aV2;
1224 Bounds( aU1, aU2, aV1, aV2 );
1225 Handle(Geom_Curve) aCUF = UIso( aU1 );
1226 Handle(Geom_Curve) aCUL = UIso( aU2 );
1227 if(aCUF.IsNull() || aCUL.IsNull())
1228 return Standard_False;
1229 Handle(Geom_BSplineCurve) aBsF = Handle(Geom_BSplineCurve)::DownCast(aCUF);
1230 Handle(Geom_BSplineCurve) aBsL = Handle(Geom_BSplineCurve)::DownCast(aCUL);
1231 return (!aBsF.IsNull() && !aBsL.IsNull() && aBsF->IsEqual( aBsL, Precision::Confusion()) );
1234 //=======================================================================
1235 //function : IsVClosed
1237 //=======================================================================
1239 Standard_Boolean Geom_BSplineSurface::IsVClosed () const
1242 return Standard_True;
1244 Standard_Real aU1, aU2, aV1, aV2;
1245 Bounds( aU1, aU2, aV1, aV2 );
1246 Handle(Geom_Curve) aCVF = VIso( aV1 );
1247 Handle(Geom_Curve) aCVL = VIso( aV2 );
1248 if(aCVF.IsNull() || aCVL.IsNull())
1249 return Standard_False;
1250 Handle(Geom_BSplineCurve) aBsF = Handle(Geom_BSplineCurve)::DownCast(aCVF);
1251 Handle(Geom_BSplineCurve) aBsL = Handle(Geom_BSplineCurve)::DownCast(aCVL);
1252 return (!aBsF.IsNull() && !aBsL.IsNull() && aBsF->IsEqual(aBsL, Precision::Confusion()));
1255 //=======================================================================
1256 //function : IsUPeriodic
1258 //=======================================================================
1260 Standard_Boolean Geom_BSplineSurface::IsUPeriodic () const
1265 //=======================================================================
1266 //function : IsVPeriodic
1268 //=======================================================================
1270 Standard_Boolean Geom_BSplineSurface::IsVPeriodic () const
1275 //=======================================================================
1276 //function : FirstUKnotIndex
1278 //=======================================================================
1280 Standard_Integer Geom_BSplineSurface::FirstUKnotIndex () const
1282 if (uperiodic) return 1;
1283 else return BSplCLib::FirstUKnotIndex(udeg,umults->Array1());
1286 //=======================================================================
1287 //function : FirstVKnotIndex
1289 //=======================================================================
1291 Standard_Integer Geom_BSplineSurface::FirstVKnotIndex () const
1293 if (vperiodic) return 1;
1294 else return BSplCLib::FirstUKnotIndex(vdeg,vmults->Array1());
1297 //=======================================================================
1298 //function : LastUKnotIndex
1300 //=======================================================================
1302 Standard_Integer Geom_BSplineSurface::LastUKnotIndex() const
1304 if (uperiodic) return uknots->Length();
1305 else return BSplCLib::LastUKnotIndex(udeg,umults->Array1());
1308 //=======================================================================
1309 //function : LastVKnotIndex
1311 //=======================================================================
1313 Standard_Integer Geom_BSplineSurface::LastVKnotIndex() const
1315 if (vperiodic) return vknots->Length();
1316 else return BSplCLib::LastUKnotIndex(vdeg,vmults->Array1());
1319 //=======================================================================
1320 //function : LocateU
1322 //=======================================================================
1324 void Geom_BSplineSurface::LocateU
1325 (const Standard_Real U,
1326 const Standard_Real ParametricTolerance,
1327 Standard_Integer& I1,
1328 Standard_Integer& I2,
1329 const Standard_Boolean WithKnotRepetition ) const
1331 Standard_Real NewU =U, vbid = vknots->Value(1);
1332 Handle(TColStd_HArray1OfReal) TheKnots;
1333 if (WithKnotRepetition) TheKnots = ufknots;
1334 else TheKnots = uknots;
1336 PeriodicNormalization(NewU, vbid); //Attention a la periode
1338 const TColStd_Array1OfReal & Knots = TheKnots->Array1();
1339 Standard_Real UFirst = Knots (1);
1340 Standard_Real ULast = Knots (Knots.Length());
1341 Standard_Real PParametricTolerance = Abs(ParametricTolerance);
1342 if (Abs (NewU - UFirst) <= PParametricTolerance) {
1345 else if (Abs (NewU - ULast) <= PParametricTolerance) {
1346 I1 = I2 = Knots.Length();
1348 else if (NewU < UFirst) {
1352 else if (NewU > ULast) {
1353 I1 = Knots.Length();
1358 BSplCLib::Hunt (Knots, NewU, I1);
1359 while ( Abs( Knots(I1+1) - NewU) <= PParametricTolerance) I1++;
1360 if ( Abs( Knots(I1) - NewU) <= PParametricTolerance) {
1369 //=======================================================================
1370 //function : LocateV
1372 //=======================================================================
1374 void Geom_BSplineSurface::LocateV
1375 (const Standard_Real V,
1376 const Standard_Real ParametricTolerance,
1377 Standard_Integer& I1,
1378 Standard_Integer& I2,
1379 const Standard_Boolean WithKnotRepetition ) const
1381 Standard_Real NewV =V, ubid = uknots->Value(1);
1382 Handle(TColStd_HArray1OfReal) TheKnots;
1383 if (WithKnotRepetition) TheKnots = vfknots;
1384 else TheKnots = vknots;
1386 PeriodicNormalization(ubid, NewV); //Attention a la periode
1388 const TColStd_Array1OfReal & Knots = TheKnots->Array1();
1389 Standard_Real VFirst = Knots (1);
1390 Standard_Real VLast = Knots (Knots.Length());
1391 Standard_Real PParametricTolerance = Abs(ParametricTolerance);
1392 if (Abs (NewV - VFirst) <= PParametricTolerance) { I1 = I2 = 1; }
1393 else if (Abs (NewV - VLast) <= PParametricTolerance) {
1394 I1 = I2 = Knots.Length();
1396 else if (NewV < VFirst - PParametricTolerance) {
1400 else if (NewV > VLast + PParametricTolerance) {
1401 I1 = Knots.Length();
1406 BSplCLib::Hunt (Knots, NewV, I1);
1407 while ( Abs( Knots(I1+1) - NewV) <= PParametricTolerance) I1++;
1408 if ( Abs( Knots(I1) - NewV) <= PParametricTolerance) {
1417 //=======================================================================
1418 //function : UReverse
1420 //=======================================================================
1422 void Geom_BSplineSurface::UReverse ()
1424 BSplCLib::Reverse(umults->ChangeArray1());
1425 BSplCLib::Reverse(uknots->ChangeArray1());
1426 Standard_Integer last;
1428 last = ufknots->Upper() - udeg -1;
1430 last = poles->UpperRow();
1431 BSplSLib::Reverse(poles->ChangeArray2(),last,Standard_True);
1432 if (urational || vrational)
1433 BSplSLib::Reverse(weights->ChangeArray2(),last,Standard_True);
1437 //=======================================================================
1438 //function : UReversedParameter
1440 //=======================================================================
1442 Standard_Real Geom_BSplineSurface::UReversedParameter
1443 ( const Standard_Real U) const
1445 return ( uknots->Value( 1) + uknots->Value( uknots->Length()) - U);
1448 //=======================================================================
1449 //function : VReverse
1451 //=======================================================================
1453 void Geom_BSplineSurface::VReverse ()
1455 BSplCLib::Reverse(vmults->ChangeArray1());
1456 BSplCLib::Reverse(vknots->ChangeArray1());
1457 Standard_Integer last;
1459 last = vfknots->Upper() - vdeg -1;
1461 last = poles->UpperCol();
1462 BSplSLib::Reverse(poles->ChangeArray2(),last,Standard_False);
1463 if (urational || vrational)
1464 BSplSLib::Reverse(weights->ChangeArray2(),last,Standard_False);
1468 //=======================================================================
1469 //function : VReversedParameter
1471 //=======================================================================
1473 Standard_Real Geom_BSplineSurface::VReversedParameter
1474 ( const Standard_Real V) const
1476 return ( vknots->Value( 1) + vknots->Value( vknots->Length()) - V);
1479 //=======================================================================
1480 //function : SetPoleCol
1482 //=======================================================================
1484 void Geom_BSplineSurface::SetPoleCol (const Standard_Integer VIndex,
1485 const TColgp_Array1OfPnt& CPoles)
1487 if (VIndex < 1 || VIndex > poles->RowLength()) {
1488 Standard_OutOfRange::Raise();
1490 if (CPoles.Lower() < 1 || CPoles.Lower() > poles->ColLength() ||
1491 CPoles.Upper() < 1 || CPoles.Upper() > poles->ColLength()) {
1492 Standard_ConstructionError::Raise();
1495 TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1497 for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
1498 Poles (I+Poles.LowerRow()-1, VIndex+Poles.LowerCol()-1) = CPoles(I);
1502 //=======================================================================
1503 //function : SetPoleCol
1505 //=======================================================================
1507 void Geom_BSplineSurface::SetPoleCol (const Standard_Integer VIndex,
1508 const TColgp_Array1OfPnt& CPoles,
1509 const TColStd_Array1OfReal& CPoleWeights)
1511 SetPoleCol (VIndex, CPoles);
1512 SetWeightCol(VIndex, CPoleWeights);
1515 //=======================================================================
1516 //function : SetPoleRow
1518 //=======================================================================
1520 void Geom_BSplineSurface::SetPoleRow (const Standard_Integer UIndex,
1521 const TColgp_Array1OfPnt& CPoles)
1523 if (UIndex < 1 || UIndex > poles->ColLength() ) {
1524 Standard_OutOfRange::Raise();
1526 if (CPoles.Lower() < 1 || CPoles.Lower() > poles->RowLength() ||
1527 CPoles.Upper() < 1 || CPoles.Upper() > poles->RowLength() ) {
1528 Standard_ConstructionError::Raise();
1531 TColgp_Array2OfPnt & Poles = poles->ChangeArray2();
1533 for (Standard_Integer I = CPoles.Lower(); I <= CPoles.Upper(); I++) {
1534 Poles (UIndex+Poles.LowerRow()-1, I+Poles.LowerCol()-1) = CPoles (I);
1538 //=======================================================================
1539 //function : SetPoleRow
1541 //=======================================================================
1543 void Geom_BSplineSurface::SetPoleRow(const Standard_Integer UIndex,
1544 const TColgp_Array1OfPnt & CPoles,
1545 const TColStd_Array1OfReal& CPoleWeights)
1547 SetPoleRow (UIndex, CPoles);
1548 SetWeightRow(UIndex, CPoleWeights);
1551 //=======================================================================
1552 //function : SetPole
1554 //=======================================================================
1556 void Geom_BSplineSurface::SetPole (const Standard_Integer UIndex,
1557 const Standard_Integer VIndex,
1560 poles->SetValue (UIndex+poles->LowerRow()-1, VIndex+poles->LowerCol()-1, P);
1563 //=======================================================================
1564 //function : SetPole
1566 //=======================================================================
1568 void Geom_BSplineSurface::SetPole (const Standard_Integer UIndex,
1569 const Standard_Integer VIndex,
1571 const Standard_Real Weight)
1573 SetWeight(UIndex, VIndex, Weight);
1574 SetPole (UIndex, VIndex, P);
1577 //=======================================================================
1578 //function : MovePoint
1580 //=======================================================================
1582 void Geom_BSplineSurface::MovePoint(const Standard_Real U,
1583 const Standard_Real V,
1585 const Standard_Integer UIndex1,
1586 const Standard_Integer UIndex2,
1587 const Standard_Integer VIndex1,
1588 const Standard_Integer VIndex2,
1589 Standard_Integer& UFirstModifiedPole,
1590 Standard_Integer& ULastmodifiedPole,
1591 Standard_Integer& VFirstModifiedPole,
1592 Standard_Integer& VLastmodifiedPole)
1594 if (UIndex1 < 1 || UIndex1 > poles->UpperRow() ||
1595 UIndex2 < 1 || UIndex2 > poles->UpperRow() || UIndex1 > UIndex2 ||
1596 VIndex1 < 1 || VIndex1 > poles->UpperCol() ||
1597 VIndex2 < 1 || VIndex2 > poles->UpperCol() || VIndex1 > VIndex2) {
1598 Standard_OutOfRange::Raise();
1601 TColgp_Array2OfPnt npoles(1, poles->UpperRow(), 1, poles->UpperCol());
1604 gp_Vec Displ(P0, P);
1605 Standard_Boolean rational = (urational || vrational);
1606 BSplSLib::MovePoint(U, V, Displ, UIndex1, UIndex2, VIndex1, VIndex2, udeg, vdeg,
1607 rational, poles->Array2(), weights->Array2(),
1608 ufknots->Array1(), vfknots->Array1(),
1609 UFirstModifiedPole, ULastmodifiedPole,
1610 VFirstModifiedPole, VLastmodifiedPole,
1612 if (UFirstModifiedPole) {
1613 poles->ChangeArray2() = npoles;
1618 //=======================================================================
1621 //=======================================================================
1623 void Geom_BSplineSurface::Bounds (Standard_Real& U1,
1626 Standard_Real& V2) const
1628 U1 = ufknots->Value (udeg+1);
1629 U2 = ufknots->Value (ufknots->Upper()-udeg);
1630 V1 = vfknots->Value (vdeg+1);
1631 V2 = vfknots->Value (vfknots->Upper()-vdeg);
1634 //=======================================================================
1635 //function : MaxDegree
1637 //=======================================================================
1639 Standard_Integer Geom_BSplineSurface::MaxDegree ()
1641 return BSplCLib::MaxDegree();
1644 //=======================================================================
1645 //function : IsURational
1647 //=======================================================================
1649 Standard_Boolean Geom_BSplineSurface::IsURational () const
1654 //=======================================================================
1655 //function : IsVRational
1657 //=======================================================================
1659 Standard_Boolean Geom_BSplineSurface::IsVRational () const
1664 //=======================================================================
1665 //function : Continuity
1667 //=======================================================================
1669 GeomAbs_Shape Geom_BSplineSurface::Continuity () const
1671 return ((Usmooth < Vsmooth) ? Usmooth : Vsmooth) ;
1674 //=======================================================================
1675 //function : NbUKnots
1677 //=======================================================================
1679 Standard_Integer Geom_BSplineSurface::NbUKnots () const
1681 return uknots->Length();
1684 //=======================================================================
1685 //function : NbUPoles
1687 //=======================================================================
1689 Standard_Integer Geom_BSplineSurface::NbUPoles () const
1691 return poles->ColLength();
1694 //=======================================================================
1695 //function : NbVKnots
1697 //=======================================================================
1699 Standard_Integer Geom_BSplineSurface::NbVKnots () const
1701 return vknots->Length();
1704 //=======================================================================
1705 //function : NbVPoles
1707 //=======================================================================
1709 Standard_Integer Geom_BSplineSurface::NbVPoles () const
1711 return poles->RowLength();
1714 //=======================================================================
1715 //function : UDegree
1717 //=======================================================================
1719 Standard_Integer Geom_BSplineSurface::UDegree () const
1724 //=======================================================================
1725 //function : VDegree
1727 //=======================================================================
1729 Standard_Integer Geom_BSplineSurface::VDegree () const
1734 //=======================================================================
1735 //function : UKnotDistribution
1737 //=======================================================================
1739 GeomAbs_BSplKnotDistribution Geom_BSplineSurface::UKnotDistribution() const
1745 //=======================================================================
1746 //function : VKnotDistribution
1748 //=======================================================================
1750 GeomAbs_BSplKnotDistribution Geom_BSplineSurface::VKnotDistribution() const
1755 //=======================================================================
1756 //function : InsertUKnots
1758 //=======================================================================
1760 void Geom_BSplineSurface::InsertUKnots
1761 (const TColStd_Array1OfReal& Knots,
1762 const TColStd_Array1OfInteger& Mults,
1763 const Standard_Real ParametricTolerance,
1764 const Standard_Boolean Add)
1766 // Check and compute new sizes
1767 Standard_Integer nbpoles, nbknots;
1769 if ( !BSplCLib::PrepareInsertKnots(udeg,uperiodic,
1770 uknots->Array1(),umults->Array1(),
1771 Knots,Mults,nbpoles,nbknots,
1772 ParametricTolerance,Add))
1773 Standard_ConstructionError::Raise("Geom_BSplineSurface::InsertUKnots");
1775 if ( nbpoles == poles->ColLength()) return;
1777 Handle(TColgp_HArray2OfPnt) npoles
1778 = new TColgp_HArray2OfPnt(1,nbpoles, 1,poles->RowLength());
1779 Handle(TColStd_HArray2OfReal) nweights =
1780 new TColStd_HArray2OfReal(1,nbpoles,
1781 1,poles->RowLength(),
1783 Handle(TColStd_HArray1OfReal) nknots = uknots;
1784 Handle(TColStd_HArray1OfInteger) nmults = umults;
1786 if ( nbknots != uknots->Length()) {
1787 nknots = new TColStd_HArray1OfReal(1,nbknots);
1788 nmults = new TColStd_HArray1OfInteger(1,nbknots);
1791 if ( urational || vrational) {
1792 BSplSLib::InsertKnots(Standard_True,
1794 poles->Array2() , weights->Array2(),
1795 uknots->Array1(), umults->Array1(),
1797 npoles->ChangeArray2(),
1798 nweights->ChangeArray2(),
1799 nknots->ChangeArray1(), nmults->ChangeArray1(),
1800 ParametricTolerance, Add);
1803 BSplSLib::InsertKnots(Standard_True,
1805 poles->Array2() , BSplSLib::NoWeights(),
1806 uknots->Array1(), umults->Array1(),
1808 npoles->ChangeArray2(),
1809 *((TColStd_Array2OfReal*) NULL),
1810 nknots->ChangeArray1(), nmults->ChangeArray1(),
1811 ParametricTolerance, Add);
1822 //=======================================================================
1823 //function : InsertVKnots
1825 //=======================================================================
1827 void Geom_BSplineSurface::InsertVKnots
1828 (const TColStd_Array1OfReal& Knots,
1829 const TColStd_Array1OfInteger& Mults,
1830 const Standard_Real ParametricTolerance,
1831 const Standard_Boolean Add)
1833 // Check and compute new sizes
1834 Standard_Integer nbpoles, nbknots;
1836 if ( !BSplCLib::PrepareInsertKnots(vdeg,vperiodic,
1837 vknots->Array1(),vmults->Array1(),
1838 Knots,Mults,nbpoles,nbknots,
1839 ParametricTolerance, Add))
1840 Standard_ConstructionError::Raise("Geom_BSplineSurface::InsertVKnots");
1842 if ( nbpoles == poles->RowLength()) return;
1844 Handle(TColgp_HArray2OfPnt) npoles
1845 = new TColgp_HArray2OfPnt(1,poles->ColLength(), 1,nbpoles);
1846 Handle(TColStd_HArray2OfReal) nweights =
1847 new TColStd_HArray2OfReal(1,poles->ColLength(),
1850 Handle(TColStd_HArray1OfReal) nknots = vknots;
1851 Handle(TColStd_HArray1OfInteger) nmults = vmults;
1853 if ( nbknots != vknots->Length()) {
1854 nknots = new TColStd_HArray1OfReal(1,nbknots);
1855 nmults = new TColStd_HArray1OfInteger(1,nbknots);
1858 if ( urational || vrational) {
1859 BSplSLib::InsertKnots(Standard_False,
1861 poles->Array2() , weights->Array2(),
1862 vknots->Array1(), vmults->Array1(),
1864 npoles->ChangeArray2(),
1865 nweights->ChangeArray2(),
1866 nknots->ChangeArray1(), nmults->ChangeArray1(),
1867 ParametricTolerance, Add);
1870 BSplSLib::InsertKnots(Standard_False,
1872 poles->Array2() , BSplSLib::NoWeights(),
1873 vknots->Array1(), vmults->Array1(),
1875 npoles->ChangeArray2(),
1876 *((TColStd_Array2OfReal*) NULL),
1877 nknots->ChangeArray1(), nmults->ChangeArray1(),
1878 ParametricTolerance, Add);
1889 //=======================================================================
1890 //function : RemoveUKnot
1892 //=======================================================================
1894 Standard_Boolean Geom_BSplineSurface::RemoveUKnot
1895 (const Standard_Integer Index,
1896 const Standard_Integer M,
1897 const Standard_Real Tolerance)
1899 if ( M < 0 ) return Standard_True;
1901 Standard_Integer I1 = FirstUKnotIndex ();
1902 Standard_Integer I2 = LastUKnotIndex ();
1904 if ( !uperiodic && (Index <= I1 || Index >= I2) ) {
1905 Standard_OutOfRange::Raise();
1907 else if ( uperiodic && (Index < I1 || Index > I2)) {
1908 Standard_OutOfRange::Raise();
1911 const TColgp_Array2OfPnt & oldpoles = poles->Array2();
1913 Standard_Integer step = umults->Value(Index) - M;
1914 if (step <= 0 ) return Standard_True;
1916 Handle(TColgp_HArray2OfPnt) npoles =
1917 new TColgp_HArray2OfPnt( 1, oldpoles.ColLength() - step,
1918 1, oldpoles.RowLength());
1919 Handle(TColStd_HArray1OfReal) nknots = uknots;
1920 Handle(TColStd_HArray1OfInteger) nmults = umults;
1923 nknots = new TColStd_HArray1OfReal(1,uknots->Length()-1);
1924 nmults = new TColStd_HArray1OfInteger(1,uknots->Length()-1);
1926 Handle(TColStd_HArray2OfReal) nweights ;
1927 if (urational || vrational) {
1929 new TColStd_HArray2OfReal( 1, npoles->ColLength(),
1930 1, npoles->RowLength());
1931 if (!BSplSLib::RemoveKnot(Standard_True,
1932 Index,M,udeg,uperiodic,
1933 poles->Array2(),weights->Array2(),
1934 uknots->Array1(),umults->Array1(),
1935 npoles->ChangeArray2(),
1936 nweights->ChangeArray2(),
1937 nknots->ChangeArray1(),nmults->ChangeArray1(),
1939 return Standard_False;
1943 // sync the size of the weights
1946 new TColStd_HArray2OfReal(1, npoles->ColLength(),
1947 1, npoles->RowLength(),
1949 if (!BSplSLib::RemoveKnot(Standard_True,
1950 Index,M,udeg,uperiodic,
1951 poles->Array2(),BSplSLib::NoWeights(),
1952 uknots->Array1(),umults->Array1(),
1953 npoles->ChangeArray2(),
1954 *((TColStd_Array2OfReal*) NULL),
1955 nknots->ChangeArray1(),nmults->ChangeArray1(),
1957 return Standard_False;
1967 return Standard_True;
1970 //=======================================================================
1971 //function : RemoveVKnot
1973 //=======================================================================
1975 Standard_Boolean Geom_BSplineSurface::RemoveVKnot
1976 (const Standard_Integer Index,
1977 const Standard_Integer M,
1978 const Standard_Real Tolerance)
1980 if ( M < 0 ) return Standard_True;
1982 Standard_Integer I1 = FirstVKnotIndex ();
1983 Standard_Integer I2 = LastVKnotIndex ();
1985 if ( !vperiodic && (Index <= I1 || Index >= I2) ) {
1986 Standard_OutOfRange::Raise();
1988 else if ( vperiodic && (Index < I1 || Index > I2)) {
1989 Standard_OutOfRange::Raise();
1992 const TColgp_Array2OfPnt & oldpoles = poles->Array2();
1994 Standard_Integer step = vmults->Value(Index) - M;
1995 if (step <= 0 ) return Standard_True;
1997 Handle(TColgp_HArray2OfPnt) npoles =
1998 new TColgp_HArray2OfPnt( 1, oldpoles.ColLength(),
1999 1, oldpoles.RowLength() - step);
2000 Handle(TColStd_HArray1OfReal) nknots = vknots;
2001 Handle(TColStd_HArray1OfInteger) nmults = vmults;
2004 nknots = new TColStd_HArray1OfReal(1,vknots->Length()-1);
2005 nmults = new TColStd_HArray1OfInteger(1,vknots->Length()-1);
2007 Handle(TColStd_HArray2OfReal) nweights ;
2008 if (urational || vrational) {
2010 new TColStd_HArray2OfReal( 1, npoles->ColLength(),
2011 1, npoles->RowLength()) ;
2014 if (!BSplSLib::RemoveKnot(Standard_False,
2015 Index,M,vdeg,vperiodic,
2016 poles->Array2(),weights->Array2(),
2017 vknots->Array1(),vmults->Array1(),
2018 npoles->ChangeArray2(),
2019 nweights->ChangeArray2(),
2020 nknots->ChangeArray1(),nmults->ChangeArray1(),
2022 return Standard_False;
2026 // sync the size of the weights array
2029 new TColStd_HArray2OfReal(1, npoles->ColLength(),
2030 1, npoles->RowLength(),
2032 if (!BSplSLib::RemoveKnot(Standard_False,
2033 Index,M,vdeg,vperiodic,
2034 poles->Array2(),BSplSLib::NoWeights(),
2035 vknots->Array1(),vmults->Array1(),
2036 npoles->ChangeArray2(),
2037 *((TColStd_Array2OfReal*) NULL),
2038 nknots->ChangeArray1(),nmults->ChangeArray1(),
2040 return Standard_False;
2049 return Standard_True;
2052 //=======================================================================
2053 //function : Resolution
2055 //=======================================================================
2057 void Geom_BSplineSurface::Resolution( const Standard_Real Tolerance3D,
2058 Standard_Real& UTolerance,
2059 Standard_Real& VTolerance)
2062 BSplSLib::Resolution(poles ->Array2(),
2079 UTolerance = Tolerance3D * umaxderivinv;
2080 VTolerance = Tolerance3D * vmaxderivinv;