1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <AppDef_MultiLine.hxx>
16 #include <AppDef_MultiPointConstraint.hxx>
17 #include <AppParCurves_MultiBSpCurve.hxx>
18 #include <AppParCurves_MultiCurve.hxx>
19 #include <AppDef_BSplineCompute.hxx>
20 #include <AppDef_Compute.hxx>
21 #include <AppParCurves_Constraint.hxx>
22 #include <Approx_MCurvesToBSpCurve.hxx>
23 #include <TColgp_Array1OfPnt.hxx>
24 #include <TColgp_Array1OfPnt2d.hxx>
25 #include <TColgp_Array1OfVec.hxx>
26 #include <TColgp_Array1OfVec2d.hxx>
28 #include <gp_Vec2d.hxx>
30 #include <gp_Pnt2d.hxx>
31 #include <math_Vector.hxx>
32 #include <BSplCLib.hxx>
34 #include <StdFail_NotDone.hxx>
35 #include <AppParCurves_HArray1OfConstraintCouple.hxx>
36 #include <AppDef_Variational.hxx>
38 static Standard_Boolean scal = 1;
39 extern Standard_Boolean AppBlend_GetContextSplineApprox();
40 extern Standard_Boolean AppBlend_GetContextApproxWithNoTgt();
42 // modified by EAP (Edward AGAPOV) Fri Jan 4 2002, bug OCC9
43 // --- keep pipe parametrized like path
46 //=======================================================================
47 //function : AppBlend_AppSurf
49 //=======================================================================
51 AppBlend_AppSurf::AppBlend_AppSurf ():done(Standard_False) {}
54 //=======================================================================
55 //function : AppBlend_AppSurf
57 //=======================================================================
59 AppBlend_AppSurf::AppBlend_AppSurf (const Standard_Integer Degmin,
60 const Standard_Integer Degmax,
61 const Standard_Real Tol3d,
62 const Standard_Real Tol2d,
63 const Standard_Integer NbIt,
64 const Standard_Boolean KnownParameters):
65 done(Standard_False),dmin(Degmin),dmax(Degmax),
66 tol3d(Tol3d),tol2d(Tol2d),nbit(NbIt),knownp(KnownParameters)
68 continuity = GeomAbs_C2;
69 paramtype = Approx_ChordLength;
75 //=======================================================================
78 //=======================================================================
80 void AppBlend_AppSurf::Init (const Standard_Integer Degmin,
81 const Standard_Integer Degmax,
82 const Standard_Real Tol3d,
83 const Standard_Real Tol2d,
84 const Standard_Integer NbIt,
85 const Standard_Boolean KnownParameters)
87 done = Standard_False;
93 knownp = KnownParameters;
94 continuity = GeomAbs_C2;
95 paramtype = Approx_ChordLength;
101 //=======================================================================
102 //function : CriteriumWeight
103 //purpose : returns the Weights associed to the criterium used in
105 //=======================================================================
107 void AppBlend_AppSurf::CriteriumWeight(Standard_Real& W1, Standard_Real& W2, Standard_Real& W3) const
111 W3 = critweights[2] ;
113 //=======================================================================
114 //function : SetCriteriumWeight
116 //=======================================================================
118 void AppBlend_AppSurf::SetCriteriumWeight(const Standard_Real W1, const Standard_Real W2, const Standard_Real W3)
120 if (W1 < 0 || W2 < 0 || W3 < 0 ) throw Standard_DomainError();
125 //=======================================================================
126 //function : SetContinuity
128 //=======================================================================
130 void AppBlend_AppSurf::SetContinuity (const GeomAbs_Shape TheCont)
132 continuity = TheCont;
135 //=======================================================================
136 //function : Continuity
138 //=======================================================================
140 GeomAbs_Shape AppBlend_AppSurf::Continuity () const
145 //=======================================================================
146 //function : SetParType
148 //=======================================================================
150 void AppBlend_AppSurf::SetParType (const Approx_ParametrizationType ParType)
155 //=======================================================================
158 //=======================================================================
160 Approx_ParametrizationType AppBlend_AppSurf::ParType () const
166 //=======================================================================
169 //=======================================================================
171 void AppBlend_AppSurf::Perform(const Handle(TheLine)& Lin,
172 TheSectionGenerator& F,
173 const Standard_Boolean SpApprox)
176 InternalPerform(Lin, F, SpApprox, Standard_False);
179 //=======================================================================
180 //function : PerformSmoothing
182 //=======================================================================
184 void AppBlend_AppSurf::PerformSmoothing(const Handle(TheLine)& Lin,
185 TheSectionGenerator& F)
188 InternalPerform(Lin, F, Standard_True, Standard_True);
191 //=======================================================================
192 //function : InternalPerform
194 //=======================================================================
196 void AppBlend_AppSurf::InternalPerform(const Handle(TheLine)& Lin,
197 TheSectionGenerator& F,
198 const Standard_Boolean SpApprox,
199 const Standard_Boolean UseSmoothing)
202 done = Standard_False;
203 if (Lin.IsNull()) {return;}
204 Standard_Integer i,j,k,NbPoint;
205 Standard_Integer NbUPoles,NbUKnots,NbPoles2d,NbVPoles;
206 Standard_Boolean withderiv;
207 AppParCurves_Constraint Cfirst,Clast;
209 Standard_Real mytol3d,mytol2d;
214 NbPoint=Lin->NbPoints();
215 AppDef_MultiPointConstraint multP;
216 AppDef_MultiLine multL(NbPoint);
218 F.GetShape(NbUPoles,NbUKnots,udeg,NbPoles2d);
220 tabUKnots = new TColStd_HArray1OfReal (1,NbUKnots);
221 tabUMults = new TColStd_HArray1OfInteger (1,NbUKnots);
223 F.Knots(tabUKnots->ChangeArray1());
224 F.Mults(tabUMults->ChangeArray1());
226 TColgp_Array1OfPnt tabAppP(1,NbUPoles);
227 TColgp_Array1OfVec tabAppV(1,NbUPoles);
229 TColgp_Array1OfPnt2d tabP2d(1,Max(1,NbPoles2d));
230 TColgp_Array1OfVec2d tabV2d(1,Max(1,NbPoles2d));
232 TColStd_Array1OfReal tabW(1,NbUPoles),tabDW(1,NbUPoles);
234 TColgp_Array1OfPnt2d tabAppP2d(1,NbPoles2d+NbUPoles); // points2d + poids
235 TColgp_Array1OfVec2d tabAppV2d(1,NbPoles2d+NbUPoles);
238 AppParCurves_MultiBSpCurve multC;
240 // Standard_Boolean SpApprox = Standard_False;
242 withderiv = F.Section(Lin->Point(1),tabAppP,tabAppV,tabP2d,tabV2d,
245 if(AppBlend_GetContextApproxWithNoTgt()) withderiv = Standard_False;
247 for (j=1; j<=NbPoles2d; j++) {
248 tabAppP2d(j) = tabP2d(j);
250 tabAppV2d(j) = tabV2d(j);
253 for (j=1; j<=NbUPoles; j++) {
254 // pour les courbes rationnelles il faut multiplier les poles par
255 // leurs poids respectifs
257 tabAppV2d(NbPoles2d+j).SetCoord(tabDW(j),0.);
258 newDv.SetLinearForm(tabDW(j),tabAppP(j).XYZ(),tabW(j),tabAppV(j).XYZ());
259 tabAppV(j).SetXYZ(newDv);
261 tabAppP(j).SetXYZ(tabAppP(j).XYZ() * tabW(j));
262 tabAppP2d(NbPoles2d+j).SetCoord(tabW(j),0.);
266 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d,tabAppV,tabAppV2d);
267 Cfirst = AppParCurves_TangencyPoint;
270 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d);
271 Cfirst = AppParCurves_PassPoint;
273 multL.SetValue(1,multP);
275 for (i=2; i<=NbPoint-1; i++) {
277 F.Section(Lin->Point(i),tabAppP,tabP2d,tabW);
278 for (j=1; j<=NbPoles2d; j++) {
279 tabAppP2d(j) = tabP2d(j);
281 for (j=1; j<=NbUPoles; j++) {
282 // pour les courbes rationnelles il faut multiplier les poles par
283 // leurs poids respectifs
284 tabAppP(j).SetXYZ(tabAppP(j).XYZ() * tabW(j));
285 tabAppP2d(NbPoles2d+j).SetCoord(tabW(j),0.);
287 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d);
288 multL.SetValue(i,multP);
290 // ***********************
292 withderiv = F.Section(Lin->Point(i),tabAppP,tabAppV,tabP2d,tabV2d,
294 if(AppBlend_GetContextApproxWithNoTgt()) withderiv = Standard_False;
296 for (j=1; j<=NbPoles2d; j++) {
297 tabAppP2d(j) = tabP2d(j);
299 tabAppV2d(j) = tabV2d(j);
302 for (j=1; j<=NbUPoles; j++) {
303 // pour les courbes rationnelles il faut multiplier les poles par
304 // leurs poids respectifs
306 tabAppV2d(NbPoles2d+j).SetCoord(tabDW(j),0.);
307 newDv.SetLinearForm(tabDW(j),tabAppP(j).XYZ(),tabW(j),tabAppV(j).XYZ());
308 tabAppV(j).SetXYZ(newDv);
310 tabAppP(j).SetXYZ(tabAppP(j).XYZ() * tabW(j));
311 tabAppP2d(NbPoles2d+j).SetCoord(tabW(j),0.);
314 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d,tabAppV,tabAppV2d);
317 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d);
319 multL.SetValue(i,multP);
321 // ******************************
324 withderiv = F.Section(Lin->Point(NbPoint),tabAppP,tabAppV,tabP2d,tabV2d,
326 if(AppBlend_GetContextApproxWithNoTgt()) withderiv = Standard_False;
328 for (j=1; j<=NbPoles2d; j++) {
329 tabAppP2d(j) = tabP2d(j);
331 tabAppV2d(j) = tabV2d(j);
334 for (j=1; j<=NbUPoles; j++) {
335 // pour les courbes rationnelles il faut multiplier les poles par
336 // leurs poids respectifs
338 tabAppV2d(NbPoles2d+j).SetCoord(tabDW(j),0.);
339 newDv.SetLinearForm(tabDW(j),tabAppP(j).XYZ(),tabW(j),tabAppV(j).XYZ());
340 tabAppV(j).SetXYZ(newDv);
342 tabAppP(j).SetXYZ(tabAppP(j).XYZ() * tabW(j));
343 tabAppP2d(NbPoles2d+j).SetCoord(tabW(j),0.);
347 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d,tabAppV,tabAppV2d);
348 Clast = AppParCurves_TangencyPoint;
351 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d);
352 Clast = AppParCurves_PassPoint;
354 multL.SetValue(NbPoint,multP);
356 //IFV 04.06.07 occ13904
359 if(Cfirst == AppParCurves_PassPoint && Clast == AppParCurves_PassPoint) {
366 AppDef_Compute theapprox (dmin,dmax,tol3d,tol2d,nbit, Standard_True, paramtype);
368 math_Vector theParams(1,NbPoint);
370 // On recale les parametres entre 0 et 1.
372 theParams(NbPoint) = 1.;
373 Standard_Real Uf = F.Parameter(Lin->Point(1));
374 Standard_Real Ul = F.Parameter(Lin->Point(NbPoint))-Uf;
375 for (i=2; i<NbPoint; i++) {
376 theParams(i) = (F.Parameter(Lin->Point(i))-Uf)/Ul;;
378 AppDef_Compute theAppDef(theParams,dmin,dmax,tol3d,tol2d,nbit,
379 Standard_True, Standard_True);
380 theapprox = theAppDef;
382 theapprox.SetConstraints(Cfirst,Clast);
383 theapprox.Perform(multL);
385 Standard_Real TheTol3d, TheTol2d;
386 mytol3d = mytol2d = 0.0;
387 for (Standard_Integer Index=1; Index<=theapprox.NbMultiCurves(); Index++) {
388 theapprox.Error(Index, TheTol3d, TheTol2d);
389 mytol3d = Max(TheTol3d, mytol3d);
390 mytol2d = Max(TheTol2d, mytol2d);
393 cout << " Tolerances obtenues --> 3d : "<< mytol3d << endl;
394 cout << " --> 2d : "<< mytol2d << endl;
396 multC = theapprox.SplineValue();
401 Standard_Boolean UseSquares = Standard_False;
402 if(nbit == 0) UseSquares = Standard_True;
403 AppDef_BSplineCompute theapprox (dmin,dmax,tol3d,tol2d,nbit,Standard_True, paramtype,
405 if(continuity == GeomAbs_C0) {
406 theapprox.SetContinuity(0);
408 if(continuity == GeomAbs_C1) {
409 theapprox.SetContinuity(1);
411 else if(continuity == GeomAbs_C2) {
412 theapprox.SetContinuity(2);
415 theapprox.SetContinuity(3);
418 theapprox.SetConstraints(Cfirst,Clast);
421 math_Vector theParams(1,NbPoint);
422 // On recale les parametres entre 0 et 1.
424 theParams(NbPoint) = 1.;
425 Standard_Real Uf = F.Parameter(Lin->Point(1));
426 Standard_Real Ul = F.Parameter(Lin->Point(NbPoint))-Uf;
427 for (i=2; i<NbPoint; i++) {
428 theParams(i) = (F.Parameter(Lin->Point(i))-Uf)/Ul;;
431 theapprox.Init(dmin,dmax,tol3d,tol2d,nbit,Standard_True,
432 Approx_IsoParametric,Standard_True);
433 theapprox.SetParameters(theParams);
435 theapprox.Perform(multL);
436 theapprox.Error(mytol3d,mytol2d);
438 cout << " Tolerances obtenues --> 3d : "<< mytol3d << endl;
439 cout << " --> 2d : "<< mytol2d << endl;
441 tol3dreached = mytol3d;
442 tol2dreached = mytol2d;
443 multC = theapprox.Value();
447 Handle(AppParCurves_HArray1OfConstraintCouple) TABofCC =
448 new AppParCurves_HArray1OfConstraintCouple(1, NbPoint);
449 AppParCurves_Constraint Constraint=AppParCurves_NoConstraint;
451 for(i = 1; i <= NbPoint; ++i) {
452 AppParCurves_ConstraintCouple ACC(i,Constraint);
453 TABofCC->SetValue(i,ACC);
456 TABofCC->ChangeValue(1).SetConstraint(Cfirst);
457 TABofCC->ChangeValue(NbPoint).SetConstraint(Clast);
459 AppDef_Variational Variation(multL, 1, NbPoint, TABofCC);
461 //===================================
462 Standard_Integer theMaxSegments = 1000;
463 Standard_Boolean theWithMinMax = Standard_False;
464 Standard_Boolean theWithCutting = Standard_True;
465 //===================================
467 Variation.SetMaxDegree(dmax);
468 Variation.SetContinuity(continuity);
469 Variation.SetMaxSegment(theMaxSegments);
471 Variation.SetTolerance(tol3d);
472 Variation.SetWithMinMax(theWithMinMax);
473 Variation.SetWithCutting(theWithCutting);
474 Variation.SetNbIterations(nbit);
476 Variation.SetCriteriumWeight(critweights[0], critweights[1], critweights[2]);
478 if(!Variation.IsCreated()) {
482 if(Variation.IsOverConstrained()) {
487 Variation.Approximate();
489 catch (Standard_Failure) {
493 if(!Variation.IsDone()) {
497 mytol3d = Variation.MaxError();
500 cout << " Tolerances obtenues --> 3d : "<< mytol3d << endl;
501 cout << " --> 2d : "<< mytol2d << endl;
503 tol3dreached = mytol3d;
504 tol2dreached = mytol2d;
505 multC = Variation.Value();
509 vdeg = multC.Degree();
510 NbVPoles = multC.NbPoles();
512 tabPoles = new TColgp_HArray2OfPnt (1,NbUPoles,1,NbVPoles);
513 tabWeights = new TColStd_HArray2OfReal (1,NbUPoles,1,NbVPoles);
514 tabVKnots = new TColStd_HArray1OfReal (multC.Knots().Lower(),
515 multC.Knots().Upper());
516 tabVKnots->ChangeArray1() = multC.Knots();
518 if (knownp && !UseSmoothing) {
519 BSplCLib::Reparametrize(F.Parameter(Lin->Point(1)),
520 F.Parameter(Lin->Point(NbPoint)),
521 tabVKnots->ChangeArray1());
524 tabVMults = new TColStd_HArray1OfInteger (multC.Multiplicities().Lower(),
525 multC.Multiplicities().Upper());
526 tabVMults->ChangeArray1() = multC.Multiplicities();
529 TColgp_Array1OfPnt newtabP(1,NbVPoles);
530 Handle(TColgp_HArray1OfPnt2d) newtabP2d =
531 new TColgp_HArray1OfPnt2d(1,NbVPoles);
532 for (j=1; j <=NbUPoles; j++) {
533 multC.Curve(j,newtabP);
534 multC.Curve(j+NbUPoles+NbPoles2d,newtabP2d->ChangeArray1());
535 for (k=1; k<=NbVPoles; k++) {
536 // pour les courbes rationnelles il faut maintenant diviser
537 // les poles par leurs poids respectifs
538 tabPoles->ChangeValue(j,k).SetXYZ(newtabP(k).XYZ()/newtabP2d->Value(k).X());
539 Standard_Real aWeight = newtabP2d->Value(k).X();
540 if (aWeight < gp::Resolution()) {
541 done = Standard_False;
544 tabWeights->SetValue(j,k,aWeight);
548 for (j=1; j<=NbPoles2d; j++) {
549 newtabP2d = new TColgp_HArray1OfPnt2d(1,NbVPoles);
550 multC.Curve(NbUPoles+j,newtabP2d->ChangeArray1());
551 seqPoles2d.Append(newtabP2d);
554 done = Standard_True;
558 //=======================================================================
561 //=======================================================================
563 void AppBlend_AppSurf::Perform(const Handle(TheLine)& Lin,
564 TheSectionGenerator& F,
565 const Standard_Integer NbMaxP)
567 done = Standard_False;
568 if (Lin.IsNull()) {return;}
569 Standard_Integer i,j,k;
570 Standard_Integer NbUPoles,NbUKnots,NbPoles2d,NbVPoles;
571 Standard_Boolean withderiv;
572 AppParCurves_Constraint Cfirst=AppParCurves_NoConstraint,Clast=AppParCurves_NoConstraint;
574 Standard_Real mytol3d = 0.0, mytol2d = 0.0;
579 Standard_Integer NbPointTot = Lin->NbPoints();
581 F.GetShape(NbUPoles,NbUKnots,udeg,NbPoles2d);
583 tabUKnots = new TColStd_HArray1OfReal (1,NbUKnots);
584 tabUMults = new TColStd_HArray1OfInteger (1,NbUKnots);
586 F.Knots(tabUKnots->ChangeArray1());
587 F.Mults(tabUMults->ChangeArray1());
589 TColgp_Array1OfPnt tabAppP(1,NbUPoles);
590 TColgp_Array1OfVec tabAppV(1,NbUPoles);
591 Standard_Real X,Y,Z,DX,DY,DZ;
592 X = Y = Z = RealLast();
593 DX = DY = DZ = RealFirst();
595 TColgp_Array1OfPnt2d tabP2d(1,Max(1,NbPoles2d));
596 TColgp_Array1OfVec2d tabV2d(1,Max(1,NbPoles2d));
597 TColStd_Array1OfReal X2d(1,Max(1,NbPoles2d));X2d.Init(RealLast());
598 TColStd_Array1OfReal Y2d(1,Max(1,NbPoles2d));Y2d.Init(RealLast());
599 TColStd_Array1OfReal DX2d(1,Max(1,NbPoles2d));DX2d.Init(RealFirst());
600 TColStd_Array1OfReal DY2d(1,Max(1,NbPoles2d));DY2d.Init(RealFirst());
602 TColStd_Array1OfReal tabW(1,NbUPoles),tabDW(1,NbUPoles);
604 TColgp_Array1OfPnt2d tabAppP2d(1,NbPoles2d+NbUPoles); // points2d + poids
605 TColgp_Array1OfVec2d tabAppV2d(1,NbPoles2d+NbUPoles);
607 // On calcule les boites de chaque ligne (box for all lines)
608 for(i = 1; i <= NbPointTot; i++){
609 F.Section(Lin->Point(i),tabAppP,tabAppV,tabP2d,tabV2d,tabW,tabDW);
611 for(j = 1; j <= NbUPoles; j++){
612 tabAppP(j).Coord(x,y,z);
613 if(x < X) X = x; if(x > DX) DX = x;
614 if(y < Y) Y = y; if(y > DY) DY = y;
615 if(z < Z) Z = z; if(z > DZ) DZ = z;
617 for(j = 1; j <= NbPoles2d; j++){
618 tabP2d(j).Coord(x,y);
619 if(x < X2d(j)) X2d(j) = x; if(x > DX2d(j)) DX2d(j) = x;
620 if(y < Y2d(j)) Y2d(j) = y; if(y > DY2d(j)) DY2d(j) = y;
623 // On calcule pour chaque ligne la transformation vers 0 1.
624 Standard_Real seuil = 1000.*tol3d;
625 Standard_Real seuil2d = 1000.*tol2d;
626 if((DX - X) < seuil ){ DX = 1.; X = 0.; }
627 else{ DX = 1./(DX - X); X *= -DX; }
628 if((DY - Y) < seuil){ DY = 1.; Y = 0.; }
629 else{ DY = 1./(DY - Y); Y *= -DY; }
630 if((DZ - Z) < seuil){ DZ = 1.; Z = 0.; }
631 else{ DZ = 1./(DZ - Z); Z *= -DZ; }
632 for(j = 1; j <= NbPoles2d; j++){
633 if((DX2d(j) - X2d(j)) < seuil2d){ DX2d(j) = 1.; X2d(j) = 0.; }
634 else{ DX2d(j) = 1./(DX2d(j) - X2d(j)); X2d(j) *= -DX2d(j); }
635 if((DY2d(j) - Y2d(j)) < seuil2d){ DY2d(j) = 1.; Y2d(j) = 0.; }
636 else{ DY2d(j) = 1./(DY2d(j) - Y2d(j)); Y2d(j) *= -DY2d(j); }
642 for(j = 1; j <= NbPoles2d; j++){
643 DX2d(j) = 1.; X2d(j) = 0.;
644 DY2d(j) = 1.; Y2d(j) = 0.;
647 // modified by eap Thu Jan 3 14:45:22 2002 ___BEGIN___
648 // Keep "inter-troncons" parameters, not only first and last
649 // Standard_Real Ufirst=0,Ulast=0;
650 TColStd_SequenceOfReal aParamSeq;
652 // Ufirst = F.Parameter(Lin->Point(1));
653 // Ulast = F.Parameter(Lin->Point(NbPointTot));
654 aParamSeq.Append( F.Parameter (Lin->Point(1)) );
656 // modified by EAP Thu Jan 3 14:45:41 2002 ___END___
658 Approx_MCurvesToBSpCurve concat;
660 //On calcule le nombre de troncons.
661 Standard_Integer nbtronc = NbPointTot/NbMaxP;
662 Standard_Integer reste = NbPointTot - (nbtronc * NbMaxP);
663 // On regarde si il faut prendre un troncon de plus.
664 Standard_Integer nmax = NbMaxP;
665 if(nbtronc > 0 && reste > 0){
666 nmax = NbPointTot/(nbtronc + 1);
667 if(nmax > (2*NbMaxP)/3) {
669 reste = NbPointTot - (nbtronc * nmax);
673 else if(nbtronc == 0){
679 // Approximate each "troncon" with nb of Bezier's using AppDef_Compute
680 // and concat them into BSpline with Approx_MCurvesToBSpCurve
682 TColStd_Array1OfInteger troncsize(1,nbtronc);
683 TColStd_Array1OfInteger troncstart(1,nbtronc);
685 Standard_Integer rab = reste/nbtronc + 1;
686 Standard_Integer start = 1;
687 Standard_Integer itronc ;
688 for( itronc = 1; itronc <= nbtronc; itronc++){
689 troncstart(itronc) = start;
690 Standard_Integer rabrab = Min(rab,reste);
691 if(reste > 0){ reste -= rabrab; }
692 troncsize(itronc) = nmax + rabrab + 1;
693 start += (nmax + rabrab);
695 troncsize(nbtronc) = troncsize(nbtronc) - 1;
696 for(itronc = 1; itronc <= nbtronc; itronc++){
697 Standard_Integer NbPoint = troncsize(itronc);
698 Standard_Integer StPoint = troncstart(itronc);
699 AppDef_MultiPointConstraint multP;
700 AppDef_MultiLine multL(NbPoint);
702 for (i=1; i<=NbPoint; i++) {
703 Standard_Integer iLin = StPoint + i - 1;
705 withderiv = F.Section(Lin->Point(iLin),tabAppP,tabAppV,tabP2d,tabV2d,
707 if(AppBlend_GetContextApproxWithNoTgt()) withderiv = Standard_False;
709 for (j=1; j<=NbPoles2d; j++) {
710 tabP2d(j).Coord(x,y);
711 tabAppP2d(j).SetCoord(DX2d(j)*x+X2d(j),DY2d(j)*y+Y2d(j));
713 tabV2d(j).Coord(x,y);
714 tabAppV2d(j).SetCoord(DX2d(j)*x,DY2d(j)*y);
717 for (j=1; j<=NbUPoles; j++) {
718 // pour les courbes rationnelles il faut multiplier les poles par
719 // leurs poids respectifs
721 tabAppV2d(NbPoles2d+j).SetCoord(tabDW(j),0.);
722 newDv.SetLinearForm(tabDW(j),tabAppP(j).XYZ(),tabW(j),tabAppV(j).XYZ());
723 tabAppV(j).SetCoord(DX*newDv.X(),DY*newDv.Y(),DZ*newDv.Z());
725 tabAppP(j).SetXYZ(tabAppP(j).XYZ() * tabW(j));
726 tabAppP2d(NbPoles2d+j).SetCoord(tabW(j),0.);
727 tabAppP(j).Coord(x,y,z);
728 tabAppP(j).SetCoord(DX*x+X,DY*y+Y,DZ*z+Z);
731 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d,tabAppV,tabAppV2d);
732 if(i == 1) Cfirst = AppParCurves_TangencyPoint;
733 else if(i == NbPoint) Clast = AppParCurves_TangencyPoint;
736 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d);
737 if(i == 1) Cfirst = AppParCurves_PassPoint;
738 else if(i == NbPoint) Clast = AppParCurves_PassPoint;
740 multL.SetValue(i,multP);
744 //IFV 04.06.07 occ13904
747 if(Cfirst == AppParCurves_PassPoint && Clast == AppParCurves_PassPoint) {
752 // modified by EAP Thu Jan 3 15:44:13 2002 ___BEGIN___
753 Standard_Real Ufloc=0., Ulloc=0.;
754 AppDef_Compute theapprox (dmin,dmax,tol3d,tol2d,nbit);
756 math_Vector theParams(1,NbPoint);
757 // On recale les parametres entre 0 et 1.
758 /*Standard_Real*/ Ufloc = F.Parameter(Lin->Point(StPoint));
759 /*Standard_Real*/ Ulloc = F.Parameter(Lin->Point(StPoint+NbPoint-1));
760 // modified by EAP Thu Jan 3 15:45:17 2002 ___END___
761 for (i=1; i <= NbPoint; i++) {
762 Standard_Integer iLin = StPoint + i - 1;
763 theParams(i) = (F.Parameter(Lin->Point(iLin))-Ufloc)/(Ulloc - Ufloc);
765 AppDef_Compute theAppDef1(theParams,dmin,dmax,tol3d,tol2d,nbit, Standard_True,Standard_True);
766 theapprox = theAppDef1;
768 theapprox.SetConstraints(Cfirst,Clast);
769 theapprox.Perform(multL);
771 // modified by EAP Thu Jan 3 16:00:43 2002 ___BEGIN___
772 // To know internal parameters if multicurve is approximated by several Bezier's
773 TColStd_SequenceOfReal aPoleDistSeq;
774 Standard_Real aWholeDist=0;
775 // modified by EAP Thu Jan 3 16:45:48 2002 ___END___
776 Standard_Real TheTol3d, TheTol2d;
777 for (Standard_Integer Index=1; Index<=theapprox.NbMultiCurves(); Index++) {
778 AppParCurves_MultiCurve& mucu = theapprox.ChangeValue(Index);
779 theapprox.Error(Index, TheTol3d, TheTol2d);
780 mytol3d = Max(TheTol3d/DX, mytol3d);
781 mytol3d = Max(TheTol3d/DY, mytol3d);
782 mytol3d = Max(TheTol3d/DZ, mytol3d);
783 for(j = 1; j <= NbUPoles; j++){
789 for(j = 1; j <= NbPoles2d; j++){
790 mucu.Transform2d(j + NbUPoles,
791 -X2d(j)/DX2d(j),1./DX2d(j),
792 -Y2d(j)/DY2d(j),1./DY2d(j));
793 mytol2d = Max(TheTol2d/DX2d(j), mytol2d);
794 mytol2d = Max(TheTol2d/DY2d(j), mytol2d);
798 // modified by EAP Thu Jan 3 15:45:23 2002 ___BEGIN___
799 if (knownp && theapprox.NbMultiCurves() > 1)
801 gp_Pnt aFirstPole = mucu.Pole(Index, 1);
802 gp_Pnt aLastPole = mucu.Pole(Index, mucu.NbPoles());
803 aPoleDistSeq.Append (aFirstPole.Distance(aLastPole));
804 aWholeDist += aPoleDistSeq.Last();
809 Standard_Integer iDist;
810 Standard_Real iU = Ufloc;
811 for (iDist=1; iDist<aPoleDistSeq.Length(); iDist++)
813 iU += aPoleDistSeq(iDist) / aWholeDist * (Ulloc - Ufloc);
814 //cout << "Internal: " << iU << endl;
815 aParamSeq.Append(iU);
817 aParamSeq.Append(Ulloc);
819 // modified by EAP Thu Jan 3 15:45:27 2002 ___END___
822 cout << " Tolerances obtenues --> 3d : "<< mytol3d << endl;
823 cout << " --> 2d : "<< mytol2d << endl;
825 tol3dreached = mytol3d;
826 tol2dreached = mytol2d;
828 const AppParCurves_MultiBSpCurve& multC = concat.Value();
829 vdeg = multC.Degree();
830 NbVPoles = multC.NbPoles();
832 tabPoles = new TColgp_HArray2OfPnt (1,NbUPoles,1,NbVPoles);
833 tabWeights = new TColStd_HArray2OfReal (1,NbUPoles,1,NbVPoles);
834 tabVKnots = new TColStd_HArray1OfReal (multC.Knots().Lower(),
835 multC.Knots().Upper());
836 tabVKnots->ChangeArray1() = multC.Knots();
839 // modified by EAP Fri Jan 4 12:07:30 2002 ___BEGIN___
840 if (aParamSeq.Length() != tabVKnots->Length())
842 BSplCLib::Reparametrize(F.Parameter(Lin->Point(1)),
843 F.Parameter(Lin->Point(Lin->NbPoints())),
844 tabVKnots->ChangeArray1()
847 cout << "Warning: AppBlend_AppSurf::Perform(), bad length of aParamSeq: " <<
848 aParamSeq.Length() << " instead of " << tabVKnots->Length() << endl;
853 Standard_Integer iKnot, iTabKnot = tabVKnots->Lower();
854 for (iKnot=1; iKnot<=aParamSeq.Length(); iKnot++, iTabKnot++)
856 //cout << "Replace " << tabVKnots->Value(iTabKnot) << " with " << aParamSeq(iKnot) << endl;
857 tabVKnots->SetValue(iTabKnot, aParamSeq(iKnot));
860 // modified by EAP Fri Jan 4 12:07:35 2002 ___END___
863 tabVMults = new TColStd_HArray1OfInteger (multC.Multiplicities().Lower(),
864 multC.Multiplicities().Upper());
865 tabVMults->ChangeArray1() = multC.Multiplicities();
868 TColgp_Array1OfPnt newtabP(1,NbVPoles);
869 Handle(TColgp_HArray1OfPnt2d) newtabP2d =
870 new TColgp_HArray1OfPnt2d(1,NbVPoles);
871 for (j=1; j <=NbUPoles; j++) {
872 multC.Curve(j,newtabP);
873 multC.Curve(j+NbUPoles+NbPoles2d,newtabP2d->ChangeArray1());
874 for (k=1; k<=NbVPoles; k++) {
875 // pour les courbes rationnelles il faut maintenant diviser
876 // les poles par leurs poids respectifs
877 tabPoles->ChangeValue(j,k).SetXYZ(newtabP(k).XYZ()/newtabP2d->Value(k).X());
878 Standard_Real aWeight = newtabP2d->Value(k).X();
879 if (aWeight < gp::Resolution()) {
880 done = Standard_False;
883 tabWeights->SetValue(j,k,aWeight);
887 for (j=1; j<=NbPoles2d; j++) {
888 newtabP2d = new TColgp_HArray1OfPnt2d(1,NbVPoles);
889 multC.Curve(NbUPoles+j,newtabP2d->ChangeArray1());
890 seqPoles2d.Append(newtabP2d);
893 done = Standard_True;
897 //=======================================================================
898 //function : SurfShape
900 //=======================================================================
902 void AppBlend_AppSurf::SurfShape (Standard_Integer& UDegree,
903 Standard_Integer& VDegree,
904 Standard_Integer& NbUPoles,
905 Standard_Integer& NbVPoles,
906 Standard_Integer& NbUKnots,
907 Standard_Integer& NbVKnots) const
909 if (!done) {throw StdFail_NotDone();}
912 NbUPoles = tabPoles->ColLength();
913 NbVPoles = tabPoles->RowLength();
914 NbUKnots = tabUKnots->Length();
915 NbVKnots = tabVKnots->Length();
919 void AppBlend_AppSurf::Surface(TColgp_Array2OfPnt& TPoles,
920 TColStd_Array2OfReal& TWeights,
921 TColStd_Array1OfReal& TUKnots,
922 TColStd_Array1OfReal& TVKnots,
923 TColStd_Array1OfInteger& TUMults,
924 TColStd_Array1OfInteger& TVMults) const
927 if (!done) {throw StdFail_NotDone();}
928 TPoles = tabPoles->Array2();
929 TWeights = tabWeights->Array2();
930 TUKnots = tabUKnots->Array1();
931 TUMults = tabUMults->Array1();
932 TVKnots = tabVKnots->Array1();
933 TVMults = tabVMults->Array1();
936 //=======================================================================
937 //function : Curves2dShape
939 //=======================================================================
941 void AppBlend_AppSurf::Curves2dShape(Standard_Integer& Degree,
942 Standard_Integer& NbPoles,
943 Standard_Integer& NbKnots) const
945 if (!done) {throw StdFail_NotDone();}
946 if (seqPoles2d.Length() == 0) {throw Standard_DomainError();}
948 NbPoles = tabPoles->ColLength();
949 NbKnots = tabVKnots->Length();
952 //=======================================================================
955 //=======================================================================
957 void AppBlend_AppSurf::Curve2d(const Standard_Integer Index,
958 TColgp_Array1OfPnt2d& TPoles,
959 TColStd_Array1OfReal& TKnots,
960 TColStd_Array1OfInteger& TMults) const
962 if (!done) {throw StdFail_NotDone();}
963 if (seqPoles2d.Length() == 0) {throw Standard_DomainError();}
964 TPoles = seqPoles2d(Index)->Array1();
965 TKnots = tabVKnots->Array1();
966 TMults = tabVMults->Array1();
969 //=======================================================================
970 //function : TolCurveOnSurf
972 //=======================================================================
974 Standard_Real AppBlend_AppSurf::TolCurveOnSurf(const Standard_Integer) const
976 return tol3dreached; //On ne s'embete pas !!