1 // Created on: 1993-10-06
2 // Created by: Bruno DUMORTIER
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.
18 #include <BSplCLib.hxx>
19 #include <Geom_BSplineCurve.hxx>
20 #include <Geom_BSplineSurface.hxx>
21 #include <GeomFill_BSplineCurves.hxx>
22 #include <GeomFill_Coons.hxx>
23 #include <GeomFill_Curved.hxx>
24 #include <GeomFill_Filling.hxx>
25 #include <GeomFill_Stretch.hxx>
26 #include <Precision.hxx>
27 #include <Standard_ConstructionError.hxx>
28 #include <Standard_NotImplemented.hxx>
29 #include <TColgp_Array1OfPnt.hxx>
30 #include <TColgp_Array2OfPnt.hxx>
31 #include <TColStd_Array1OfInteger.hxx>
32 #include <TColStd_Array1OfReal.hxx>
33 #include <TColStd_Array2OfReal.hxx>
35 //=======================================================================
37 //purpose : Internal Use Only
38 // This function is used to prepare the Filling: The Curves
39 // are arranged in this way:
50 //=======================================================================
51 Standard_Boolean Arrange(const Handle(Geom_BSplineCurve)& C1,
52 const Handle(Geom_BSplineCurve)& C2,
53 const Handle(Geom_BSplineCurve)& C3,
54 const Handle(Geom_BSplineCurve)& C4,
55 Handle(Geom_BSplineCurve)& CC1,
56 Handle(Geom_BSplineCurve)& CC2,
57 Handle(Geom_BSplineCurve)& CC3,
58 Handle(Geom_BSplineCurve)& CC4,
59 const Standard_Real Tol )
61 Handle(Geom_BSplineCurve) GC[4];
62 Handle(Geom_BSplineCurve) Dummy;
63 GC[0] = Handle(Geom_BSplineCurve)::DownCast(C1->Copy());
64 GC[1] = Handle(Geom_BSplineCurve)::DownCast(C2->Copy());
65 GC[2] = Handle(Geom_BSplineCurve)::DownCast(C3->Copy());
66 GC[3] = Handle(Geom_BSplineCurve)::DownCast(C4->Copy());
69 Standard_Boolean Trouve;
71 for (i=1; i<=3; i++) {
72 Trouve = Standard_False;
73 for ( j=i; j<=3 && !Trouve; j++) {
74 if (GC[j]->StartPoint().Distance( GC[i-1]->EndPoint()) < Tol) {
78 Trouve = Standard_True;
80 else if (GC[j]->EndPoint().Distance( GC[i-1]->EndPoint()) < Tol) {
81 GC[j] = Handle(Geom_BSplineCurve)::DownCast(GC[j]->Reversed());
85 Trouve = Standard_True;
88 if (!Trouve) return Standard_False;
93 CC3 = Handle(Geom_BSplineCurve)::DownCast( GC[2]->Reversed());
94 CC4 = Handle(Geom_BSplineCurve)::DownCast( GC[3]->Reversed());
101 //=======================================================================
102 //function : SetSameDistribution
103 //purpose : Internal Use Only
104 //=======================================================================
106 Standard_Integer SetSameDistribution(Handle(Geom_BSplineCurve)& C1,
107 Handle(Geom_BSplineCurve)& C2 )
109 Standard_Integer nbp1 = C1->NbPoles();
110 Standard_Integer nbk1 = C1->NbKnots();
111 TColgp_Array1OfPnt P1(1,nbp1);
112 TColStd_Array1OfReal W1(1,nbp1);
114 TColStd_Array1OfReal K1(1,nbk1);
115 TColStd_Array1OfInteger M1(1,nbk1);
118 if( C1->IsRational())
121 C1->Multiplicities(M1);
123 Standard_Integer nbp2 = C2->NbPoles();
124 Standard_Integer nbk2 = C2->NbKnots();
125 TColgp_Array1OfPnt P2(1,nbp2);
126 TColStd_Array1OfReal W2(1,nbp2);
128 TColStd_Array1OfReal K2(1,nbk2);
129 TColStd_Array1OfInteger M2(1,nbk2);
132 if( C2->IsRational())
135 C2->Multiplicities(M2);
137 Standard_Real K11 = K1( 1 );
138 Standard_Real K12 = K1(nbk1);
139 Standard_Real K21 = K2( 1 );
140 Standard_Real K22 = K2(nbk2);
142 if ( (K12-K11) > (K22-K21)) {
143 BSplCLib::Reparametrize( K11, K12, K2);
146 else if ( (K12-K11) < (K22-K21)) {
147 BSplCLib::Reparametrize( K21, K22, K1);
150 else if(Abs(K12-K11) > Precision::PConfusion()) {
151 BSplCLib::Reparametrize( K11, K12, K2);
155 Standard_Integer NP,NK;
156 if ( BSplCLib::PrepareInsertKnots(C1->Degree(),Standard_False,
157 K1,M1,K2,&M2,NP,NK,Precision::PConfusion(),
159 TColgp_Array1OfPnt NewP(1, NP);
160 TColStd_Array1OfReal NewW(1, NP);
161 TColStd_Array1OfReal NewK(1, NK);
162 TColStd_Array1OfInteger NewM(1, NK);
163 BSplCLib::InsertKnots(C1->Degree(),Standard_False,
165 NewP,&NewW,NewK,NewM,Precision::PConfusion(),
167 if ( C1->IsRational()) {
168 C1 = new Geom_BSplineCurve(NewP,NewW,NewK,NewM,C1->Degree());
171 C1 = new Geom_BSplineCurve(NewP,NewK,NewM,C1->Degree());
173 BSplCLib::InsertKnots(C2->Degree(),Standard_False,
175 NewP,&NewW,NewK,NewM,Precision::PConfusion(),
177 if ( C2->IsRational()) {
178 C2 = new Geom_BSplineCurve(NewP,NewW,NewK,NewM,C2->Degree());
181 C2 = new Geom_BSplineCurve(NewP,NewK,NewM,C2->Degree());
185 throw Standard_ConstructionError(" ");
188 return C1->NbPoles();
192 //=======================================================================
193 //function : GeomFill_BSplineCurves
195 //=======================================================================
197 GeomFill_BSplineCurves::GeomFill_BSplineCurves()
202 //=======================================================================
203 //function : GeomFill_BSplineCurves
205 //=======================================================================
207 GeomFill_BSplineCurves::GeomFill_BSplineCurves
208 (const Handle(Geom_BSplineCurve)& C1,
209 const Handle(Geom_BSplineCurve)& C2,
210 const Handle(Geom_BSplineCurve)& C3,
211 const Handle(Geom_BSplineCurve)& C4,
212 const GeomFill_FillingStyle Type )
214 Init( C1, C2, C3, C4, Type);
218 //=======================================================================
219 //function : GeomFill_BSplineCurves
221 //=======================================================================
223 GeomFill_BSplineCurves::GeomFill_BSplineCurves
224 (const Handle(Geom_BSplineCurve)& C1,
225 const Handle(Geom_BSplineCurve)& C2,
226 const Handle(Geom_BSplineCurve)& C3,
227 const GeomFill_FillingStyle Type )
229 Init( C1, C2, C3, Type);
233 //=======================================================================
234 //function : GeomFill_BSplineCurves
236 //=======================================================================
238 GeomFill_BSplineCurves::GeomFill_BSplineCurves
239 (const Handle(Geom_BSplineCurve)& C1,
240 const Handle(Geom_BSplineCurve)& C2,
241 const GeomFill_FillingStyle Type )
247 //=======================================================================
250 //=======================================================================
252 void GeomFill_BSplineCurves::Init
253 (const Handle(Geom_BSplineCurve)& C1,
254 const Handle(Geom_BSplineCurve)& C2,
255 const Handle(Geom_BSplineCurve)& C3,
256 const Handle(Geom_BSplineCurve)& C4,
257 const GeomFill_FillingStyle Type )
259 // On ordonne les courbes
260 Handle(Geom_BSplineCurve) CC1, CC2, CC3, CC4;
262 Standard_Real Tol = Precision::Confusion();
264 Standard_Boolean IsOK =
266 Arrange( C1, C2, C3, C4, CC1, CC2, CC3, CC4, Tol);
268 Standard_ConstructionError_Raise_if
269 (!IsOK, " GeomFill_BSplineCurves: Courbes non jointives");
271 // Mise en conformite des degres
272 Standard_Integer Deg1 = CC1->Degree();
273 Standard_Integer Deg2 = CC2->Degree();
274 Standard_Integer Deg3 = CC3->Degree();
275 Standard_Integer Deg4 = CC4->Degree();
276 Standard_Integer DegU = Max( Deg1, Deg3);
277 Standard_Integer DegV = Max( Deg2, Deg4);
278 if ( Deg1 < DegU) CC1->IncreaseDegree(DegU);
279 if ( Deg2 < DegV) CC2->IncreaseDegree(DegV);
280 if ( Deg3 < DegU) CC3->IncreaseDegree(DegU);
281 if ( Deg4 < DegV) CC4->IncreaseDegree(DegV);
283 // Mise en conformite des distributions de noeuds
284 Standard_Integer NbUPoles = SetSameDistribution(CC1,CC3);
285 Standard_Integer NbVPoles = SetSameDistribution(CC2,CC4);
287 if(Type == GeomFill_CoonsStyle) {
288 if(NbUPoles < 4 || NbVPoles < 4)
289 throw Standard_ConstructionError("GeomFill_BSplineCurves: invalid filling style");
292 TColgp_Array1OfPnt P1(1,NbUPoles);
293 TColgp_Array1OfPnt P2(1,NbVPoles);
294 TColgp_Array1OfPnt P3(1,NbUPoles);
295 TColgp_Array1OfPnt P4(1,NbVPoles);
301 // Traitement des courbes rationelles
302 Standard_Boolean isRat = ( CC1->IsRational() || CC2->IsRational() ||
303 CC3->IsRational() || CC4->IsRational() );
305 TColStd_Array1OfReal W1(1,NbUPoles);
306 TColStd_Array1OfReal W3(1,NbUPoles);
307 TColStd_Array1OfReal W2(1,NbVPoles);
308 TColStd_Array1OfReal W4(1,NbVPoles);
314 if (CC1->IsRational()) {
317 if (CC2->IsRational()) {
320 if (CC3->IsRational()) {
323 if (CC4->IsRational()) {
328 GeomFill_Filling Caro;
332 case GeomFill_StretchStyle :
333 Caro = GeomFill_Stretch( P1, P2, P3, P4, W1, W2, W3, W4);
335 case GeomFill_CoonsStyle :
336 Caro = GeomFill_Coons ( P1, P4, P3, P2, W1, W4, W3, W2);
338 case GeomFill_CurvedStyle :
339 Caro = GeomFill_Curved ( P1, P2, P3, P4, W1, W2, W3, W4);
346 case GeomFill_StretchStyle :
347 Caro = GeomFill_Stretch( P1, P2, P3, P4);
349 case GeomFill_CoonsStyle :
350 Caro = GeomFill_Coons ( P1, P4, P3, P2);
352 case GeomFill_CurvedStyle :
353 Caro = GeomFill_Curved ( P1, P2, P3, P4);
358 NbUPoles = Caro.NbUPoles();
359 NbVPoles = Caro.NbVPoles();
360 TColgp_Array2OfPnt Poles(1,NbUPoles,1,NbVPoles);
363 // Creation de la surface
364 Standard_Integer NbUKnot = CC1->NbKnots();
365 TColStd_Array1OfReal UKnots(1,NbUKnot);
366 TColStd_Array1OfInteger UMults(1,NbUKnot);
368 CC1->Multiplicities(UMults);
370 Standard_Integer NbVKnot = CC2->NbKnots();
371 TColStd_Array1OfReal VKnots(1,NbVKnot);
372 TColStd_Array1OfInteger VMults(1,NbVKnot);
374 CC2->Multiplicities(VMults);
378 if (Caro.isRational()) {
379 TColStd_Array2OfReal Weights(1,NbUPoles, 1,NbVPoles);
380 Caro.Weights(Weights);
381 mySurface = new Geom_BSplineSurface(Poles , Weights,
384 CC1->Degree(), CC2->Degree());
387 mySurface = new Geom_BSplineSurface(Poles ,
390 CC1->Degree(), CC2->Degree());
396 //=======================================================================
399 //=======================================================================
401 void GeomFill_BSplineCurves::Init
402 (const Handle(Geom_BSplineCurve)& C1,
403 const Handle(Geom_BSplineCurve)& C2,
404 const Handle(Geom_BSplineCurve)& C3,
405 const GeomFill_FillingStyle Type )
407 Handle(Geom_BSplineCurve) C4;
408 TColgp_Array1OfPnt Poles(1,2);
409 TColStd_Array1OfReal Knots(1,2);
410 TColStd_Array1OfInteger Mults(1,2);
411 Standard_Real Tol = Precision::Confusion();
413 if(C1->StartPoint().SquareDistance(C2->StartPoint()) > Tol &&
414 C1->StartPoint().SquareDistance(C2->EndPoint()) > Tol )
415 Poles( 1) = C1->StartPoint();
417 Poles( 1) = C1->EndPoint();
419 if(C3->StartPoint().SquareDistance(C2->StartPoint()) > Tol &&
420 C3->StartPoint().SquareDistance(C2->EndPoint()) > Tol )
421 Poles( 2) = C3->StartPoint();
423 Poles( 2) = C3->EndPoint();
425 Knots( 1) = C2->Knot(C2->FirstUKnotIndex());
426 Knots( 2) = C2->Knot(C2->LastUKnotIndex());
427 Mults( 1) = Mults( 2) = 2;
428 C4 = new Geom_BSplineCurve( Poles, Knots, Mults, 1);
429 Init( C1, C2, C3, C4, Type);
433 //=======================================================================
436 //=======================================================================
438 void GeomFill_BSplineCurves::Init
439 (const Handle(Geom_BSplineCurve)& C1,
440 const Handle(Geom_BSplineCurve)& C2,
441 const GeomFill_FillingStyle Type )
443 Handle(Geom_BSplineCurve)
444 CC1 = Handle(Geom_BSplineCurve)::DownCast(C1->Copy());
445 Handle(Geom_BSplineCurve)
446 CC2 = Handle(Geom_BSplineCurve)::DownCast(C2->Copy());
448 Standard_Integer Deg1 = CC1->Degree();
449 Standard_Integer Deg2 = CC2->Degree();
451 Standard_Boolean isRat = ( CC1->IsRational() || CC2->IsRational());
453 if ( Type != GeomFill_CurvedStyle) {
454 Standard_Integer DegU = Max( Deg1, Deg2);
456 if ( CC1->Degree() < DegU ) CC1->IncreaseDegree(DegU);
457 if ( CC2->Degree() < DegU ) CC2->IncreaseDegree(DegU);
459 // Mise en conformite des distributions de noeuds
460 Standard_Integer NbPoles = SetSameDistribution(CC1,CC2);
461 TColgp_Array2OfPnt Poles(1,NbPoles, 1,2);
462 TColgp_Array1OfPnt P1( 1, NbPoles);
463 TColgp_Array1OfPnt P2( 1, NbPoles);
467 for (i=1; i<=NbPoles; i++) {
471 Standard_Integer NbUKnots = CC1->NbKnots();
472 TColStd_Array1OfReal UKnots( 1, NbUKnots);
473 TColStd_Array1OfInteger UMults( 1, NbUKnots);
475 CC1->Multiplicities(UMults);
476 // Standard_Integer NbVKnots = 2;
477 TColStd_Array1OfReal VKnots( 1, 2);
478 TColStd_Array1OfInteger VMults( 1, 2);
485 // Traitement des courbes rationelles
487 TColStd_Array2OfReal Weights(1,NbPoles, 1,2);
488 TColStd_Array1OfReal W1(1,NbPoles);
489 TColStd_Array1OfReal W2(1,NbPoles);
494 if (CC1->IsRational()) {
497 if (CC2->IsRational()) {
500 for (i=1; i<=NbPoles; i++) {
501 Weights(i, 1) = W1( i);
502 Weights(i, 2) = W2( i);
505 mySurface = new Geom_BSplineSurface(Poles , Weights,
513 mySurface = new Geom_BSplineSurface(Poles ,
520 Standard_Real Eps = Precision::Confusion();
521 Standard_Boolean IsOK = Standard_False;
522 if ( CC1->StartPoint().IsEqual(CC2->StartPoint(),Eps)) {
523 IsOK = Standard_True;
525 else if ( CC1->StartPoint().IsEqual(CC2->EndPoint(),Eps)) {
527 IsOK = Standard_True;
529 else if ( CC1->EndPoint().IsEqual(CC2->StartPoint(),Eps)) {
531 IsOK = Standard_True;
533 else if ( CC1->EndPoint().IsEqual(CC2->EndPoint(),Eps)) {
536 IsOK = Standard_True;
540 throw Standard_OutOfRange("GeomFill_BSplineCurves: Courbes non jointives");
542 Standard_Integer NbUPoles = CC1->NbPoles();
543 Standard_Integer NbVPoles = CC2->NbPoles();
544 TColgp_Array1OfPnt P1(1,NbUPoles);
545 TColgp_Array1OfPnt P2(1,NbVPoles);
549 Standard_Integer NbUKnots = CC1->NbKnots();
550 Standard_Integer NbVKnots = CC2->NbKnots();
551 TColStd_Array1OfReal UKnots(1,NbUKnots);
552 TColStd_Array1OfReal VKnots(1,NbVKnots);
553 TColStd_Array1OfInteger UMults(1,NbUKnots);
554 TColStd_Array1OfInteger VMults(1,NbVKnots);
556 CC1->Multiplicities(UMults);
558 CC2->Multiplicities(VMults);
560 TColStd_Array1OfReal W1(1,NbUPoles);
561 TColStd_Array1OfReal W2(1,NbVPoles);
565 GeomFill_Filling Caro;
567 if (CC1->IsRational()) {
570 if (CC2->IsRational()) {
573 Caro = GeomFill_Curved( P1, P2, W1, W2);
576 Caro = GeomFill_Curved( P1, P2);
579 NbUPoles = Caro.NbUPoles();
580 NbVPoles = Caro.NbVPoles();
581 TColgp_Array2OfPnt Poles(1,NbUPoles,1,NbVPoles);
585 if (Caro.isRational()) {
586 TColStd_Array2OfReal Weights(1,NbUPoles, 1,NbVPoles);
587 Caro.Weights(Weights);
588 mySurface = new Geom_BSplineSurface(Poles , Weights,
592 Standard_False, Standard_False);
595 mySurface = new Geom_BSplineSurface(Poles ,
599 Standard_False, Standard_False);