1 // Created on: 1991-08-26
3 // Copyright (c) 1991-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 // Modifed RLE Aug 93 - Complete rewrite
18 // xab 21-Mar-95 implemented cache mecanism
19 // pmn 25-09-96 Interpolation
20 // jct 25-09-96 : Correction de l'alloc de LocalArray dans RationalDerivative.
21 // pmn 07-10-96 : Correction de DN dans le cas rationnal.
22 // pmn 06-02-97 : Correction des poids dans RationalDerivative. (PRO700)
24 #include <BSplCLib.hxx>
25 #include <BSplSLib.hxx>
28 #include <math_Matrix.hxx>
29 #include <NCollection_LocalArray.hxx>
31 #include <Standard_ConstructionError.hxx>
32 #include <Standard_NotImplemented.hxx>
33 #include <TColgp_Array1OfXYZ.hxx>
34 #include <TColgp_Array2OfXYZ.hxx>
35 #include <TColStd_HArray1OfInteger.hxx>
37 // for null derivatives
38 static Standard_Real BSplSLib_zero[3] = {0.0, 0.0, 0.0};
40 //=======================================================================
41 //struct : BSplCLib_DataContainer
42 //purpose: Auxiliary structure providing buffers for poles and knots used in
43 // evaluation of bspline (allocated in the stack)
44 //=======================================================================
46 struct BSplSLib_DataContainer
48 BSplSLib_DataContainer (Standard_Integer UDegree, Standard_Integer VDegree)
50 (void)UDegree; (void)VDegree; // just to avoid compiler warning in Release mode
51 Standard_OutOfRange_Raise_if (UDegree > BSplCLib::MaxDegree() ||
52 VDegree > BSplCLib::MaxDegree() || BSplCLib::MaxDegree() > 25,
53 "BSplSLib: bspline degree is greater than maximum supported");
55 Standard_Real poles[4*(25+1)*(25+1)];
56 Standard_Real knots1[2*25];
57 Standard_Real knots2[2*25];
58 Standard_Real ders[48];
61 //**************************************************************************
63 //**************************************************************************
65 //=======================================================================
66 //function : RationalDerivative
67 //purpose : computes the rational derivatives when whe have the
68 // the derivatives of the homogeneous numerator and the
69 // the derivatives of the denominator
70 //=======================================================================
72 void BSplSLib::RationalDerivative(const Standard_Integer UDeg,
73 const Standard_Integer VDeg,
74 const Standard_Integer N,
75 const Standard_Integer M,
76 Standard_Real& HDerivatives,
77 Standard_Real& RDerivatives,
78 const Standard_Boolean All)
81 // if All is True all derivatives are computed. if Not only
82 // the requested N, M is computed
85 // let f(u,v) be a rational function = ------------------
89 // Let (N,M) the order of the derivatives we want : then since
92 // Numerator = f * Denominator
96 // (N,M) 1 ( (N M) (p q) (N -p M-q) )
97 // f = ------------ ( Numerator - SUM SUM a * f * Denominator )
98 // (0,0) ( p<N q<M p q )
108 // HDerivatives is an array where derivatives are stored in the following form
109 // Numerator is assumee to have 3 functions that is a vector of dimension
112 // (0,0) (0,0) (0, DegV) (0, DegV)
113 // Numerator Denominator ... Numerator Denominator
115 // (1,0) (1,0) (1, DegV) (1, DegV)
116 // Numerator Denominator ... Numerator Denominator
118 // ...........................................................
121 // (DegU,0) (DegU,0) (DegU, DegV) (DegU, DegV)
122 // Numerator Denominator ... Numerator Denominator
125 Standard_Integer ii,jj,pp,qq,index,index1,index2;
126 Standard_Integer M1,M3,M4,N1,iiM1,iiM3,jjM1,ppM1,ppM3;
127 Standard_Integer MinN,MinN1,MinM,MinM1;
128 Standard_Integer index_u,index_u1,index_v,index_v1,index_w;
134 M4 = (VDeg + 1) << 2;
136 NCollection_LocalArray<Standard_Real> StoreDerivatives (All ? 0 : ii * 3);
137 Standard_Real *RArray = (All ? &RDerivatives : (Standard_Real*)StoreDerivatives);
138 NCollection_LocalArray<Standard_Real> StoreW (ii);
139 Standard_Real *HomogeneousArray = &HDerivatives;
140 Standard_Real denominator,Pii,Pip,Pjq;
142 denominator = 1.0e0 / HomogeneousArray[3];
145 if (UDeg < N) MinN = UDeg;
147 if (VDeg < M) MinM = VDeg;
153 for (ii = 0 ; ii < MinN1 ; ii++) {
159 for (jj = 0 ; jj < MinM1 ; jj++) {
160 RArray[index_v++] = HomogeneousArray[index_v1++];
161 RArray[index_v++] = HomogeneousArray[index_v1++];
162 RArray[index_v++] = HomogeneousArray[index_v1++];
163 StoreW[index_w++] = HomogeneousArray[index_v1++];
166 for (jj = MinM1 ; jj < M1 ; jj++) {
167 RArray[index_v++] = 0.;
168 RArray[index_v++] = 0.;
169 RArray[index_v++] = 0.;
170 StoreW[index_w++] = 0.;
175 index_v = MinN1 * M3;
176 index_w = MinN1 * M1;
178 for (ii = MinN1 ; ii < N1 ; ii++) {
180 for (jj = 0 ; jj < M1 ; jj++) {
181 RArray[index_v++] = 0.0e0;
182 RArray[index_v++] = 0.0e0;
183 RArray[index_v++] = 0.0e0;
184 StoreW[index_w++] = 0.0e0;
188 // --------------- Calculation ----------------
193 for (ii = 0 ; ii <= N ; ii++) {
199 for (jj = 0 ; jj <= M ; jj++) {
205 for (pp = 0 ; pp < ii ; pp++) {
209 index2 = jjM1 - ppM1;
210 Pip = PLib::Bin(ii,pp);
212 for (qq = 0 ; qq <= jj ; qq++) {
214 Pjq = Pip * PLib::Bin(jj,qq) * StoreW[index2];
215 RArray[index1] -= Pjq * RArray[index]; index++; index1++;
216 RArray[index1] -= Pjq * RArray[index]; index++; index1++;
217 RArray[index1] -= Pjq * RArray[index]; index++;
223 Pii = PLib::Bin(ii,ii);
225 for (qq = 0 ; qq < jj ; qq++) {
227 Pjq = Pii * PLib::Bin(jj,qq) * StoreW[index2];
228 RArray[index1] -= Pjq * RArray[index]; index++; index1++;
229 RArray[index1] -= Pjq * RArray[index]; index++; index1++;
230 RArray[index1] -= Pjq * RArray[index]; index++;
233 RArray[index1] *= denominator; index1++;
234 RArray[index1] *= denominator; index1++;
235 RArray[index1] *= denominator;
240 RArray = &RDerivatives;
242 index = (index << 1) + index;
243 RArray[0] = StoreDerivatives[index]; index++;
244 RArray[1] = StoreDerivatives[index]; index++;
245 RArray[2] = StoreDerivatives[index];
249 //=======================================================================
250 //function : PrepareEval
252 //=======================================================================
257 // Prepare all data for computing points :
258 // local arrays of knots
259 // local array of poles (multiplied by the weights if rational)
261 // The first direction to compute (smaller degree) is returned
262 // and the poles are stored according to this direction.
264 static Standard_Boolean PrepareEval (const Standard_Real U,
265 const Standard_Real V,
266 const Standard_Integer Uindex,
267 const Standard_Integer Vindex,
268 const Standard_Integer UDegree,
269 const Standard_Integer VDegree,
270 const Standard_Boolean URat,
271 const Standard_Boolean VRat,
272 const Standard_Boolean UPer,
273 const Standard_Boolean VPer,
274 const TColgp_Array2OfPnt& Poles,
275 const TColStd_Array2OfReal* Weights,
276 const TColStd_Array1OfReal& UKnots,
277 const TColStd_Array1OfReal& VKnots,
278 const TColStd_Array1OfInteger* UMults,
279 const TColStd_Array1OfInteger* VMults,
280 Standard_Real& u1, // first parameter to use
281 Standard_Real& u2, // second parameter to use
282 Standard_Integer& d1, // first degree
283 Standard_Integer& d2, // second degree
284 Standard_Boolean& rational,
285 BSplSLib_DataContainer& dc)
287 rational = URat || VRat;
288 Standard_Integer uindex = Uindex;
289 Standard_Integer vindex = Vindex;
290 Standard_Integer UKLower = UKnots.Lower();
291 Standard_Integer UKUpper = UKnots.Upper();
292 Standard_Integer VKLower = VKnots.Lower();
293 Standard_Integer VKUpper = VKnots.Upper();
295 if (UDegree <= VDegree)
297 // compute the indices
298 if (uindex < UKLower || uindex > UKUpper)
299 BSplCLib::LocateParameter(UDegree,UKnots,UMults,U,UPer,uindex,u1);
303 if (vindex < VKLower || vindex > VKUpper)
304 BSplCLib::LocateParameter(VDegree,VKnots,VMults,V,VPer,vindex,u2);
311 BSplCLib::BuildKnots(UDegree,uindex,UPer,UKnots,UMults,*dc.knots1);
312 BSplCLib::BuildKnots(VDegree,vindex,VPer,VKnots,VMults,*dc.knots2);
315 uindex -= UKLower + UDegree;
317 uindex = BSplCLib::PoleIndex(UDegree,uindex,UPer,*UMults);
320 vindex -= VKLower + VDegree;
322 vindex = BSplCLib::PoleIndex(VDegree,vindex,VPer,*VMults);
325 Standard_Integer i,j,ip,jp;
326 Standard_Real w, *pole = dc.poles;
329 Standard_Integer PLowerRow = Poles.LowerRow();
330 Standard_Integer PUpperRow = Poles.UpperRow();
331 Standard_Integer PLowerCol = Poles.LowerCol();
332 Standard_Integer PUpperCol = Poles.UpperCol();
334 // verify if locally non rational
337 rational = Standard_False;
338 ip = PLowerRow + uindex;
339 jp = PLowerCol + vindex;
341 if(ip < PLowerRow) ip = PUpperRow;
342 if(jp < PLowerCol) jp = PUpperCol;
344 w = Weights->Value(ip,jp);
345 Standard_Real eps = Epsilon(w);
348 for (i = 0; i <= UDegree && !rational; i++)
350 jp = PLowerCol + vindex;
355 for (j = 0; j <= VDegree && !rational; j++)
357 dw = Weights->Value(ip,jp) - w;
361 rational = (dw > eps);
378 ip = PLowerRow + uindex;
385 for (i = 0; i <= d1; i++)
387 jp = PLowerCol + vindex;
392 for (j = 0; j <= d2; j++)
394 const gp_Pnt& P = Poles .Value(ip,jp);
395 pole[3] = w = Weights->Value(ip,jp);
415 for (i = 0; i <= d1; i++)
417 jp = PLowerCol + vindex;
422 for (j = 0; j <= d2; j++)
424 const gp_Pnt& P = Poles.Value(ip,jp);
442 return Standard_True;
446 // compute the indices
447 if (uindex < UKLower || uindex > UKUpper)
448 BSplCLib::LocateParameter(UDegree,UKnots,UMults,U,UPer,uindex,u2);
452 if (vindex < VKLower || vindex > VKUpper)
453 BSplCLib::LocateParameter(VDegree,VKnots,VMults,V,VPer,vindex,u1);
462 BSplCLib::BuildKnots(UDegree,uindex,UPer,UKnots,UMults,*dc.knots2);
463 BSplCLib::BuildKnots(VDegree,vindex,VPer,VKnots,VMults,*dc.knots1);
466 uindex -= UKLower + UDegree;
468 uindex = BSplCLib::PoleIndex(UDegree,uindex,UPer,*UMults);
471 vindex -= VKLower + VDegree;
473 vindex = BSplCLib::PoleIndex(VDegree,vindex,VPer,*VMults);
476 Standard_Integer i,j,ip,jp;
477 Standard_Real w, *pole = dc.poles;
480 Standard_Integer PLowerRow = Poles.LowerRow();
481 Standard_Integer PUpperRow = Poles.UpperRow();
482 Standard_Integer PLowerCol = Poles.LowerCol();
483 Standard_Integer PUpperCol = Poles.UpperCol();
485 // verify if locally non rational
488 rational = Standard_False;
489 ip = PLowerRow + uindex;
490 jp = PLowerCol + vindex;
498 w = Weights->Value(ip,jp);
499 Standard_Real eps = Epsilon(w);
502 for (i = 0; i <= UDegree && !rational; i++)
504 jp = PLowerCol + vindex;
509 for (j = 0; j <= VDegree && !rational; j++)
511 dw = Weights->Value(ip,jp) - w;
512 if (dw < 0) dw = - dw;
530 jp = PLowerCol + vindex;
537 for (i = 0; i <= d1; i++)
539 ip = PLowerRow + uindex;
544 for (j = 0; j <= d2; j++)
546 const gp_Pnt& P = Poles.Value(ip,jp);
547 pole[3] = w = Weights->Value(ip,jp);
568 for (i = 0; i <= d1; i++)
570 ip = PLowerRow + uindex;
578 for (j = 0; j <= d2; j++)
580 const gp_Pnt& P = Poles.Value(ip,jp);
599 return Standard_False;
603 //=======================================================================
606 //=======================================================================
609 (const Standard_Real U,
610 const Standard_Real V,
611 const Standard_Integer UIndex,
612 const Standard_Integer VIndex,
613 const TColgp_Array2OfPnt& Poles,
614 const TColStd_Array2OfReal* Weights,
615 const TColStd_Array1OfReal& UKnots,
616 const TColStd_Array1OfReal& VKnots,
617 const TColStd_Array1OfInteger* UMults,
618 const TColStd_Array1OfInteger* VMults,
619 const Standard_Integer UDegree,
620 const Standard_Integer VDegree,
621 const Standard_Boolean URat,
622 const Standard_Boolean VRat,
623 const Standard_Boolean UPer,
624 const Standard_Boolean VPer,
627 // Standard_Integer k ;
652 //=======================================================================
655 //=======================================================================
657 void BSplSLib::HomogeneousD0
658 (const Standard_Real U,
659 const Standard_Real V,
660 const Standard_Integer UIndex,
661 const Standard_Integer VIndex,
662 const TColgp_Array2OfPnt& Poles,
663 const TColStd_Array2OfReal* Weights,
664 const TColStd_Array1OfReal& UKnots,
665 const TColStd_Array1OfReal& VKnots,
666 const TColStd_Array1OfInteger* UMults,
667 const TColStd_Array1OfInteger* VMults,
668 const Standard_Integer UDegree,
669 const Standard_Integer VDegree,
670 const Standard_Boolean URat,
671 const Standard_Boolean VRat,
672 const Standard_Boolean UPer,
673 const Standard_Boolean VPer,
677 Standard_Boolean rational;
678 // Standard_Integer k,dim;
679 Standard_Integer dim;
681 Standard_Integer d1,d2;
684 BSplSLib_DataContainer dc (UDegree, VDegree);
685 PrepareEval(U,V,UIndex,VIndex,UDegree,VDegree,URat,VRat,UPer,VPer,
686 Poles,Weights,UKnots,VKnots,UMults,VMults,
687 u1,u2,d1,d2,rational,dc);
690 BSplCLib::Eval(u1,d1,*dc.knots1,dim * (d2 + 1),*dc.poles);
691 BSplCLib::Eval(u2,d2,*dc.knots2,dim,*dc.poles);
699 BSplCLib::Eval(u1,d1,*dc.knots1,dim * (d2 + 1),*dc.poles);
700 BSplCLib::Eval(u2,d2,*dc.knots2,dim,*dc.poles);
707 //=======================================================================
710 //=======================================================================
713 (const Standard_Real U,
714 const Standard_Real V,
715 const Standard_Integer UIndex,
716 const Standard_Integer VIndex,
717 const TColgp_Array2OfPnt& Poles,
718 const TColStd_Array2OfReal* Weights,
719 const TColStd_Array1OfReal& UKnots,
720 const TColStd_Array1OfReal& VKnots,
721 const TColStd_Array1OfInteger* UMults,
722 const TColStd_Array1OfInteger* VMults,
723 const Standard_Integer UDegree,
724 const Standard_Integer VDegree,
725 const Standard_Boolean URat,
726 const Standard_Boolean VRat,
727 const Standard_Boolean UPer,
728 const Standard_Boolean VPer,
733 Standard_Boolean rational;
734 // Standard_Integer k,dim,dim2;
735 Standard_Integer dim,dim2;
737 Standard_Integer d1,d2;
738 Standard_Real *result, *resVu, *resVv;
739 BSplSLib_DataContainer dc (UDegree, VDegree);
741 (U,V,UIndex,VIndex,UDegree,VDegree,URat,VRat,UPer,VPer,
742 Poles,Weights,UKnots,VKnots,UMults,VMults,
743 u1,u2,d1,d2,rational,dc)) {
746 dim2 = (d2 + 1) << 2;
747 BSplCLib::Bohm(u1,d1,1,*dc.knots1,dim2,*dc.poles);
748 BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*dc.poles);
749 BSplCLib::Eval(u2,d2, *dc.knots2,dim ,*(dc.poles + dim2));
750 BSplSLib::RationalDerivative(d1,d2,1,1,*dc.poles,*dc.ders);
758 dim2 = (dim2 << 1) + dim2;
759 BSplCLib::Bohm(u1,d1,1,*dc.knots1,dim2,*dc.poles);
760 BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*dc.poles);
761 BSplCLib::Eval(u2,d2, *dc.knots2,dim ,*(dc.poles + dim2));
763 resVu = result + dim2;
770 dim2 = (d2 + 1) << 2;
771 BSplCLib::Bohm(u1,d1,1,*dc.knots1,dim2,*dc.poles);
772 BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*dc.poles);
773 BSplCLib::Eval(u2,d2, *dc.knots2,dim ,*(dc.poles + dim2));
774 BSplSLib::RationalDerivative(d1,d2,1,1,*dc.poles,*dc.ders);
782 dim2 = (dim2 << 1) + dim2;
783 BSplCLib::Bohm(u1,d1,1,*dc.knots1,dim2,*dc.poles);
784 BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*dc.poles);
785 BSplCLib::Eval(u2,d2 ,*dc.knots2,dim ,*(dc.poles + dim2));
788 resVv = result + dim2;
805 //=======================================================================
808 //=======================================================================
810 void BSplSLib::HomogeneousD1
811 (const Standard_Real U,
812 const Standard_Real V,
813 const Standard_Integer UIndex,
814 const Standard_Integer VIndex,
815 const TColgp_Array2OfPnt& Poles,
816 const TColStd_Array2OfReal* Weights,
817 const TColStd_Array1OfReal& UKnots,
818 const TColStd_Array1OfReal& VKnots,
819 const TColStd_Array1OfInteger* UMults,
820 const TColStd_Array1OfInteger* VMults,
821 const Standard_Integer UDegree,
822 const Standard_Integer VDegree,
823 const Standard_Boolean URat,
824 const Standard_Boolean VRat,
825 const Standard_Boolean UPer,
826 const Standard_Boolean VPer,
834 Standard_Boolean rational;
835 // Standard_Integer k,dim;
836 Standard_Integer dim;
838 Standard_Integer d1,d2;
843 BSplSLib_DataContainer dc (UDegree, VDegree);
844 Standard_Boolean ufirst = PrepareEval
845 (U,V,UIndex,VIndex,UDegree,VDegree,URat,VRat,UPer,VPer,
846 Poles,Weights,UKnots,VKnots,UMults,VMults,
847 u1,u2,d1,d2,rational,dc);
848 dim = rational ? 4 : 3;
850 BSplCLib::Bohm(u1,d1,1,*dc.knots1,dim * (d2 + 1),*dc.poles);
851 BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim,*dc.poles);
852 BSplCLib::Eval(u2,d2,*dc.knots2,dim,*(dc.poles+dim*(d2+1)));
854 Standard_Real *result, *resVu, *resVv;
856 resVu = result + (ufirst ? dim*(d2+1) : dim);
857 resVv = result + (ufirst ? dim : dim*(d2+1));
878 //=======================================================================
881 //=======================================================================
884 (const Standard_Real U,
885 const Standard_Real V,
886 const Standard_Integer UIndex,
887 const Standard_Integer VIndex,
888 const TColgp_Array2OfPnt& Poles,
889 const TColStd_Array2OfReal* Weights,
890 const TColStd_Array1OfReal& UKnots,
891 const TColStd_Array1OfReal& VKnots,
892 const TColStd_Array1OfInteger* UMults,
893 const TColStd_Array1OfInteger* VMults,
894 const Standard_Integer UDegree,
895 const Standard_Integer VDegree,
896 const Standard_Boolean URat,
897 const Standard_Boolean VRat,
898 const Standard_Boolean UPer,
899 const Standard_Boolean VPer,
907 Standard_Boolean rational;
908 // Standard_Integer k,dim,dim2;
909 Standard_Integer dim,dim2;
911 Standard_Integer d1,d2;
912 Standard_Real *result, *resVu, *resVv, *resVuu, *resVvv, *resVuv;
913 BSplSLib_DataContainer dc (UDegree, VDegree);
915 (U,V,UIndex,VIndex,UDegree,VDegree,URat,VRat,UPer,VPer,
916 Poles,Weights,UKnots,VKnots,UMults,VMults,
917 u1,u2,d1,d2,rational,dc)) {
920 dim2 = (d2 + 1) << 2;
921 BSplCLib::Bohm(u1,d1,2,*dc.knots1,dim2,*dc.poles);
922 BSplCLib::Bohm(u2,d2,2,*dc.knots2,dim ,*dc.poles);
923 BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*(dc.poles + dim2));
925 BSplCLib::Eval(u2,d2,*dc.knots2,dim ,*(dc.poles + (dim2 << 1)));
926 BSplSLib::RationalDerivative(d1,d2,2,2,*dc.poles,*dc.ders);
930 resVuu = result + 18;
932 resVuv = result + 12;
937 dim2 = (dim2 << 1) + dim2;
938 BSplCLib::Bohm(u1,d1,2,*dc.knots1,dim2,*dc.poles);
939 BSplCLib::Bohm(u2,d2,2,*dc.knots2,dim ,*dc.poles);
940 BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*(dc.poles + dim2));
942 BSplCLib::Eval(u2,d2,*dc.knots2,dim ,*(dc.poles + (dim2 << 1)));
944 resVu = result + dim2;
946 if (UDegree <= 1) resVuu = BSplSLib_zero;
947 else resVuu = result + (dim2 << 1);
948 if (VDegree <= 1) resVvv = BSplSLib_zero;
949 else resVvv = result + 6;
950 resVuv = result + (d2 << 1) + d2 + 6;
956 dim2 = (d2 + 1) << 2;
957 BSplCLib::Bohm(u1,d1,2,*dc.knots1,dim2,*dc.poles);
958 BSplCLib::Bohm(u2,d2,2,*dc.knots2,dim ,*dc.poles);
959 BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*(dc.poles + dim2));
961 BSplCLib::Eval(u2,d2,*dc.knots2,dim ,*(dc.poles + (dim2 << 1)));
962 BSplSLib::RationalDerivative(d1,d2,2,2,*dc.poles,*dc.ders);
967 resVvv = result + 18;
968 resVuv = result + 12;
973 dim2 = (dim2 << 1) + dim2;
974 BSplCLib::Bohm(u1,d1,2,*dc.knots1,dim2,*dc.poles);
975 BSplCLib::Bohm(u2,d2,2,*dc.knots2,dim ,*dc.poles);
976 BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*(dc.poles + dim2));
978 BSplCLib::Eval(u2,d2,*dc.knots2,dim ,*(dc.poles + (dim2 << 1)));
981 resVv = result + dim2;
982 if (UDegree <= 1) resVuu = BSplSLib_zero;
983 else resVuu = result + 6;
984 if (VDegree <= 1) resVvv = BSplSLib_zero;
985 else resVvv = result + (dim2 << 1);
986 resVuv = result + (d2 << 1) + d2 + 6;
1000 Vuu.SetY(resVuu[1]);
1001 Vvv.SetY(resVvv[1]);
1002 Vuv.SetY(resVuv[1]);
1005 Vu .SetZ(resVu [2]);
1006 Vv .SetZ(resVv [2]);
1007 Vuu.SetZ(resVuu[2]);
1008 Vvv.SetZ(resVvv[2]);
1009 Vuv.SetZ(resVuv[2]);
1012 //=======================================================================
1015 //=======================================================================
1018 (const Standard_Real U,
1019 const Standard_Real V,
1020 const Standard_Integer UIndex,
1021 const Standard_Integer VIndex,
1022 const TColgp_Array2OfPnt& Poles,
1023 const TColStd_Array2OfReal* Weights,
1024 const TColStd_Array1OfReal& UKnots,
1025 const TColStd_Array1OfReal& VKnots,
1026 const TColStd_Array1OfInteger* UMults,
1027 const TColStd_Array1OfInteger* VMults,
1028 const Standard_Integer UDegree,
1029 const Standard_Integer VDegree,
1030 const Standard_Boolean URat,
1031 const Standard_Boolean VRat,
1032 const Standard_Boolean UPer,
1033 const Standard_Boolean VPer,
1045 Standard_Boolean rational;
1046 // Standard_Integer k,dim,dim2;
1047 Standard_Integer dim,dim2;
1048 Standard_Real u1,u2;
1049 Standard_Integer d1,d2;
1050 Standard_Real *result, *resVu, *resVv, *resVuu, *resVvv, *resVuv,
1051 *resVuuu, *resVvvv, *resVuuv, *resVuvv;
1052 BSplSLib_DataContainer dc (UDegree, VDegree);
1054 (U,V,UIndex,VIndex,UDegree,VDegree,URat,VRat,UPer,VPer,
1055 Poles,Weights,UKnots,VKnots,UMults,VMults,
1056 u1,u2,d1,d2,rational,dc)) {
1059 dim2 = (d2 + 1) << 2;
1060 BSplCLib::Bohm (u1,d1,3,*dc.knots1,dim2,*dc.poles);
1061 BSplCLib::Bohm (u2,d2,3,*dc.knots2,dim ,*dc.poles);
1062 BSplCLib::Bohm (u2,d2,2,*dc.knots2,dim ,*(dc.poles + dim2));
1064 BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*(dc.poles + (dim2 << 1)));
1066 BSplCLib::Eval(u2,d2 ,*dc.knots2,dim ,*(dc.poles + (dim2 << 1) + dim2));
1067 BSplSLib::RationalDerivative(d1,d2,3,3,*dc.poles,*dc.ders);
1069 resVu = result + 12;
1071 resVuu = result + 24;
1072 resVvv = result + 6;
1073 resVuv = result + 15;
1074 resVuuu = result + 36;
1075 resVvvv = result + 9;
1076 resVuuv = result + 27;
1077 resVuvv = result + 18;
1082 dim2 = (dim2 << 1) + dim2;
1083 BSplCLib::Bohm (u1,d1,3,*dc.knots1,dim2,*dc.poles);
1084 BSplCLib::Bohm (u2,d2,3,*dc.knots2,dim ,*dc.poles);
1085 BSplCLib::Bohm (u2,d2,2,*dc.knots2,dim ,*(dc.poles + dim2));
1087 BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*(dc.poles + (dim2 << 1)));
1089 BSplCLib::Eval(u2,d2 ,*dc.knots2,dim ,*(dc.poles + (dim2 << 1) + dim2));
1091 resVu = result + dim2;
1094 resVuu = BSplSLib_zero;
1095 resVuuv = BSplSLib_zero;
1098 resVuu = result + (dim2 << 1);
1099 resVuuv = result + (dim2 << 1) + 3;
1102 resVvv = BSplSLib_zero;
1103 resVuvv = BSplSLib_zero;
1106 resVvv = result + 6;
1107 resVuvv = result + dim2 + 6;
1109 resVuv = result + (d2 << 1) + d2 + 6;
1110 if (UDegree <= 2) resVuuu = BSplSLib_zero;
1111 else resVuuu = result + (dim2 << 1) + dim2;
1112 if (VDegree <= 2) resVvvv = BSplSLib_zero;
1113 else resVvvv = result + 9;
1119 dim2 = (d2 + 1) << 2;
1120 BSplCLib::Bohm (u1,d1,3,*dc.knots1,dim2,*dc.poles);
1121 BSplCLib::Bohm (u2,d2,3,*dc.knots2,dim ,*dc.poles);
1122 BSplCLib::Bohm (u2,d2,2,*dc.knots2,dim ,*(dc.poles + dim2));
1124 BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*(dc.poles + (dim2 << 1)));
1126 BSplCLib::Eval(u2,d2 ,*dc.knots2,dim ,*(dc.poles + (dim2 << 1) + dim2));
1127 BSplSLib::RationalDerivative(d1,d2,3,3,*dc.poles,*dc.ders);
1130 resVv = result + 12;
1131 resVuu = result + 6;
1132 resVvv = result + 24;
1133 resVuv = result + 15;
1134 resVuuu = result + 9;
1135 resVvvv = result + 36;
1136 resVuuv = result + 18;
1137 resVuvv = result + 27;
1142 dim2 = (dim2 << 1) + dim2;
1143 BSplCLib::Bohm (u1,d1,3,*dc.knots1,dim2,*dc.poles);
1144 BSplCLib::Bohm (u2,d2,3,*dc.knots2,dim ,*dc.poles);
1145 BSplCLib::Bohm (u2,d2,2,*dc.knots2,dim ,*(dc.poles + dim2));
1147 BSplCLib::Bohm(u2,d2,1,*dc.knots2,dim ,*(dc.poles + (dim2 << 1)));
1149 BSplCLib::Eval(u2,d2 ,*dc.knots2,dim ,*(dc.poles + (dim2 << 1) + dim2));
1152 resVv = result + dim2;
1154 resVuu = BSplSLib_zero;
1155 resVuuv = BSplSLib_zero;
1158 resVuu = result + 6;
1159 resVuuv = result + dim2 + 6;
1162 resVvv = BSplSLib_zero;
1163 resVuvv = BSplSLib_zero;
1166 resVvv = result + (dim2 << 1);
1167 resVuvv = result + (dim2 << 1) + 3;
1169 resVuv = result + (d2 << 1) + d2 + 6;
1170 if (UDegree <= 2) resVuuu = BSplSLib_zero;
1171 else resVuuu = result + 9;
1172 if (VDegree <= 2) resVvvv = BSplSLib_zero;
1173 else resVvvv = result + (dim2 << 1) + dim2;
1177 P .SetX(result [0]);
1178 Vu .SetX(resVu [0]);
1179 Vv .SetX(resVv [0]);
1180 Vuu .SetX(resVuu [0]);
1181 Vvv .SetX(resVvv [0]);
1182 Vuv .SetX(resVuv [0]);
1183 Vuuu.SetX(resVuuu[0]);
1184 Vvvv.SetX(resVvvv[0]);
1185 Vuuv.SetX(resVuuv[0]);
1186 Vuvv.SetX(resVuvv[0]);
1188 P .SetY(result [1]);
1189 Vu .SetY(resVu [1]);
1190 Vv .SetY(resVv [1]);
1191 Vuu .SetY(resVuu [1]);
1192 Vvv .SetY(resVvv [1]);
1193 Vuv .SetY(resVuv [1]);
1194 Vuuu.SetY(resVuuu[1]);
1195 Vvvv.SetY(resVvvv[1]);
1196 Vuuv.SetY(resVuuv[1]);
1197 Vuvv.SetY(resVuvv[1]);
1199 P .SetZ(result [2]);
1200 Vu .SetZ(resVu [2]);
1201 Vv .SetZ(resVv [2]);
1202 Vuu .SetZ(resVuu [2]);
1203 Vvv .SetZ(resVvv [2]);
1204 Vuv .SetZ(resVuv [2]);
1205 Vuuu.SetZ(resVuuu[2]);
1206 Vvvv.SetZ(resVvvv[2]);
1207 Vuuv.SetZ(resVuuv[2]);
1208 Vuvv.SetZ(resVuvv[2]);
1211 //=======================================================================
1214 //=======================================================================
1217 (const Standard_Real U,
1218 const Standard_Real V,
1219 const Standard_Integer Nu,
1220 const Standard_Integer Nv,
1221 const Standard_Integer UIndex,
1222 const Standard_Integer VIndex,
1223 const TColgp_Array2OfPnt& Poles,
1224 const TColStd_Array2OfReal* Weights,
1225 const TColStd_Array1OfReal& UKnots,
1226 const TColStd_Array1OfReal& VKnots,
1227 const TColStd_Array1OfInteger* UMults,
1228 const TColStd_Array1OfInteger* VMults,
1229 const Standard_Integer UDegree,
1230 const Standard_Integer VDegree,
1231 const Standard_Boolean URat,
1232 const Standard_Boolean VRat,
1233 const Standard_Boolean UPer,
1234 const Standard_Boolean VPer,
1237 Standard_Boolean rational;
1238 Standard_Integer k,dim;
1239 Standard_Real u1,u2;
1240 Standard_Integer d1,d2;
1242 BSplSLib_DataContainer dc (UDegree, VDegree);
1243 Standard_Boolean ufirst = PrepareEval
1244 (U,V,UIndex,VIndex,UDegree,VDegree,URat,VRat,UPer,VPer,
1245 Poles,Weights,UKnots,VKnots,UMults,VMults,
1246 u1,u2,d1,d2,rational,dc);
1247 dim = rational ? 4 : 3;
1250 if ((Nu > UDegree) || (Nv > VDegree)) {
1258 Standard_Integer n1 = ufirst ? Nu : Nv;
1259 Standard_Integer n2 = ufirst ? Nv : Nu;
1261 BSplCLib::Bohm(u1,d1,n1,*dc.knots1,dim * (d2 + 1),*dc.poles);
1263 for (k = 0; k <= Min(n1,d1); k++)
1264 BSplCLib::Bohm(u2,d2,n2,*dc.knots2,dim,*(dc.poles+k*dim*(d2+1)));
1266 Standard_Real *result;
1268 BSplSLib::RationalDerivative(d1,d2,n1,n2,*dc.poles,*dc.ders,Standard_False);
1269 result = dc.ders; // because Standard_False ci-dessus.
1273 result = dc.poles + (n1 * (d2+1) + n2) * dim ;
1282 // Surface modifications
1284 // a surface is processed as a curve of curves.
1285 // i.e : a curve of parameter u where the current point is the set of poles
1289 //=======================================================================
1292 //=======================================================================
1294 void BSplSLib::Iso(const Standard_Real Param,
1295 const Standard_Boolean IsU,
1296 const TColgp_Array2OfPnt& Poles,
1297 const TColStd_Array2OfReal* Weights,
1298 const TColStd_Array1OfReal& Knots,
1299 const TColStd_Array1OfInteger* Mults,
1300 const Standard_Integer Degree,
1301 const Standard_Boolean Periodic,
1302 TColgp_Array1OfPnt& CPoles,
1303 TColStd_Array1OfReal* CWeights)
1305 Standard_Integer index = 0;
1306 Standard_Real u = Param;
1307 Standard_Boolean rational = Weights != NULL;
1308 Standard_Integer dim = rational ? 4 : 3;
1310 // compute local knots
1312 NCollection_LocalArray<Standard_Real> locknots1 (2*Degree);
1313 BSplCLib::LocateParameter(Degree,Knots,Mults,u,Periodic,index,u);
1314 BSplCLib::BuildKnots(Degree,index,Periodic,Knots,Mults,*locknots1);
1316 index -= Knots.Lower() + Degree;
1318 index = BSplCLib::PoleIndex(Degree,index,Periodic,*Mults);
1321 // copy the local poles
1323 // Standard_Integer f1,l1,f2,l2,i,j,k;
1324 Standard_Integer f1,l1,f2,l2,i,j;
1327 f1 = Poles.LowerRow();
1328 l1 = Poles.UpperRow();
1329 f2 = Poles.LowerCol();
1330 l2 = Poles.UpperCol();
1333 f1 = Poles.LowerCol();
1334 l1 = Poles.UpperCol();
1335 f2 = Poles.LowerRow();
1336 l2 = Poles.UpperRow();
1339 NCollection_LocalArray<Standard_Real> locpoles ((Degree+1) * (l2-f2+1) * dim);
1341 Standard_Real w, *pole = locpoles;
1344 for (i = 0; i <= Degree; i++) {
1346 for (j = f2; j <= l2; j++) {
1348 const gp_Pnt& P = IsU ? Poles(index,j) : Poles(j,index);
1350 pole[3] = w = IsU ? (*Weights)(index,j) : (*Weights)(j,index);
1351 pole[0] = P.X() * w;
1352 pole[1] = P.Y() * w;
1353 pole[2] = P.Z() * w;
1363 if (index > l1) index = f1;
1367 BSplCLib::Eval(u,Degree,*locknots1,(l2-f2+1)*dim,*locpoles);
1372 for (i = CPoles.Lower(); i <= CPoles.Upper(); i++) {
1373 gp_Pnt& P = CPoles(i);
1375 (*CWeights)(i) = w = pole[3];
1376 P.SetX( pole[0] / w);
1377 P.SetY( pole[1] / w);
1378 P.SetZ( pole[2] / w);
1388 // if the input is not rational but weights are wanted
1389 if (!rational && (CWeights != NULL)) {
1391 for (i = CWeights->Lower(); i <= CWeights->Upper(); i++)
1392 (*CWeights)(i) = 1.;
1396 //=======================================================================
1397 //function : Reverse
1399 //=======================================================================
1401 void BSplSLib::Reverse( TColgp_Array2OfPnt& Poles,
1402 const Standard_Integer Last,
1403 const Standard_Boolean UDirection)
1405 Standard_Integer i,j, l = Last;
1407 l = Poles.LowerRow() +
1408 (l - Poles.LowerRow())%(Poles.ColLength());
1409 TColgp_Array2OfPnt temp(0, Poles.ColLength()-1,
1410 Poles.LowerCol(), Poles.UpperCol());
1412 for (i = Poles.LowerRow(); i <= l; i++) {
1414 for (j = Poles.LowerCol(); j <= Poles.UpperCol(); j++) {
1415 temp(l-i,j) = Poles(i,j);
1419 for (i = l+1; i <= Poles.UpperRow(); i++) {
1421 for (j = Poles.LowerCol(); j <= Poles.UpperCol(); j++) {
1422 temp(l+Poles.ColLength()-i,j) = Poles(i,j);
1426 for (i = Poles.LowerRow(); i <= Poles.UpperRow(); i++) {
1428 for (j = Poles.LowerCol(); j <= Poles.UpperCol(); j++) {
1429 Poles(i,j) = temp (i-Poles.LowerRow(),j);
1434 l = Poles.LowerCol() +
1435 (l - Poles.LowerCol())%(Poles.RowLength());
1436 TColgp_Array2OfPnt temp(Poles.LowerRow(), Poles.UpperRow(),
1437 0, Poles.RowLength()-1);
1439 for (j = Poles.LowerCol(); j <= l; j++) {
1441 for (i = Poles.LowerRow(); i <= Poles.UpperRow(); i++) {
1442 temp(i,l-j) = Poles(i,j);
1446 for (j = l+1; j <= Poles.UpperCol(); j++) {
1448 for (i = Poles.LowerRow(); i <= Poles.UpperRow(); i++) {
1449 temp(i,l+Poles.RowLength()-j) = Poles(i,j);
1453 for (i = Poles.LowerRow(); i <= Poles.UpperRow(); i++) {
1455 for (j = Poles.LowerCol(); j <= Poles.UpperCol(); j++) {
1456 Poles(i,j) = temp (i,j-Poles.LowerCol());
1462 //=======================================================================
1463 //function : Reverse
1465 //=======================================================================
1467 void BSplSLib::Reverse( TColStd_Array2OfReal& Weights,
1468 const Standard_Integer Last,
1469 const Standard_Boolean UDirection)
1471 Standard_Integer i,j, l = Last;
1473 l = Weights.LowerRow() +
1474 (l - Weights.LowerRow())%(Weights.ColLength());
1475 TColStd_Array2OfReal temp(0, Weights.ColLength()-1,
1476 Weights.LowerCol(), Weights.UpperCol());
1478 for (i = Weights.LowerRow(); i <= l; i++) {
1480 for (j = Weights.LowerCol(); j <= Weights.UpperCol(); j++) {
1481 temp(l-i,j) = Weights(i,j);
1485 for (i = l+1; i <= Weights.UpperRow(); i++) {
1487 for (j = Weights.LowerCol(); j <= Weights.UpperCol(); j++) {
1488 temp(l+Weights.ColLength()-i,j) = Weights(i,j);
1492 for (i = Weights.LowerRow(); i <= Weights.UpperRow(); i++) {
1494 for (j = Weights.LowerCol(); j <= Weights.UpperCol(); j++) {
1495 Weights(i,j) = temp (i-Weights.LowerRow(),j);
1500 l = Weights.LowerCol() +
1501 (l - Weights.LowerCol())%(Weights.RowLength());
1502 TColStd_Array2OfReal temp(Weights.LowerRow(), Weights.UpperRow(),
1503 0, Weights.RowLength()-1);
1505 for (j = Weights.LowerCol(); j <= l; j++) {
1507 for (i = Weights.LowerRow(); i <= Weights.UpperRow(); i++) {
1508 temp(i,l-j) = Weights(i,j);
1512 for (j = l+1; j <= Weights.UpperCol(); j++) {
1514 for (i = Weights.LowerRow(); i <= Weights.UpperRow(); i++) {
1515 temp(i,l+Weights.RowLength()-j) = Weights(i,j);
1519 for (i = Weights.LowerRow(); i <= Weights.UpperRow(); i++) {
1521 for (j = Weights.LowerCol(); j <= Weights.UpperCol(); j++) {
1522 Weights(i,j) = temp (i,j-Weights.LowerCol());
1528 //=======================================================================
1529 //function : IsRational
1531 //=======================================================================
1533 Standard_Boolean BSplSLib::IsRational
1534 (const TColStd_Array2OfReal& Weights,
1535 const Standard_Integer I1,
1536 const Standard_Integer I2,
1537 const Standard_Integer J1,
1538 const Standard_Integer J2,
1539 const Standard_Real Epsi)
1541 Standard_Real eps = (Epsi > 0.0) ? Epsi : Epsilon(Weights(I1,I2));
1542 Standard_Integer i,j;
1543 Standard_Integer fi = Weights.LowerRow(), li = Weights.ColLength();
1544 Standard_Integer fj = Weights.LowerCol(), lj = Weights.RowLength();
1546 for (i = I1 - fi; i < I2 - fi; i++) {
1548 for (j = J1 - fj; j < J2 - fj; j++) {
1549 if (Abs(Weights(fi+i%li,fj+j%lj)-Weights(fi+(i+1)%li,fj+j%lj))>eps)
1550 return Standard_True;
1553 return Standard_False;
1556 //=======================================================================
1557 //function : SetPoles
1559 //=======================================================================
1561 void BSplSLib::SetPoles(const TColgp_Array2OfPnt& Poles,
1562 TColStd_Array1OfReal& FP,
1563 const Standard_Boolean UDirection)
1565 Standard_Integer i, j, l = FP.Lower();
1566 Standard_Integer PLowerRow = Poles.LowerRow();
1567 Standard_Integer PUpperRow = Poles.UpperRow();
1568 Standard_Integer PLowerCol = Poles.LowerCol();
1569 Standard_Integer PUpperCol = Poles.UpperCol();
1572 for ( i = PLowerRow; i <= PUpperRow; i++) {
1574 for ( j = PLowerCol; j <= PUpperCol; j++) {
1575 const gp_Pnt& P = Poles.Value(i,j);
1584 for ( j = PLowerCol; j <= PUpperCol; j++) {
1586 for ( i = PLowerRow; i <= PUpperRow; i++) {
1587 const gp_Pnt& P = Poles.Value(i,j);
1596 //=======================================================================
1597 //function : SetPoles
1599 //=======================================================================
1601 void BSplSLib::SetPoles(const TColgp_Array2OfPnt& Poles,
1602 const TColStd_Array2OfReal& Weights,
1603 TColStd_Array1OfReal& FP,
1604 const Standard_Boolean UDirection)
1606 Standard_Integer i, j, l = FP.Lower();
1607 Standard_Integer PLowerRow = Poles.LowerRow();
1608 Standard_Integer PUpperRow = Poles.UpperRow();
1609 Standard_Integer PLowerCol = Poles.LowerCol();
1610 Standard_Integer PUpperCol = Poles.UpperCol();
1613 for ( i = PLowerRow; i <= PUpperRow; i++) {
1615 for ( j = PLowerCol; j <= PUpperCol; j++) {
1616 const gp_Pnt& P = Poles .Value(i,j);
1617 Standard_Real w = Weights.Value(i,j);
1618 FP(l) = P.X() * w; l++;
1619 FP(l) = P.Y() * w; l++;
1620 FP(l) = P.Z() * w; l++;
1627 for ( j = PLowerCol; j <= PUpperCol; j++) {
1629 for ( i = PLowerRow; i <= PUpperRow; i++) {
1630 const gp_Pnt& P = Poles .Value(i,j);
1631 Standard_Real w = Weights.Value(i,j);
1632 FP(l) = P.X() * w; l++;
1633 FP(l) = P.Y() * w; l++;
1634 FP(l) = P.Z() * w; l++;
1641 //=======================================================================
1642 //function : GetPoles
1644 //=======================================================================
1646 void BSplSLib::GetPoles(const TColStd_Array1OfReal& FP,
1647 TColgp_Array2OfPnt& Poles,
1648 const Standard_Boolean UDirection)
1650 Standard_Integer i, j, l = FP.Lower();
1651 Standard_Integer PLowerRow = Poles.LowerRow();
1652 Standard_Integer PUpperRow = Poles.UpperRow();
1653 Standard_Integer PLowerCol = Poles.LowerCol();
1654 Standard_Integer PUpperCol = Poles.UpperCol();
1657 for ( i = PLowerRow; i <= PUpperRow; i++) {
1659 for ( j = PLowerCol; j <= PUpperCol; j++) {
1660 gp_Pnt& P = Poles.ChangeValue(i,j);
1669 for ( j = PLowerCol; j <= PUpperCol; j++) {
1671 for ( i = PLowerRow; i <= PUpperRow; i++) {
1672 gp_Pnt& P = Poles.ChangeValue(i,j);
1681 //=======================================================================
1682 //function : GetPoles
1684 //=======================================================================
1686 void BSplSLib::GetPoles(const TColStd_Array1OfReal& FP,
1687 TColgp_Array2OfPnt& Poles,
1688 TColStd_Array2OfReal& Weights,
1689 const Standard_Boolean UDirection)
1691 Standard_Integer i, j, l = FP.Lower();
1692 Standard_Integer PLowerRow = Poles.LowerRow();
1693 Standard_Integer PUpperRow = Poles.UpperRow();
1694 Standard_Integer PLowerCol = Poles.LowerCol();
1695 Standard_Integer PUpperCol = Poles.UpperCol();
1698 for ( i = PLowerRow; i <= PUpperRow; i++) {
1700 for ( j = PLowerCol; j <= PUpperCol; j++) {
1701 Standard_Real w = FP( l + 3);
1703 gp_Pnt& P = Poles.ChangeValue(i,j);
1704 P.SetX(FP(l) / w); l++;
1705 P.SetY(FP(l) / w); l++;
1706 P.SetZ(FP(l) / w); l++;
1713 for ( j = PLowerCol; j <= PUpperCol; j++) {
1715 for ( i = PLowerRow; i <= PUpperRow; i++) {
1716 Standard_Real w = FP( l + 3);
1718 gp_Pnt& P = Poles.ChangeValue(i,j);
1719 P.SetX(FP(l) / w); l++;
1720 P.SetY(FP(l) / w); l++;
1721 P.SetZ(FP(l) / w); l++;
1728 //=======================================================================
1729 //function : InsertKnots
1731 //=======================================================================
1733 void BSplSLib::InsertKnots(const Standard_Boolean UDirection,
1734 const Standard_Integer Degree,
1735 const Standard_Boolean Periodic,
1736 const TColgp_Array2OfPnt& Poles,
1737 const TColStd_Array2OfReal* Weights,
1738 const TColStd_Array1OfReal& Knots,
1739 const TColStd_Array1OfInteger& Mults,
1740 const TColStd_Array1OfReal& AddKnots,
1741 const TColStd_Array1OfInteger* AddMults,
1742 TColgp_Array2OfPnt& NewPoles,
1743 TColStd_Array2OfReal* NewWeights,
1744 TColStd_Array1OfReal& NewKnots,
1745 TColStd_Array1OfInteger& NewMults,
1746 const Standard_Real Epsilon,
1747 const Standard_Boolean Add )
1749 Standard_Boolean rational = Weights != NULL;
1750 Standard_Integer dim = 3;
1751 if (rational) dim++;
1753 TColStd_Array1OfReal poles( 1, dim*Poles.RowLength()*Poles.ColLength());
1754 TColStd_Array1OfReal
1755 newpoles( 1, dim*NewPoles.RowLength()*NewPoles.ColLength());
1757 if (rational) SetPoles(Poles,*Weights,poles,UDirection);
1758 else SetPoles(Poles,poles,UDirection);
1761 dim *= Poles.RowLength();
1764 dim *= Poles.ColLength();
1766 BSplCLib::InsertKnots(Degree,Periodic,dim,poles,Knots,Mults,
1767 AddKnots,AddMults,newpoles,NewKnots,NewMults,
1770 if (rational) GetPoles(newpoles,NewPoles,*NewWeights,UDirection);
1771 else GetPoles(newpoles,NewPoles,UDirection);
1774 //=======================================================================
1775 //function : RemoveKnot
1777 //=======================================================================
1779 Standard_Boolean BSplSLib::RemoveKnot
1780 (const Standard_Boolean UDirection,
1781 const Standard_Integer Index,
1782 const Standard_Integer Mult,
1783 const Standard_Integer Degree,
1784 const Standard_Boolean Periodic,
1785 const TColgp_Array2OfPnt& Poles,
1786 const TColStd_Array2OfReal* Weights,
1787 const TColStd_Array1OfReal& Knots,
1788 const TColStd_Array1OfInteger& Mults,
1789 TColgp_Array2OfPnt& NewPoles,
1790 TColStd_Array2OfReal* NewWeights,
1791 TColStd_Array1OfReal& NewKnots,
1792 TColStd_Array1OfInteger& NewMults,
1793 const Standard_Real Tolerance)
1795 Standard_Boolean rational = Weights != NULL;
1796 Standard_Integer dim = 3;
1797 if (rational) dim++;
1799 TColStd_Array1OfReal poles( 1, dim*Poles.RowLength()*Poles.ColLength());
1800 TColStd_Array1OfReal
1801 newpoles( 1, dim*NewPoles.RowLength()*NewPoles.ColLength());
1803 if (rational) SetPoles(Poles,*Weights,poles,UDirection);
1804 else SetPoles(Poles,poles,UDirection);
1807 dim *= Poles.RowLength();
1810 dim *= Poles.ColLength();
1813 if ( !BSplCLib::RemoveKnot(Index,Mult,Degree,Periodic,dim,
1814 poles,Knots,Mults,newpoles,NewKnots,NewMults,
1816 return Standard_False;
1818 if (rational) GetPoles(newpoles,NewPoles,*NewWeights,UDirection);
1819 else GetPoles(newpoles,NewPoles,UDirection);
1820 return Standard_True;
1823 //=======================================================================
1824 //function : IncreaseDegree
1826 //=======================================================================
1828 void BSplSLib::IncreaseDegree
1829 (const Standard_Boolean UDirection,
1830 const Standard_Integer Degree,
1831 const Standard_Integer NewDegree,
1832 const Standard_Boolean Periodic,
1833 const TColgp_Array2OfPnt& Poles,
1834 const TColStd_Array2OfReal* Weights,
1835 const TColStd_Array1OfReal& Knots,
1836 const TColStd_Array1OfInteger& Mults,
1837 TColgp_Array2OfPnt& NewPoles,
1838 TColStd_Array2OfReal* NewWeights,
1839 TColStd_Array1OfReal& NewKnots,
1840 TColStd_Array1OfInteger& NewMults)
1842 Standard_Boolean rational = Weights != NULL;
1843 Standard_Integer dim = 3;
1844 if (rational) dim++;
1846 TColStd_Array1OfReal poles( 1, dim*Poles.RowLength()*Poles.ColLength());
1847 TColStd_Array1OfReal
1848 newpoles( 1, dim*NewPoles.RowLength()*NewPoles.ColLength());
1850 if (rational) SetPoles(Poles,*Weights,poles,UDirection);
1851 else SetPoles(Poles,poles,UDirection);
1854 dim *= Poles.RowLength();
1857 dim *= Poles.ColLength();
1860 BSplCLib::IncreaseDegree(Degree,NewDegree,Periodic,dim,poles,Knots,Mults,
1861 newpoles,NewKnots,NewMults);
1863 if (rational) GetPoles(newpoles,NewPoles,*NewWeights,UDirection);
1864 else GetPoles(newpoles,NewPoles,UDirection);
1867 //=======================================================================
1868 //function : Unperiodize
1870 //=======================================================================
1872 void BSplSLib::Unperiodize
1873 (const Standard_Boolean UDirection,
1874 const Standard_Integer Degree,
1875 const TColStd_Array1OfInteger& Mults,
1876 const TColStd_Array1OfReal& Knots,
1877 const TColgp_Array2OfPnt& Poles,
1878 const TColStd_Array2OfReal* Weights,
1879 TColStd_Array1OfInteger& NewMults,
1880 TColStd_Array1OfReal& NewKnots,
1881 TColgp_Array2OfPnt& NewPoles,
1882 TColStd_Array2OfReal* NewWeights)
1884 Standard_Boolean rational = Weights != NULL;
1885 Standard_Integer dim = 3;
1886 if (rational) dim++;
1888 TColStd_Array1OfReal poles( 1, dim*Poles.RowLength()*Poles.ColLength());
1889 TColStd_Array1OfReal
1890 newpoles( 1, dim*NewPoles.RowLength()*NewPoles.ColLength());
1892 if (rational) SetPoles(Poles,*Weights,poles,UDirection);
1893 else SetPoles(Poles,poles,UDirection);
1896 dim *= Poles.RowLength();
1899 dim *= Poles.ColLength();
1902 BSplCLib::Unperiodize(Degree, dim, Mults, Knots, poles,
1903 NewMults, NewKnots, newpoles);
1905 if (rational) GetPoles(newpoles,NewPoles,*NewWeights,UDirection);
1906 else GetPoles(newpoles,NewPoles,UDirection);
1909 //=======================================================================
1910 //function : BuildCache
1911 //purpose : Stores theTaylor expansion normalized between 0,1 in the
1912 // Cache : in case of a rational function the Poles are
1913 // stored in homogeneous form
1914 //=======================================================================
1916 void BSplSLib::BuildCache
1917 (const Standard_Real U,
1918 const Standard_Real V,
1919 const Standard_Real USpanDomain,
1920 const Standard_Real VSpanDomain,
1921 const Standard_Boolean UPeriodic,
1922 const Standard_Boolean VPeriodic,
1923 const Standard_Integer UDegree,
1924 const Standard_Integer VDegree,
1925 const Standard_Integer UIndex,
1926 const Standard_Integer VIndex,
1927 const TColStd_Array1OfReal& UFlatKnots,
1928 const TColStd_Array1OfReal& VFlatKnots,
1929 const TColgp_Array2OfPnt& Poles,
1930 const TColStd_Array2OfReal* Weights,
1931 TColgp_Array2OfPnt& CachePoles,
1932 TColStd_Array2OfReal* CacheWeights)
1934 Standard_Boolean rational,rational_u,rational_v,flag_u_or_v;
1935 Standard_Integer kk,d1,d1p1,d2,d2p1,ii,jj,iii,jjj,Index;
1936 Standard_Real u1,min_degree_domain,max_degree_domain,f,factor[2],u2;
1937 if (Weights != NULL)
1938 rational_u = rational_v = Standard_True;
1940 rational_u = rational_v = Standard_False;
1941 BSplSLib_DataContainer dc (UDegree, VDegree);
1957 (BSplCLib::NoMults()),
1958 (BSplCLib::NoMults()),
1968 BSplCLib::Bohm(u1,d1,d1,*dc.knots1,4 * d2p1,*dc.poles);
1970 for (kk = 0; kk <= d1 ; kk++)
1971 BSplCLib::Bohm(u2,d2,d2,*dc.knots2,4,*(dc.poles + kk * 4 * d2p1));
1973 min_degree_domain = USpanDomain ;
1974 max_degree_domain = VSpanDomain ;
1977 min_degree_domain = VSpanDomain ;
1978 max_degree_domain = USpanDomain ;
1982 for (ii = 0 ; ii <= d2 ; ii++) {
1986 for (jj = 0 ; jj <= d1 ; jj++) {
1988 Index = jj * d2p1 + ii ;
1990 gp_Pnt& P = CachePoles(iii,jjj);
1991 f = factor[0] * factor[1];
1992 P.SetX( f * dc.poles[Index]); Index++;
1993 P.SetY( f * dc.poles[Index]); Index++;
1994 P.SetZ( f * dc.poles[Index]); Index++;
1995 (*CacheWeights)(iii ,jjj) = f * dc.poles[Index] ;
1996 factor[1] *= min_degree_domain / (Standard_Real) (jjj) ;
1998 factor[0] *= max_degree_domain / (Standard_Real) (iii) ;
2002 BSplCLib::Bohm(u1,d1,d1,*dc.knots1,3 * d2p1,*dc.poles);
2004 for (kk = 0; kk <= d1 ; kk++)
2005 BSplCLib::Bohm(u2,d2,d2,*dc.knots2,3,*(dc.poles + kk * 3 * d2p1));
2007 min_degree_domain = USpanDomain ;
2008 max_degree_domain = VSpanDomain ;
2011 min_degree_domain = VSpanDomain ;
2012 max_degree_domain = USpanDomain ;
2016 for (ii = 0 ; ii <= d2 ; ii++) {
2020 for (jj = 0 ; jj <= d1 ; jj++) {
2022 Index = jj * d2p1 + ii ;
2023 Index = (Index << 1) + Index;
2024 gp_Pnt& P = CachePoles(iii,jjj);
2025 f = factor[0] * factor[1];
2026 P.SetX( f * dc.poles[Index]); Index++;
2027 P.SetY( f * dc.poles[Index]); Index++;
2028 P.SetZ( f * dc.poles[Index]);
2029 factor[1] *= min_degree_domain / (Standard_Real) (jjj) ;
2031 factor[0] *= max_degree_domain / (Standard_Real) (iii) ;
2033 if (Weights != NULL) {
2035 // means that PrepareEval did found out that the surface was
2036 // locally polynomial but since the surface is constructed
2037 // with some weights we need to set the weight polynomial to constant
2040 for (ii = 1 ; ii <= d2p1 ; ii++) {
2042 for (jj = 1 ; jj <= d1p1 ; jj++) {
2043 (*CacheWeights)(ii,jj) = 0.0e0 ;
2046 (*CacheWeights)(1,1) = 1.0e0 ;
2051 void BSplSLib::BuildCache(const Standard_Real theU,
2052 const Standard_Real theV,
2053 const Standard_Real theUSpanDomain,
2054 const Standard_Real theVSpanDomain,
2055 const Standard_Boolean theUPeriodicFlag,
2056 const Standard_Boolean theVPeriodicFlag,
2057 const Standard_Integer theUDegree,
2058 const Standard_Integer theVDegree,
2059 const Standard_Integer theUIndex,
2060 const Standard_Integer theVIndex,
2061 const TColStd_Array1OfReal& theUFlatKnots,
2062 const TColStd_Array1OfReal& theVFlatKnots,
2063 const TColgp_Array2OfPnt& thePoles,
2064 const TColStd_Array2OfReal* theWeights,
2065 TColStd_Array2OfReal& theCacheArray)
2067 Standard_Boolean flag_u_or_v;
2068 Standard_Integer d1, d2;
2069 Standard_Real u1, u2;
2070 Standard_Boolean isRationalOnParam = (theWeights != NULL);
2071 Standard_Boolean isRational;
2073 BSplSLib_DataContainer dc(theUDegree, theVDegree);
2075 PrepareEval(theU, theV, theUIndex, theVIndex, theUDegree, theVDegree,
2076 isRationalOnParam, isRationalOnParam,
2077 theUPeriodicFlag, theVPeriodicFlag,
2078 thePoles, theWeights,
2079 theUFlatKnots, theVFlatKnots,
2080 (BSplCLib::NoMults()), (BSplCLib::NoMults()),
2081 u1, u2, d1, d2, isRational, dc);
2083 Standard_Integer d2p1 = d2 + 1;
2084 Standard_Integer aDimension = isRational ? 4 : 3;
2085 Standard_Integer aCacheShift = // helps to store weights when PrepareEval did not found that the surface is locally polynomial
2086 (isRationalOnParam && !isRational) ? aDimension + 1 : aDimension;
2088 Standard_Real aDomains[2];
2089 // aDomains[0] corresponds to variable with minimal degree
2090 // aDomains[1] corresponds to variable with maximal degree
2093 aDomains[0] = theUSpanDomain;
2094 aDomains[1] = theVSpanDomain;
2098 aDomains[0] = theVSpanDomain;
2099 aDomains[1] = theUSpanDomain;
2102 BSplCLib::Bohm(u1, d1, d1, *dc.knots1, aDimension * d2p1, *dc.poles);
2103 for (Standard_Integer kk = 0; kk <= d1 ; kk++)
2104 BSplCLib::Bohm(u2, d2, d2, *dc.knots2, aDimension, *(dc.poles + kk * aDimension * d2p1));
2106 Standard_Real* aCache = (Standard_Real *) &(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol()));
2107 Standard_Real* aPolyCoeffs = dc.poles;
2109 Standard_Real aFactors[2];
2110 // aFactors[0] corresponds to variable with minimal degree
2111 // aFactors[1] corresponds to variable with maximal degree
2113 Standard_Integer aRow, aCol, i;
2114 Standard_Real aCoeff;
2115 for (aRow = 0; aRow <= d2; aRow++)
2118 for (aCol = 0; aCol <= d1; aCol++)
2120 aPolyCoeffs = dc.poles + (aCol * d2p1 + aRow) * aDimension;
2121 aCoeff = aFactors[0] * aFactors[1];
2122 for (i = 0; i < aDimension; i++)
2123 aCache[i] = aPolyCoeffs[i] * aCoeff;
2124 aCache += aCacheShift;
2125 aFactors[0] *= aDomains[0] / (aCol + 1);
2127 aFactors[1] *= aDomains[1] / (aRow + 1);
2130 // Fill the weights for the surface which is not locally polynomial
2131 if (aCacheShift > aDimension)
2133 aCache = (Standard_Real *) &(theCacheArray(theCacheArray.LowerRow(), theCacheArray.LowerCol()));
2134 aCache += aCacheShift - 1;
2135 for (aRow = 0; aRow <= d2; aRow++)
2136 for (aCol = 0; aCol <= d1; aCol++)
2139 aCache += aCacheShift;
2141 theCacheArray.SetValue(theCacheArray.LowerRow(), theCacheArray.LowerCol() + aCacheShift - 1, 1.0);
2146 //=======================================================================
2147 //function : CacheD0
2148 //purpose : Evaluates the polynomial cache of the Bspline Curve
2150 //=======================================================================
2152 void BSplSLib::CacheD0(const Standard_Real UParameter,
2153 const Standard_Real VParameter,
2154 const Standard_Integer UDegree,
2155 const Standard_Integer VDegree,
2156 const Standard_Real UCacheParameter,
2157 const Standard_Real VCacheParameter,
2158 const Standard_Real USpanLenght,
2159 const Standard_Real VSpanLenght,
2160 const TColgp_Array2OfPnt& PolesArray,
2161 const TColStd_Array2OfReal* WeightsArray,
2165 // the CacheParameter is where the cache polynomial was evaluated in homogeneous
2167 // the SpanLenght is the normalizing factor so that the polynomial is between
2180 PArray = (Standard_Real *)
2181 &(PolesArray(PolesArray.LowerCol(), PolesArray.LowerRow())) ;
2183 myPoint = (Standard_Real *) &aPoint ;
2184 if (UDegree <= VDegree) {
2185 min_degree = UDegree ;
2186 max_degree = VDegree ;
2187 new_parameter[1] = (UParameter - UCacheParameter) / USpanLenght ;
2188 new_parameter[0] = (VParameter - VCacheParameter) / VSpanLenght ;
2189 dimension = 3 * (UDegree + 1) ;
2192 min_degree = VDegree ;
2193 max_degree = UDegree ;
2194 new_parameter[0] = (UParameter - UCacheParameter) / USpanLenght ;
2195 new_parameter[1] = (VParameter - VCacheParameter) / VSpanLenght ;
2196 dimension = 3 * (VDegree + 1) ;
2198 NCollection_LocalArray<Standard_Real> locpoles(dimension);
2200 PLib::NoDerivativeEvalPolynomial(new_parameter[0],
2203 max_degree*dimension,
2207 PLib::NoDerivativeEvalPolynomial(new_parameter[1],
2210 (min_degree << 1) + min_degree,
2213 if (WeightsArray != NULL) {
2214 dimension = min_degree + 1 ;
2215 const TColStd_Array2OfReal& refWeights = *WeightsArray;
2217 WArray = (Standard_Real *)
2218 &refWeights(refWeights.LowerCol(),refWeights.LowerRow()) ;
2219 PLib::NoDerivativeEvalPolynomial(new_parameter[0],
2222 max_degree*dimension,
2226 PLib::NoDerivativeEvalPolynomial(new_parameter[1],
2232 inverse = 1.0e0/ inverse ;
2234 myPoint[0] *= inverse ;
2235 myPoint[1] *= inverse ;
2236 myPoint[2] *= inverse ;
2240 //=======================================================================
2241 //function : CacheD1
2242 //purpose : Evaluates the polynomial cache of the Bspline Curve
2244 //=======================================================================
2246 void BSplSLib::CacheD1(const Standard_Real UParameter,
2247 const Standard_Real VParameter,
2248 const Standard_Integer UDegree,
2249 const Standard_Integer VDegree,
2250 const Standard_Real UCacheParameter,
2251 const Standard_Real VCacheParameter,
2252 const Standard_Real USpanLenght,
2253 const Standard_Real VSpanLenght,
2254 const TColgp_Array2OfPnt& PolesArray,
2255 const TColStd_Array2OfReal* WeightsArray,
2261 // the CacheParameter is where the cache polynomial was evaluated in homogeneous
2263 // the SpanLenght is the normalizing factor so that the polynomial is between
2279 PArray = (Standard_Real *)
2280 &(PolesArray(PolesArray.LowerCol(), PolesArray.LowerRow())) ;
2281 Standard_Real local_poles_array[2][2][3],
2282 local_poles_and_weights_array[2][2][4],
2283 local_weights_array[2][2] ;
2284 Standard_Real * my_vec_min,
2287 my_point = (Standard_Real *) &aPoint ;
2289 // initialize in case of rational evaluation
2290 // because RationalDerivative will use all
2294 if (WeightsArray != NULL) {
2296 local_poles_array [0][0][0] = 0.0e0 ;
2297 local_poles_array [0][0][1] = 0.0e0 ;
2298 local_poles_array [0][0][2] = 0.0e0 ;
2299 local_weights_array [0][0] = 0.0e0 ;
2300 local_poles_and_weights_array[0][0][0] = 0.0e0 ;
2301 local_poles_and_weights_array[0][0][1] = 0.0e0 ;
2302 local_poles_and_weights_array[0][0][2] = 0.0e0 ;
2303 local_poles_and_weights_array[0][0][3] = 0.0e0 ;
2305 local_poles_array [0][1][0] = 0.0e0 ;
2306 local_poles_array [0][1][1] = 0.0e0 ;
2307 local_poles_array [0][1][2] = 0.0e0 ;
2308 local_weights_array [0][1] = 0.0e0 ;
2309 local_poles_and_weights_array[0][1][0] = 0.0e0 ;
2310 local_poles_and_weights_array[0][1][1] = 0.0e0 ;
2311 local_poles_and_weights_array[0][1][2] = 0.0e0 ;
2312 local_poles_and_weights_array[0][1][3] = 0.0e0 ;
2314 local_poles_array [1][0][0] = 0.0e0 ;
2315 local_poles_array [1][0][1] = 0.0e0 ;
2316 local_poles_array [1][0][2] = 0.0e0 ;
2317 local_weights_array [1][0] = 0.0e0 ;
2318 local_poles_and_weights_array[1][0][0] = 0.0e0 ;
2319 local_poles_and_weights_array[1][0][1] = 0.0e0 ;
2320 local_poles_and_weights_array[1][0][2] = 0.0e0 ;
2321 local_poles_and_weights_array[1][0][3] = 0.0e0 ;
2323 local_poles_array [1][1][0] = 0.0e0 ;
2324 local_poles_array [1][1][1] = 0.0e0 ;
2325 local_poles_array [1][1][2] = 0.0e0 ;
2326 local_weights_array [1][1] = 0.0e0 ;
2327 local_poles_and_weights_array[1][1][0] = 0.0e0 ;
2328 local_poles_and_weights_array[1][1][1] = 0.0e0 ;
2329 local_poles_and_weights_array[1][1][2] = 0.0e0 ;
2330 local_poles_and_weights_array[1][1][3] = 0.0e0 ;
2333 if (UDegree <= VDegree) {
2334 min_degree = UDegree ;
2335 max_degree = VDegree ;
2336 inverse_min = 1.0e0/USpanLenght ;
2337 inverse_max = 1.0e0/VSpanLenght ;
2338 new_parameter[0] = (VParameter - VCacheParameter) * inverse_max ;
2339 new_parameter[1] = (UParameter - UCacheParameter) * inverse_min ;
2341 dimension = 3 * (UDegree + 1) ;
2342 my_vec_min = (Standard_Real *) &aVecU ;
2343 my_vec_max = (Standard_Real *) &aVecV ;
2346 min_degree = VDegree ;
2347 max_degree = UDegree ;
2348 inverse_min = 1.0e0/VSpanLenght ;
2349 inverse_max = 1.0e0/USpanLenght ;
2350 new_parameter[0] = (UParameter - UCacheParameter) * inverse_max ;
2351 new_parameter[1] = (VParameter - VCacheParameter) * inverse_min ;
2352 dimension = 3 * (VDegree + 1) ;
2353 my_vec_min = (Standard_Real *) &aVecV ;
2354 my_vec_max = (Standard_Real *) &aVecU ;
2357 NCollection_LocalArray<Standard_Real> locpoles (2 * dimension);
2359 PLib::EvalPolynomial(new_parameter[0],
2366 PLib::EvalPolynomial(new_parameter[1],
2371 local_poles_array[0][0][0]) ;
2372 PLib::NoDerivativeEvalPolynomial(new_parameter[1],
2375 (min_degree << 1) + min_degree,
2376 locpoles[dimension],
2377 local_poles_array[1][0][0]) ;
2379 if (WeightsArray != NULL) {
2380 dimension = min_degree + 1 ;
2381 const TColStd_Array2OfReal& refWeights = *WeightsArray;
2383 WArray = (Standard_Real *)
2384 &refWeights(refWeights.LowerCol(),refWeights.LowerRow()) ;
2385 PLib::EvalPolynomial(new_parameter[0],
2392 PLib::EvalPolynomial(new_parameter[1],
2397 local_weights_array[0][0]) ;
2398 PLib::NoDerivativeEvalPolynomial(new_parameter[1],
2402 locpoles[dimension],
2403 local_weights_array[1][0]) ;
2405 local_poles_and_weights_array[0][0][0] = local_poles_array [0][0][0] ;
2406 local_poles_and_weights_array[0][0][1] = local_poles_array [0][0][1] ;
2407 local_poles_and_weights_array[0][0][2] = local_poles_array [0][0][2] ;
2408 local_poles_and_weights_array[0][0][3] = local_weights_array[0][0] ;
2410 local_poles_and_weights_array[0][1][0] = local_poles_array [0][1][0] ;
2411 local_poles_and_weights_array[0][1][1] = local_poles_array [0][1][1] ;
2412 local_poles_and_weights_array[0][1][2] = local_poles_array [0][1][2] ;
2413 local_poles_and_weights_array[0][1][3] = local_weights_array[0][1] ;
2415 local_poles_and_weights_array[1][0][0] = local_poles_array [1][0][0] ;
2416 local_poles_and_weights_array[1][0][1] = local_poles_array [1][0][1] ;
2417 local_poles_and_weights_array[1][0][2] = local_poles_array [1][0][2] ;
2418 local_poles_and_weights_array[1][0][3] = local_weights_array[1][0] ;
2420 local_poles_and_weights_array[1][1][0] = local_poles_array [1][1][0] ;
2421 local_poles_and_weights_array[1][1][1] = local_poles_array [1][1][1] ;
2422 local_poles_and_weights_array[1][1][2] = local_poles_array [1][1][2] ;
2423 local_poles_and_weights_array[1][1][3] = local_weights_array[1][1] ;
2425 BSplSLib::RationalDerivative(1,
2429 local_poles_and_weights_array[0][0][0],
2430 local_poles_array[0][0][0]) ;
2433 my_point [0] = local_poles_array [0][0][0] ;
2434 my_vec_min[0] = inverse_min * local_poles_array[0][1][0] ;
2435 my_vec_max[0] = inverse_max * local_poles_array[1][0][0] ;
2437 my_point [1] = local_poles_array [0][0][1] ;
2438 my_vec_min[1] = inverse_min * local_poles_array[0][1][1] ;
2439 my_vec_max[1] = inverse_max * local_poles_array[1][0][1] ;
2441 my_point [2] = local_poles_array [0][0][2] ;
2442 my_vec_min[2] = inverse_min * local_poles_array[0][1][2] ;
2443 my_vec_max[2] = inverse_max * local_poles_array[1][0][2] ;
2446 //=======================================================================
2447 //function : CacheD2
2448 //purpose : Evaluates the polynomial cache of the Bspline Curve
2450 //=======================================================================
2452 void BSplSLib::CacheD2(const Standard_Real UParameter,
2453 const Standard_Real VParameter,
2454 const Standard_Integer UDegree,
2455 const Standard_Integer VDegree,
2456 const Standard_Real UCacheParameter,
2457 const Standard_Real VCacheParameter,
2458 const Standard_Real USpanLenght,
2459 const Standard_Real VSpanLenght,
2460 const TColgp_Array2OfPnt& PolesArray,
2461 const TColStd_Array2OfReal* WeightsArray,
2470 // the CacheParameter is where the cache polynomial was evaluated in homogeneous
2472 // the SpanLenght is the normalizing factor so that the polynomial is between
2489 PArray = (Standard_Real *)
2490 &(PolesArray(PolesArray.LowerCol(), PolesArray.LowerRow())) ;
2491 Standard_Real local_poles_array[3][3][3],
2492 local_poles_and_weights_array[3][3][4],
2493 local_weights_array[3][3] ;
2494 Standard_Real * my_vec_min,
2500 my_point = (Standard_Real *) &aPoint ;
2503 // initialize in case the min and max degree are less than 2
2505 local_poles_array[0][0][0] = 0.0e0 ;
2506 local_poles_array[0][0][1] = 0.0e0 ;
2507 local_poles_array[0][0][2] = 0.0e0 ;
2508 local_poles_array[0][1][0] = 0.0e0 ;
2509 local_poles_array[0][1][1] = 0.0e0 ;
2510 local_poles_array[0][1][2] = 0.0e0 ;
2511 local_poles_array[0][2][0] = 0.0e0 ;
2512 local_poles_array[0][2][1] = 0.0e0 ;
2513 local_poles_array[0][2][2] = 0.0e0 ;
2515 local_poles_array[1][0][0] = 0.0e0 ;
2516 local_poles_array[1][0][1] = 0.0e0 ;
2517 local_poles_array[1][0][2] = 0.0e0 ;
2518 local_poles_array[1][1][0] = 0.0e0 ;
2519 local_poles_array[1][1][1] = 0.0e0 ;
2520 local_poles_array[1][1][2] = 0.0e0 ;
2521 local_poles_array[1][2][0] = 0.0e0 ;
2522 local_poles_array[1][2][1] = 0.0e0 ;
2523 local_poles_array[1][2][2] = 0.0e0 ;
2525 local_poles_array[2][0][0] = 0.0e0 ;
2526 local_poles_array[2][0][1] = 0.0e0 ;
2527 local_poles_array[2][0][2] = 0.0e0 ;
2528 local_poles_array[2][1][0] = 0.0e0 ;
2529 local_poles_array[2][1][1] = 0.0e0 ;
2530 local_poles_array[2][1][2] = 0.0e0 ;
2531 local_poles_array[2][2][0] = 0.0e0 ;
2532 local_poles_array[2][2][1] = 0.0e0 ;
2533 local_poles_array[2][2][2] = 0.0e0 ;
2535 // initialize in case of rational evaluation
2536 // because RationalDerivative will use all
2540 if (WeightsArray != NULL) {
2542 local_poles_and_weights_array[0][0][0] = 0.0e0 ;
2543 local_poles_and_weights_array[0][0][1] = 0.0e0 ;
2544 local_poles_and_weights_array[0][0][2] = 0.0e0 ;
2545 local_poles_and_weights_array[0][1][0] = 0.0e0 ;
2546 local_poles_and_weights_array[0][1][1] = 0.0e0 ;
2547 local_poles_and_weights_array[0][1][2] = 0.0e0 ;
2548 local_poles_and_weights_array[0][2][0] = 0.0e0 ;
2549 local_poles_and_weights_array[0][2][1] = 0.0e0 ;
2550 local_poles_and_weights_array[0][2][2] = 0.0e0 ;
2552 local_poles_and_weights_array[1][0][0] = 0.0e0 ;
2553 local_poles_and_weights_array[1][0][1] = 0.0e0 ;
2554 local_poles_and_weights_array[1][0][2] = 0.0e0 ;
2555 local_poles_and_weights_array[1][1][0] = 0.0e0 ;
2556 local_poles_and_weights_array[1][1][1] = 0.0e0 ;
2557 local_poles_and_weights_array[1][1][2] = 0.0e0 ;
2558 local_poles_and_weights_array[1][2][0] = 0.0e0 ;
2559 local_poles_and_weights_array[1][2][1] = 0.0e0 ;
2560 local_poles_and_weights_array[1][2][2] = 0.0e0 ;
2562 local_poles_and_weights_array[2][0][0] = 0.0e0 ;
2563 local_poles_and_weights_array[2][0][1] = 0.0e0 ;
2564 local_poles_and_weights_array[2][0][2] = 0.0e0 ;
2565 local_poles_and_weights_array[2][1][0] = 0.0e0 ;
2566 local_poles_and_weights_array[2][1][1] = 0.0e0 ;
2567 local_poles_and_weights_array[2][1][2] = 0.0e0 ;
2568 local_poles_and_weights_array[2][2][0] = 0.0e0 ;
2569 local_poles_and_weights_array[2][2][1] = 0.0e0 ;
2570 local_poles_and_weights_array[2][2][2] = 0.0e0 ;
2572 local_poles_and_weights_array[0][0][3] =
2573 local_weights_array[0][0] = 0.0e0 ;
2574 local_poles_and_weights_array[0][1][3] =
2575 local_weights_array[0][1] = 0.0e0 ;
2576 local_poles_and_weights_array[0][2][3] =
2577 local_weights_array[0][2] = 0.0e0 ;
2578 local_poles_and_weights_array[1][0][3] =
2579 local_weights_array[1][0] = 0.0e0 ;
2580 local_poles_and_weights_array[1][1][3] =
2581 local_weights_array[1][1] = 0.0e0 ;
2582 local_poles_and_weights_array[1][2][3] =
2583 local_weights_array[1][2] = 0.0e0 ;
2584 local_poles_and_weights_array[2][0][3] =
2585 local_weights_array[2][0] = 0.0e0 ;
2586 local_poles_and_weights_array[2][1][3] =
2587 local_weights_array[2][1] = 0.0e0 ;
2588 local_poles_and_weights_array[2][2][3] =
2589 local_weights_array[2][2] = 0.0e0 ;
2592 if (UDegree <= VDegree) {
2593 min_degree = UDegree ;
2594 max_degree = VDegree ;
2595 inverse_min = 1.0e0/USpanLenght ;
2596 inverse_max = 1.0e0/VSpanLenght ;
2597 new_parameter[0] = (VParameter - VCacheParameter) * inverse_max ;
2598 new_parameter[1] = (UParameter - UCacheParameter) * inverse_min ;
2600 dimension = 3 * (UDegree + 1) ;
2601 my_vec_min = (Standard_Real *) &aVecU ;
2602 my_vec_max = (Standard_Real *) &aVecV ;
2603 my_vec_min_min = (Standard_Real *) &aVecUU ;
2604 my_vec_min_max = (Standard_Real *) &aVecUV ;
2605 my_vec_max_max = (Standard_Real *) &aVecVV ;
2608 min_degree = VDegree ;
2609 max_degree = UDegree ;
2610 inverse_min = 1.0e0/VSpanLenght ;
2611 inverse_max = 1.0e0/USpanLenght ;
2612 new_parameter[0] = (UParameter - UCacheParameter) * inverse_max ;
2613 new_parameter[1] = (VParameter - VCacheParameter) * inverse_min ;
2614 dimension = 3 * (VDegree + 1) ;
2615 my_vec_min = (Standard_Real *) &aVecV ;
2616 my_vec_max = (Standard_Real *) &aVecU ;
2617 my_vec_min_min = (Standard_Real *) &aVecVV ;
2618 my_vec_min_max = (Standard_Real *) &aVecUV ;
2619 my_vec_max_max = (Standard_Real *) &aVecUU ;
2622 NCollection_LocalArray<Standard_Real> locpoles (3 * dimension);
2625 // initialize in case min or max degree are less than 2
2627 Standard_Integer MinIndMax = 2;
2628 if ( max_degree < 2) MinIndMax = max_degree;
2629 Standard_Integer MinIndMin = 2;
2630 if ( min_degree < 2) MinIndMin = min_degree;
2632 index = MinIndMax * dimension ;
2634 for (ii = MinIndMax ; ii < 3 ; ii++) {
2636 for (kk = 0 ; kk < dimension ; kk++) {
2637 locpoles[index] = 0.0e0 ;
2642 PLib::EvalPolynomial(new_parameter[0],
2649 PLib::EvalPolynomial(new_parameter[1],
2654 local_poles_array[0][0][0]) ;
2655 PLib::EvalPolynomial(new_parameter[1],
2659 locpoles[dimension],
2660 local_poles_array[1][0][0]) ;
2662 PLib::NoDerivativeEvalPolynomial(new_parameter[1],
2665 (min_degree << 1) + min_degree,
2666 locpoles[dimension + dimension],
2667 local_poles_array[2][0][0]) ;
2669 if (WeightsArray != NULL) {
2670 dimension = min_degree + 1 ;
2671 const TColStd_Array2OfReal& refWeights = *WeightsArray;
2673 WArray = (Standard_Real *)
2674 &refWeights(refWeights.LowerCol(),refWeights.LowerRow()) ;
2675 PLib::EvalPolynomial(new_parameter[0],
2682 PLib::EvalPolynomial(new_parameter[1],
2687 local_weights_array[0][0]) ;
2688 PLib::EvalPolynomial(new_parameter[1],
2692 locpoles[dimension],
2693 local_weights_array[1][0]) ;
2694 PLib::NoDerivativeEvalPolynomial(new_parameter[1],
2698 locpoles[dimension + dimension],
2699 local_weights_array[2][0]) ;
2702 local_poles_and_weights_array[0][0][0] = local_poles_array[0][0][0];
2703 local_poles_and_weights_array[0][0][1] = local_poles_array[0][0][1];
2704 local_poles_and_weights_array[0][0][2] = local_poles_array[0][0][2];
2705 local_poles_and_weights_array[0][1][0] = local_poles_array[0][1][0];
2706 local_poles_and_weights_array[0][1][1] = local_poles_array[0][1][1];
2707 local_poles_and_weights_array[0][1][2] = local_poles_array[0][1][2];
2708 local_poles_and_weights_array[0][2][0] = local_poles_array[0][2][0];
2709 local_poles_and_weights_array[0][2][1] = local_poles_array[0][2][1];
2710 local_poles_and_weights_array[0][2][2] = local_poles_array[0][2][2];
2712 local_poles_and_weights_array[1][0][0] = local_poles_array[1][0][0];
2713 local_poles_and_weights_array[1][0][1] = local_poles_array[1][0][1];
2714 local_poles_and_weights_array[1][0][2] = local_poles_array[1][0][2];
2715 local_poles_and_weights_array[1][1][0] = local_poles_array[1][1][0];
2716 local_poles_and_weights_array[1][1][1] = local_poles_array[1][1][1];
2717 local_poles_and_weights_array[1][1][2] = local_poles_array[1][1][2];
2718 local_poles_and_weights_array[1][2][0] = local_poles_array[1][2][0];
2719 local_poles_and_weights_array[1][2][1] = local_poles_array[1][2][1];
2720 local_poles_and_weights_array[1][2][2] = local_poles_array[1][2][2];
2722 local_poles_and_weights_array[2][0][0] = local_poles_array[2][0][0];
2723 local_poles_and_weights_array[2][0][1] = local_poles_array[2][0][1];
2724 local_poles_and_weights_array[2][0][2] = local_poles_array[2][0][2];
2725 local_poles_and_weights_array[2][1][0] = local_poles_array[2][1][0];
2726 local_poles_and_weights_array[2][1][1] = local_poles_array[2][1][1];
2727 local_poles_and_weights_array[2][1][2] = local_poles_array[2][1][2];
2728 local_poles_and_weights_array[2][2][0] = local_poles_array[2][2][0];
2729 local_poles_and_weights_array[2][2][1] = local_poles_array[2][2][1];
2730 local_poles_and_weights_array[2][2][2] = local_poles_array[2][2][2];
2733 local_poles_and_weights_array[0][0][3] = local_weights_array[0][0];
2734 local_poles_and_weights_array[0][1][3] = local_weights_array[0][1];
2735 local_poles_and_weights_array[0][2][3] = local_weights_array[0][2];
2736 local_poles_and_weights_array[1][0][3] = local_weights_array[1][0];
2737 local_poles_and_weights_array[1][1][3] = local_weights_array[1][1];
2738 local_poles_and_weights_array[1][2][3] = local_weights_array[1][2];
2739 local_poles_and_weights_array[2][0][3] = local_weights_array[2][0];
2740 local_poles_and_weights_array[2][1][3] = local_weights_array[2][1];
2741 local_poles_and_weights_array[2][2][3] = local_weights_array[2][2];
2743 BSplSLib::RationalDerivative(2,
2747 local_poles_and_weights_array[0][0][0],
2748 local_poles_array[0][0][0]) ;
2752 Standard_Real minmin = inverse_min * inverse_min;
2753 Standard_Real minmax = inverse_min * inverse_max;
2754 Standard_Real maxmax = inverse_max * inverse_max;
2756 my_point [0] = local_poles_array [0][0][0] ;
2757 my_vec_min [0] = inverse_min * local_poles_array[0][1][0] ;
2758 my_vec_max [0] = inverse_max * local_poles_array[1][0][0] ;
2759 my_vec_min_min[0] = minmin * local_poles_array [0][2][0] ;
2760 my_vec_min_max[0] = minmax * local_poles_array [1][1][0] ;
2761 my_vec_max_max[0] = maxmax * local_poles_array [2][0][0] ;
2763 my_point [1] = local_poles_array [0][0][1] ;
2764 my_vec_min [1] = inverse_min * local_poles_array[0][1][1] ;
2765 my_vec_max [1] = inverse_max * local_poles_array[1][0][1] ;
2766 my_vec_min_min[1] = minmin * local_poles_array [0][2][1] ;
2767 my_vec_min_max[1] = minmax * local_poles_array [1][1][1] ;
2768 my_vec_max_max[1] = maxmax * local_poles_array [2][0][1] ;
2770 my_point [2] = local_poles_array [0][0][2] ;
2771 my_vec_min [2] = inverse_min * local_poles_array[0][1][2] ;
2772 my_vec_max [2] = inverse_max * local_poles_array[1][0][2] ;
2773 my_vec_min_min[2] = minmin * local_poles_array [0][2][2] ;
2774 my_vec_min_max[2] = minmax * local_poles_array [1][1][2] ;
2775 my_vec_max_max[2] = maxmax * local_poles_array [2][0][2] ;
2778 //=======================================================================
2779 //function : MovePoint
2780 //purpose : Find the new poles which allows an old point (with a
2781 // given u and v as parameters) to reach a new position
2782 //=======================================================================
2784 void BSplSLib::MovePoint (const Standard_Real U,
2785 const Standard_Real V,
2786 const gp_Vec& Displ,
2787 const Standard_Integer UIndex1,
2788 const Standard_Integer UIndex2,
2789 const Standard_Integer VIndex1,
2790 const Standard_Integer VIndex2,
2791 const Standard_Integer UDegree,
2792 const Standard_Integer VDegree,
2793 const Standard_Boolean Rational,
2794 const TColgp_Array2OfPnt& Poles,
2795 const TColStd_Array2OfReal& Weights,
2796 const TColStd_Array1OfReal& UFlatKnots,
2797 const TColStd_Array1OfReal& VFlatKnots,
2798 Standard_Integer& UFirstIndex,
2799 Standard_Integer& ULastIndex,
2800 Standard_Integer& VFirstIndex,
2801 Standard_Integer& VLastIndex,
2802 TColgp_Array2OfPnt& NewPoles)
2804 // calculate the UBSplineBasis in the parameter U
2805 Standard_Integer UFirstNonZeroBsplineIndex;
2806 math_Matrix UBSplineBasis(1, 1,
2808 Standard_Integer ErrorCod1 = BSplCLib::EvalBsplineBasis(1,
2813 UFirstNonZeroBsplineIndex,
2815 // calculate the VBSplineBasis in the parameter V
2816 Standard_Integer VFirstNonZeroBsplineIndex;
2817 math_Matrix VBSplineBasis(1, 1,
2819 Standard_Integer ErrorCod2 = BSplCLib::EvalBsplineBasis(1,
2824 VFirstNonZeroBsplineIndex,
2826 if (ErrorCod1 || ErrorCod2) {
2834 // find the span which is predominant for parameter U
2835 UFirstIndex = UFirstNonZeroBsplineIndex;
2836 ULastIndex = UFirstNonZeroBsplineIndex + UDegree ;
2837 if (UFirstIndex < UIndex1) UFirstIndex = UIndex1;
2838 if (ULastIndex > UIndex2) ULastIndex = UIndex2;
2840 Standard_Real maxValue = 0.0;
2841 Standard_Integer i, ukk1=0, ukk2;
2843 for (i = UFirstIndex-UFirstNonZeroBsplineIndex+1; i <= ULastIndex-UFirstNonZeroBsplineIndex+1; i++) {
2844 if (UBSplineBasis(1,i) > maxValue) {
2845 ukk1 = i + UFirstNonZeroBsplineIndex - 1;
2846 maxValue = UBSplineBasis(1,i);
2850 // find a ukk2 if symetriy
2852 i = ukk1 - UFirstNonZeroBsplineIndex + 2;
2853 if ((ukk1+1) <= ULastIndex) {
2854 if (Abs(UBSplineBasis(1, ukk1-UFirstNonZeroBsplineIndex+2) - maxValue) < 1.e-10) {
2859 // find the span which is predominant for parameter V
2860 VFirstIndex = VFirstNonZeroBsplineIndex;
2861 VLastIndex = VFirstNonZeroBsplineIndex + VDegree ;
2863 if (VFirstIndex < VIndex1) VFirstIndex = VIndex1;
2864 if (VLastIndex > VIndex2) VLastIndex = VIndex2;
2867 Standard_Integer j, vkk1=0, vkk2;
2869 for (j = VFirstIndex-VFirstNonZeroBsplineIndex+1; j <= VLastIndex-VFirstNonZeroBsplineIndex+1; j++) {
2870 if (VBSplineBasis(1,j) > maxValue) {
2871 vkk1 = j + VFirstNonZeroBsplineIndex - 1;
2872 maxValue = VBSplineBasis(1,j);
2876 // find a vkk2 if symetriy
2878 j = vkk1 - VFirstNonZeroBsplineIndex + 2;
2879 if ((vkk1+1) <= VLastIndex) {
2880 if (Abs(VBSplineBasis(1, vkk1-VFirstNonZeroBsplineIndex+2) - maxValue) < 1.e-10) {
2885 // compute the vector of displacement
2886 Standard_Real D1 = 0.0;
2887 Standard_Real D2 = 0.0;
2888 Standard_Real hN, Coef, DvalU, DvalV;
2890 Standard_Integer ii, jj;
2892 for (i = 1; i <= UDegree+1; i++) {
2893 ii = i + UFirstNonZeroBsplineIndex - 1;
2897 else if (ii > ukk2) {
2904 for (j = 1; j <= VDegree+1; j++) {
2905 jj = j + VFirstNonZeroBsplineIndex - 1;
2907 hN = Weights(ii, jj)*UBSplineBasis(1, i)*VBSplineBasis(1,j);
2911 hN = UBSplineBasis(1, i)*VBSplineBasis(1,j);
2913 if (ii >= UFirstIndex && ii <= ULastIndex && jj >= VFirstIndex && jj <= VLastIndex) {
2917 else if (jj > vkk2) {
2923 D1 += 1./(DvalU + DvalV + 1.) * hN;
2935 // compute the new poles
2937 for (i=Poles.LowerRow(); i<=Poles.UpperRow(); i++) {
2941 else if (i > ukk2) {
2948 for (j=Poles.LowerCol(); j<=Poles.UpperCol(); j++) {
2949 if (i >= UFirstIndex && i <= ULastIndex && j >= VFirstIndex && j <= VLastIndex) {
2953 else if (j > vkk2) {
2959 NewPoles(i,j) = Poles(i,j).Translated((Coef/(DvalU + DvalV + 1.))*Displ);
2962 NewPoles(i,j) = Poles(i,j);
2968 //=======================================================================
2969 // function : Resolution
2970 // purpose : this computes an estimate for the maximum of the
2971 // partial derivatives both in U and in V
2974 // The calculation resembles at the calculation of curves with
2975 // additional index for the control point. Let Si,j be the
2976 // control points for ls surface and Di,j the weights.
2977 // The checking of upper bounds for the partial derivatives
2978 // will be omitted and Su is the next upper bound in the polynomial case :
2982 // | Si,j - Si-1,j |
2983 // d * Max | ------------- |
2984 // i = 2,n | ti+d - ti |
2988 // and in the rational case :
2992 // Di,j * (Si,j - Sk,j) - Di-1,j * (Si-1,j - Sk,j)
2993 // Max Max d * -----------------------------------------------
2994 // k=1,n i dans Rj ti+d - ti
2996 // ----------------------------------------------------------------------
3004 // with Rj = {j-d, ...., j+d+d+1}.
3007 //=======================================================================
3009 void BSplSLib::Resolution(const TColgp_Array2OfPnt& Poles,
3010 const TColStd_Array2OfReal* Weights,
3011 const TColStd_Array1OfReal& UKnots,
3012 const TColStd_Array1OfReal& VKnots,
3013 const TColStd_Array1OfInteger& UMults,
3014 const TColStd_Array1OfInteger& VMults,
3015 const Standard_Integer UDegree,
3016 const Standard_Integer VDegree,
3017 const Standard_Boolean URational,
3018 const Standard_Boolean VRational,
3019 const Standard_Boolean UPeriodic,
3020 const Standard_Boolean VPeriodic,
3021 const Standard_Real Tolerance3D,
3022 Standard_Real& UTolerance,
3023 Standard_Real& VTolerance)
3025 Standard_Real Wij,Wmj,Wji,Wjm;
3026 Standard_Real Xij,Xmj,Xji,Xjm,Xpq,Xqp;
3027 Standard_Real Yij,Ymj,Yji,Yjm,Ypq,Yqp;
3028 Standard_Real Zij,Zmj,Zji,Zjm,Zpq,Zqp;
3029 Standard_Real factor,value,min,min_weights=0,inverse,max_derivative[2];
3031 max_derivative[0] = max_derivative[1] = 0.0e0 ;
3033 Standard_Integer PRowLength, PColLength;
3034 Standard_Integer ii,jj,pp,qq,ii_index,jj_index,pp_index,qq_index;
3035 Standard_Integer ii_minus,upper[2],lower[2],poles_length[2];
3036 Standard_Integer num_poles[2],num_flat_knots[2];
3039 BSplCLib::KnotSequenceLength(UMults,
3043 BSplCLib::KnotSequenceLength(VMults,
3046 TColStd_Array1OfReal flat_knots_in_u(1,num_flat_knots[0]) ;
3047 TColStd_Array1OfReal flat_knots_in_v(1,num_flat_knots[1]) ;
3048 BSplCLib::KnotSequence(UKnots,
3053 BSplCLib::KnotSequence(VKnots,
3058 PRowLength = Poles.RowLength();
3059 PColLength = Poles.ColLength();
3060 if (URational || VRational) {
3061 Standard_Integer Wsize = PRowLength * PColLength;
3062 const TColStd_Array2OfReal& refWights = *Weights;
3063 const Standard_Real * WG = &refWights(refWights.LowerRow(), refWights.LowerCol());
3064 min_weights = WG[0];
3066 for (ii = 1 ; ii < Wsize ; ii++) {
3068 if (min_weights > min) min_weights = min;
3071 Standard_Integer UD1 = UDegree + 1;
3072 Standard_Integer VD1 = VDegree + 1;
3073 num_poles[0] = num_flat_knots[0] - UD1;
3074 num_poles[1] = num_flat_knots[1] - VD1;
3075 poles_length[0] = PColLength;
3076 poles_length[1] = PRowLength;
3078 Standard_Integer UD2 = UDegree << 1;
3079 Standard_Integer VD2 = VDegree << 1;
3081 for (ii = 2 ; ii <= num_poles[0] ; ii++) {
3082 ii_index = (ii - 1) % poles_length[0] + 1 ;
3083 ii_minus = (ii - 2) % poles_length[0] + 1 ;
3084 inverse = flat_knots_in_u(ii + UDegree) - flat_knots_in_u(ii) ;
3085 inverse = 1.0e0 / inverse ;
3086 lower[0] = ii - UD1;
3087 if (lower[0] < 1) lower[0] = 1;
3088 upper[0] = ii + UD2 + 1;
3089 if (upper[0] > num_poles[0]) upper[0] = num_poles[0];
3091 for ( jj = 1 ; jj <= num_poles[1] ; jj++) {
3092 jj_index = (jj - 1) % poles_length[1] + 1 ;
3093 lower[1] = jj - VD1;
3094 if (lower[1] < 1) lower[1] = 1;
3095 upper[1] = jj + VD2 + 1;
3096 if (upper[1] > num_poles[1]) upper[1] = num_poles[1];
3097 const gp_Pnt& Pij = Poles .Value(ii_index,jj_index);
3098 Wij = Weights->Value(ii_index,jj_index);
3099 const gp_Pnt& Pmj = Poles .Value(ii_minus,jj_index);
3100 Wmj = Weights->Value(ii_minus,jj_index);
3108 for (pp = lower[0] ; pp <= upper[0] ; pp++) {
3109 pp_index = (pp - 1) % poles_length[0] + 1 ;
3111 for (qq = lower[1] ; qq <= upper[1] ; qq++) {
3113 qq_index = (qq - 1) % poles_length[1] + 1 ;
3114 const gp_Pnt& Ppq = Poles.Value(pp_index,qq_index);
3118 factor = (Xpq - Xij) * Wij;
3119 factor -= (Xpq - Xmj) * Wmj;
3120 if (factor < 0) factor = - factor;
3122 factor = (Ypq - Yij) * Wij;
3123 factor -= (Ypq - Ymj) * Wmj;
3124 if (factor < 0) factor = - factor;
3126 factor = (Zpq - Zij) * Wij;
3127 factor -= (Zpq - Zmj) * Wmj;
3128 if (factor < 0) factor = - factor;
3131 if (max_derivative[0] < value) max_derivative[0] = value ;
3136 max_derivative[0] /= min_weights ;
3140 for (ii = 2 ; ii <= num_poles[0] ; ii++) {
3141 ii_index = (ii - 1) % poles_length[0] + 1 ;
3142 ii_minus = (ii - 2) % poles_length[0] + 1 ;
3143 inverse = flat_knots_in_u(ii + UDegree) - flat_knots_in_u(ii) ;
3144 inverse = 1.0e0 / inverse ;
3146 for ( jj = 1 ; jj <= num_poles[1] ; jj++) {
3147 jj_index = (jj - 1) % poles_length[1] + 1 ;
3149 const gp_Pnt& Pij = Poles.Value(ii_index,jj_index);
3150 const gp_Pnt& Pmj = Poles.Value(ii_minus,jj_index);
3151 factor = Pij.X() - Pmj.X();
3152 if (factor < 0) factor = - factor;
3154 factor = Pij.Y() - Pmj.Y();
3155 if (factor < 0) factor = - factor;
3157 factor = Pij.Z() - Pmj.Z();
3158 if (factor < 0) factor = - factor;
3161 if (max_derivative[0] < value) max_derivative[0] = value ;
3165 max_derivative[0] *= UDegree ;
3167 Standard_Integer UD2 = UDegree << 1;
3168 Standard_Integer VD2 = VDegree << 1;
3170 for (ii = 2 ; ii <= num_poles[1] ; ii++) {
3171 ii_index = (ii - 1) % poles_length[1] + 1 ;
3172 ii_minus = (ii - 2) % poles_length[1] + 1 ;
3173 inverse = flat_knots_in_v(ii + VDegree) - flat_knots_in_v(ii) ;
3174 inverse = 1.0e0 / inverse ;
3175 lower[0] = ii - VD1;
3176 if (lower[0] < 1) lower[0] = 1;
3177 upper[0] = ii + VD2 + 1;
3178 if (upper[0] > num_poles[1]) upper[0] = num_poles[1];
3180 for ( jj = 1 ; jj <= num_poles[0] ; jj++) {
3181 jj_index = (jj - 1) % poles_length[0] + 1 ;
3182 lower[1] = jj - UD1;
3183 if (lower[1] < 1) lower[1] = 1;
3184 upper[1] = jj + UD2 + 1;
3185 if (upper[1] > num_poles[0]) upper[1] = num_poles[0];
3186 const gp_Pnt& Pji = Poles .Value(jj_index,ii_index);
3187 Wji = Weights->Value(jj_index,ii_index);
3188 const gp_Pnt& Pjm = Poles .Value(jj_index,ii_minus);
3189 Wjm = Weights->Value(jj_index,ii_minus);
3197 for (pp = lower[1] ; pp <= upper[1] ; pp++) {
3198 pp_index = (pp - 1) % poles_length[1] + 1 ;
3200 for (qq = lower[0] ; qq <= upper[0] ; qq++) {
3202 qq_index = (qq - 1) % poles_length[0] + 1 ;
3203 const gp_Pnt& Pqp = Poles.Value(qq_index,pp_index);
3207 factor = (Xqp - Xji) * Wji;
3208 factor -= (Xqp - Xjm) * Wjm;
3209 if (factor < 0) factor = - factor;
3211 factor = (Yqp - Yji) * Wji;
3212 factor -= (Yqp - Yjm) * Wjm;
3213 if (factor < 0) factor = - factor;
3215 factor = (Zqp - Zji) * Wji;
3216 factor -= (Zqp - Zjm) * Wjm;
3217 if (factor < 0) factor = - factor;
3220 if (max_derivative[1] < value) max_derivative[1] = value ;
3225 max_derivative[1] /= min_weights ;
3229 for (ii = 2 ; ii <= num_poles[1] ; ii++) {
3230 ii_index = (ii - 1) % poles_length[1] + 1 ;
3231 ii_minus = (ii - 2) % poles_length[1] + 1 ;
3232 inverse = flat_knots_in_v(ii + VDegree) - flat_knots_in_v(ii) ;
3233 inverse = 1.0e0 / inverse ;
3235 for ( jj = 1 ; jj <= num_poles[0] ; jj++) {
3236 jj_index = (jj - 1) % poles_length[0] + 1 ;
3238 const gp_Pnt& Pji = Poles.Value(jj_index,ii_index);
3239 const gp_Pnt& Pjm = Poles.Value(jj_index,ii_minus);
3240 factor = Pji.X() - Pjm.X() ;
3241 if (factor < 0) factor = - factor;
3243 factor = Pji.Y() - Pjm.Y() ;
3244 if (factor < 0) factor = - factor;
3246 factor = Pji.Z() - Pjm.Z() ;
3247 if (factor < 0) factor = - factor;
3250 if (max_derivative[1] < value) max_derivative[1] = value ;
3254 max_derivative[1] *= VDegree ;
3255 max_derivative[0] *= M_SQRT2 ;
3256 max_derivative[1] *= M_SQRT2 ;
3257 if(max_derivative[0] && max_derivative[1]) {
3258 UTolerance = Tolerance3D / max_derivative[0] ;
3259 VTolerance = Tolerance3D / max_derivative[1] ;
3262 UTolerance=VTolerance=0.0;
3264 cout<<"ElSLib.cxx : maxderivative = 0.0 "<<endl;
3269 //=======================================================================
3270 //function : Interpolate
3272 //=======================================================================
3274 void BSplSLib::Interpolate(const Standard_Integer UDegree,
3275 const Standard_Integer VDegree,
3276 const TColStd_Array1OfReal& UFlatKnots,
3277 const TColStd_Array1OfReal& VFlatKnots,
3278 const TColStd_Array1OfReal& UParameters,
3279 const TColStd_Array1OfReal& VParameters,
3280 TColgp_Array2OfPnt& Poles,
3281 TColStd_Array2OfReal& Weights,
3282 Standard_Integer& InversionProblem)
3284 Standard_Integer ii, jj, ll, kk, dimension;
3285 Standard_Integer ULength = UParameters.Length();
3286 Standard_Integer VLength = VParameters.Length();
3287 Standard_Real * poles_array;
3289 // extraction of iso u
3290 dimension = 4*ULength;
3291 TColStd_Array2OfReal Points(1, VLength,
3294 Handle(TColStd_HArray1OfInteger) ContactOrder =
3295 new (TColStd_HArray1OfInteger)(1, VLength);
3296 ContactOrder->Init(0);
3298 for (ii=1; ii <= VLength; ii++) {
3300 for (jj=1, ll=1; jj<= ULength; jj++, ll+=4) {
3301 Points(ii,ll) = Poles(jj, ii).X();
3302 Points(ii,ll+1) = Poles(jj, ii).Y();
3303 Points(ii,ll+2) = Poles(jj, ii).Z();
3304 Points(ii,ll+3) = Weights(jj,ii) ;
3308 // interpolation of iso u
3309 poles_array = (Standard_Real *) &Points.ChangeValue(1,1) ;
3310 BSplCLib::Interpolate(VDegree,
3313 ContactOrder->Array1(),
3317 if (InversionProblem != 0) return;
3319 // extraction of iso v
3321 dimension = VLength*4;
3322 TColStd_Array2OfReal IsoPoles(1, ULength,
3325 ContactOrder = new (TColStd_HArray1OfInteger)(1, ULength);
3326 ContactOrder->Init(0);
3327 poles_array = (Standard_Real *) &IsoPoles.ChangeValue(1,1) ;
3329 for (ii=1, kk=1; ii <= ULength; ii++, kk+=4) {
3331 for (jj=1, ll=1; jj<= VLength; jj++, ll+=4) {
3332 IsoPoles (ii,ll) = Points(jj, kk);
3333 IsoPoles (ii,ll+1) = Points(jj, kk+1);
3334 IsoPoles (ii,ll+2) = Points(jj, kk+2);
3335 IsoPoles (ii,ll+3) = Points(jj, kk+3);
3338 // interpolation of iso v
3339 BSplCLib::Interpolate(UDegree,
3342 ContactOrder->Array1(),
3349 for (ii=1; ii <= ULength; ii++) {
3351 for (jj=1, ll=1; jj<= VLength; jj++, ll+=4) {
3352 gp_Pnt Pnt(IsoPoles(ii,ll), IsoPoles(ii,ll+1), IsoPoles(ii,ll+2));
3353 Poles.SetValue(ii, jj, Pnt);
3354 Weights.SetValue(ii,jj,IsoPoles(ii,ll+3)) ;
3359 //=======================================================================
3360 //function : Interpolate
3362 //=======================================================================
3364 void BSplSLib::Interpolate(const Standard_Integer UDegree,
3365 const Standard_Integer VDegree,
3366 const TColStd_Array1OfReal& UFlatKnots,
3367 const TColStd_Array1OfReal& VFlatKnots,
3368 const TColStd_Array1OfReal& UParameters,
3369 const TColStd_Array1OfReal& VParameters,
3370 TColgp_Array2OfPnt& Poles,
3371 Standard_Integer& InversionProblem)
3373 Standard_Integer ii, jj, ll, kk, dimension;
3374 Standard_Integer ULength = UParameters.Length();
3375 Standard_Integer VLength = VParameters.Length();
3376 Standard_Real * poles_array;
3378 // extraction of iso u
3379 dimension = 3*ULength;
3380 TColStd_Array2OfReal Points(1, VLength,
3383 Handle(TColStd_HArray1OfInteger) ContactOrder =
3384 new (TColStd_HArray1OfInteger)(1, VLength);
3385 ContactOrder->Init(0);
3387 for (ii=1; ii <= VLength; ii++) {
3389 for (jj=1, ll=1; jj<= ULength; jj++, ll+=3) {
3390 Points(ii,ll) = Poles(jj, ii).X();
3391 Points(ii,ll+1) = Poles(jj, ii).Y();
3392 Points(ii,ll+2) = Poles(jj, ii).Z();
3396 // interpolation of iso u
3397 poles_array = (Standard_Real *) &Points.ChangeValue(1,1) ;
3398 BSplCLib::Interpolate(VDegree,
3401 ContactOrder->Array1(),
3405 if (InversionProblem != 0) return;
3407 // extraction of iso v
3409 dimension = VLength*3;
3410 TColStd_Array2OfReal IsoPoles(1, ULength,
3413 ContactOrder = new (TColStd_HArray1OfInteger)(1, ULength);
3414 ContactOrder->Init(0);
3415 poles_array = (Standard_Real *) &IsoPoles.ChangeValue(1,1) ;
3417 for (ii=1, kk=1; ii <= ULength; ii++, kk+=3) {
3419 for (jj=1, ll=1; jj<= VLength; jj++, ll+=3) {
3420 IsoPoles (ii,ll) = Points(jj, kk);
3421 IsoPoles (ii,ll+1) = Points(jj, kk+1);
3422 IsoPoles (ii,ll+2) = Points(jj, kk+2);
3425 // interpolation of iso v
3426 BSplCLib::Interpolate(UDegree,
3429 ContactOrder->Array1(),
3436 for (ii=1; ii <= ULength; ii++) {
3438 for (jj=1, ll=1; jj<= VLength; jj++, ll+=3) {
3439 gp_Pnt Pnt(IsoPoles(ii,ll), IsoPoles(ii,ll+1), IsoPoles(ii,ll+2));
3440 Poles.SetValue(ii, jj, Pnt);
3445 //=======================================================================
3446 //function : FunctionMultiply
3448 //=======================================================================
3450 void BSplSLib::FunctionMultiply
3451 (const BSplSLib_EvaluatorFunction& Function,
3452 const Standard_Integer UBSplineDegree,
3453 const Standard_Integer VBSplineDegree,
3454 const TColStd_Array1OfReal& UBSplineKnots,
3455 const TColStd_Array1OfReal& VBSplineKnots,
3456 const TColStd_Array1OfInteger * UMults,
3457 const TColStd_Array1OfInteger * VMults,
3458 const TColgp_Array2OfPnt& Poles,
3459 const TColStd_Array2OfReal* Weights,
3460 const TColStd_Array1OfReal& UFlatKnots,
3461 const TColStd_Array1OfReal& VFlatKnots,
3462 const Standard_Integer UNewDegree,
3463 const Standard_Integer VNewDegree,
3464 TColgp_Array2OfPnt& NewNumerator,
3465 TColStd_Array2OfReal& NewDenominator,
3466 Standard_Integer& Status)
3468 Standard_Integer num_uparameters,
3473 Standard_Real result ;
3475 num_uparameters = UFlatKnots.Length() - UNewDegree - 1 ;
3476 num_vparameters = VFlatKnots.Length() - VNewDegree - 1 ;
3477 TColStd_Array1OfReal UParameters(1,num_uparameters) ;
3478 TColStd_Array1OfReal VParameters(1,num_vparameters) ;
3480 if ((NewNumerator.ColLength() == num_uparameters) &&
3481 (NewNumerator.RowLength() == num_vparameters) &&
3482 (NewDenominator.ColLength() == num_uparameters) &&
3483 (NewDenominator.RowLength() == num_vparameters)) {
3486 BSplCLib::BuildSchoenbergPoints(UNewDegree,
3490 BSplCLib::BuildSchoenbergPoints(VNewDegree,
3494 for (ii = 1 ; ii <= num_uparameters ; ii++) {
3496 for (jj = 1 ; jj <= num_vparameters ; jj++) {
3497 HomogeneousD0(UParameters(ii),
3513 NewDenominator(ii,jj),
3514 NewNumerator(ii,jj)) ;
3516 Function.Evaluate (0,
3522 Standard_ConstructionError::Raise();
3524 gp_Pnt& P = NewNumerator(ii,jj);
3525 P.SetX(P.X() * result);
3526 P.SetY(P.Y() * result);
3527 P.SetZ(P.Z() * result);
3528 NewDenominator(ii,jj) *= result ;
3531 Interpolate(UNewDegree,
3542 Standard_ConstructionError::Raise();