0027674: BRepOffsetAPI_ThruSections make invalid shape if sections are connected...
[occt.git] / src / AppBlend / AppBlend_AppSurf.gxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 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
973c2be1 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.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
7fd59977 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>
27#include <gp_Vec.hxx>
28#include <gp_Vec2d.hxx>
29#include <gp_Pnt.hxx>
30#include <gp_Pnt2d.hxx>
31#include <math_Vector.hxx>
32#include <BSplCLib.hxx>
33
34#include <StdFail_NotDone.hxx>
35#include <AppParCurves_HArray1OfConstraintCouple.hxx>
f62de372 36#include <AppDef_Variational.hxx>
7fd59977 37
38static Standard_Boolean scal = 1;
7fd59977 39extern Standard_Boolean AppBlend_GetContextSplineApprox();
40extern Standard_Boolean AppBlend_GetContextApproxWithNoTgt();
7fd59977 41
42// modified by EAP (Edward AGAPOV) Fri Jan 4 2002, bug OCC9
43// --- keep pipe parametrized like path
44
45
46//=======================================================================
47//function : AppBlend_AppSurf
48//purpose :
49//=======================================================================
50
51AppBlend_AppSurf::AppBlend_AppSurf ():done(Standard_False) {}
52
53
54//=======================================================================
55//function : AppBlend_AppSurf
56//purpose :
57//=======================================================================
58
59AppBlend_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)
67{
68 continuity = GeomAbs_C2;
69 paramtype = Approx_ChordLength;
70 critweights[0]=0.4;
71 critweights[1]=0.2;
72 critweights[2]=0.4;
73}
74
75//=======================================================================
76//function : Init
77//purpose :
78//=======================================================================
79
80void 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)
86{
87 done = Standard_False;
88 dmin = Degmin;
89 dmax = Degmax;
90 tol3d = Tol3d;
91 tol2d = Tol2d;
92 nbit = NbIt;
93 knownp = KnownParameters;
94 continuity = GeomAbs_C2;
95 paramtype = Approx_ChordLength;
96 critweights[0]=0.4;
97 critweights[1]=0.2;
98 critweights[2]=0.4;
99}
100
101//=======================================================================
102//function : CriteriumWeight
103//purpose : returns the Weights associed to the criterium used in
104// the optimization.
105//=======================================================================
106//
107void AppBlend_AppSurf::CriteriumWeight(Standard_Real& W1, Standard_Real& W2, Standard_Real& W3) const
108{
109 W1 = critweights[0];
110 W2 = critweights[1];
111 W3 = critweights[2] ;
112}
113//=======================================================================
114//function : SetCriteriumWeight
115//purpose :
116//=======================================================================
117
118void AppBlend_AppSurf::SetCriteriumWeight(const Standard_Real W1, const Standard_Real W2, const Standard_Real W3)
119{
120 if (W1 < 0 || W2 < 0 || W3 < 0 ) Standard_DomainError::Raise();
121 critweights[0] = W1;
122 critweights[1] = W2;
123 critweights[2] = W3;
124}
125//=======================================================================
126//function : SetContinuity
127//purpose :
128//=======================================================================
129
130void AppBlend_AppSurf::SetContinuity (const GeomAbs_Shape TheCont)
131{
132 continuity = TheCont;
133}
134
135//=======================================================================
136//function : Continuity
137//purpose :
138//=======================================================================
139
140GeomAbs_Shape AppBlend_AppSurf::Continuity () const
141{
142 return continuity;
143}
144
145//=======================================================================
146//function : SetParType
147//purpose :
148//=======================================================================
149
150void AppBlend_AppSurf::SetParType (const Approx_ParametrizationType ParType)
151{
152 paramtype = ParType;
153}
154
155//=======================================================================
156//function : ParType
157//purpose :
158//=======================================================================
159
160Approx_ParametrizationType AppBlend_AppSurf::ParType () const
161{
162 return paramtype;
163}
164
165
166//=======================================================================
167//function : Perform
168//purpose :
169//=======================================================================
170
171void AppBlend_AppSurf::Perform(const Handle(TheLine)& Lin,
172 TheSectionGenerator& F,
173 const Standard_Boolean SpApprox)
174
175{
176 InternalPerform(Lin, F, SpApprox, Standard_False);
177}
178
179//=======================================================================
180//function : PerformSmoothing
181//purpose :
182//=======================================================================
183
184void AppBlend_AppSurf::PerformSmoothing(const Handle(TheLine)& Lin,
185 TheSectionGenerator& F)
186
187{
188 InternalPerform(Lin, F, Standard_True, Standard_True);
189}
190
191//=======================================================================
192//function : InternalPerform
193//purpose :
194//=======================================================================
195
196void AppBlend_AppSurf::InternalPerform(const Handle(TheLine)& Lin,
197 TheSectionGenerator& F,
198 const Standard_Boolean SpApprox,
199 const Standard_Boolean UseSmoothing)
200
201{
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;
208
209 Standard_Real mytol3d,mytol2d;
210 gp_XYZ newDv;
211
212 seqPoles2d.Clear();
213
214 NbPoint=Lin->NbPoints();
215 AppDef_MultiPointConstraint multP;
216 AppDef_MultiLine multL(NbPoint);
217
218 F.GetShape(NbUPoles,NbUKnots,udeg,NbPoles2d);
219
220 tabUKnots = new TColStd_HArray1OfReal (1,NbUKnots);
221 tabUMults = new TColStd_HArray1OfInteger (1,NbUKnots);
222
223 F.Knots(tabUKnots->ChangeArray1());
224 F.Mults(tabUMults->ChangeArray1());
225
226 TColgp_Array1OfPnt tabAppP(1,NbUPoles);
227 TColgp_Array1OfVec tabAppV(1,NbUPoles);
228
229 TColgp_Array1OfPnt2d tabP2d(1,Max(1,NbPoles2d));
230 TColgp_Array1OfVec2d tabV2d(1,Max(1,NbPoles2d));
231
232 TColStd_Array1OfReal tabW(1,NbUPoles),tabDW(1,NbUPoles);
233
234 TColgp_Array1OfPnt2d tabAppP2d(1,NbPoles2d+NbUPoles); // points2d + poids
235 TColgp_Array1OfVec2d tabAppV2d(1,NbPoles2d+NbUPoles);
236
237
238 AppParCurves_MultiBSpCurve multC;
239
240// Standard_Boolean SpApprox = Standard_False;
241
242 withderiv = F.Section(Lin->Point(1),tabAppP,tabAppV,tabP2d,tabV2d,
243 tabW,tabDW);
244
7fd59977 245 if(AppBlend_GetContextApproxWithNoTgt()) withderiv = Standard_False;
7fd59977 246
247 for (j=1; j<=NbPoles2d; j++) {
248 tabAppP2d(j) = tabP2d(j);
249 if (withderiv) {
250 tabAppV2d(j) = tabV2d(j);
251 }
252 }
253 for (j=1; j<=NbUPoles; j++) {
254 // pour les courbes rationnelles il faut multiplier les poles par
255 // leurs poids respectifs
256 if (withderiv) {
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);
260 }
261 tabAppP(j).SetXYZ(tabAppP(j).XYZ() * tabW(j));
262 tabAppP2d(NbPoles2d+j).SetCoord(tabW(j),0.);
263 }
264
265 if (withderiv) {
266 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d,tabAppV,tabAppV2d);
267 Cfirst = AppParCurves_TangencyPoint;
268 }
269 else {
270 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d);
271 Cfirst = AppParCurves_PassPoint;
272 }
273 multL.SetValue(1,multP);
274
275 for (i=2; i<=NbPoint-1; i++) {
276 if (SpApprox) {
277 F.Section(Lin->Point(i),tabAppP,tabP2d,tabW);
278 for (j=1; j<=NbPoles2d; j++) {
279 tabAppP2d(j) = tabP2d(j);
280 }
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.);
286 }
287 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d);
288 multL.SetValue(i,multP);
289 }
290// ***********************
291 else {
292 withderiv = F.Section(Lin->Point(i),tabAppP,tabAppV,tabP2d,tabV2d,
293 tabW,tabDW);
7fd59977 294 if(AppBlend_GetContextApproxWithNoTgt()) withderiv = Standard_False;
7fd59977 295
296 for (j=1; j<=NbPoles2d; j++) {
297 tabAppP2d(j) = tabP2d(j);
298 if (withderiv) {
299 tabAppV2d(j) = tabV2d(j);
300 }
301 }
302 for (j=1; j<=NbUPoles; j++) {
303 // pour les courbes rationnelles il faut multiplier les poles par
304 // leurs poids respectifs
305 if (withderiv) {
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);
309 }
310 tabAppP(j).SetXYZ(tabAppP(j).XYZ() * tabW(j));
311 tabAppP2d(NbPoles2d+j).SetCoord(tabW(j),0.);
312 }
313 if (withderiv) {
314 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d,tabAppV,tabAppV2d);
315 }
316 else {
317 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d);
318 }
319 multL.SetValue(i,multP);
320 }
321// ******************************
322 }
323
324 withderiv = F.Section(Lin->Point(NbPoint),tabAppP,tabAppV,tabP2d,tabV2d,
325 tabW,tabDW);
0797d9d3 326 if(AppBlend_GetContextApproxWithNoTgt()) withderiv = Standard_False;
7fd59977 327
328 for (j=1; j<=NbPoles2d; j++) {
329 tabAppP2d(j) = tabP2d(j);
330 if (withderiv) {
331 tabAppV2d(j) = tabV2d(j);
332 }
333 }
334 for (j=1; j<=NbUPoles; j++) {
335 // pour les courbes rationnelles il faut multiplier les poles par
336 // leurs poids respectifs
337 if (withderiv) {
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);
341 }
342 tabAppP(j).SetXYZ(tabAppP(j).XYZ() * tabW(j));
343 tabAppP2d(NbPoles2d+j).SetCoord(tabW(j),0.);
344 }
345
346 if (withderiv) {
347 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d,tabAppV,tabAppV2d);
348 Clast = AppParCurves_TangencyPoint;
349 }
350 else {
351 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d);
352 Clast = AppParCurves_PassPoint;
353 }
354 multL.SetValue(NbPoint,multP);
355
356 //IFV 04.06.07 occ13904
357 if(NbPoint == 2) {
358 dmin = 1;
359 if(Cfirst == AppParCurves_PassPoint && Clast == AppParCurves_PassPoint) {
360 dmax = 1;
361 }
362 }
363
364
365 if (!SpApprox) {
366 AppDef_Compute theapprox (dmin,dmax,tol3d,tol2d,nbit, Standard_True, paramtype);
367 if (knownp) {
368 math_Vector theParams(1,NbPoint);
369
370 // On recale les parametres entre 0 et 1.
371 theParams(1) = 0.;
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;;
377 }
378 AppDef_Compute theAppDef(theParams,dmin,dmax,tol3d,tol2d,nbit,
379 Standard_True, Standard_True);
380 theapprox = theAppDef;
381 }
382 theapprox.SetConstraints(Cfirst,Clast);
383 theapprox.Perform(multL);
384
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);
391 }
0797d9d3 392#ifdef OCCT_DEBUG
7fd59977 393 cout << " Tolerances obtenues --> 3d : "<< mytol3d << endl;
394 cout << " --> 2d : "<< mytol2d << endl;
395#endif
396 multC = theapprox.SplineValue();
397 }
398
399 else {
400 if(!UseSmoothing) {
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,
404 UseSquares);
405 if(continuity == GeomAbs_C0) {
406 theapprox.SetContinuity(0);
407 }
408 if(continuity == GeomAbs_C1) {
409 theapprox.SetContinuity(1);
410 }
411 else if(continuity == GeomAbs_C2) {
412 theapprox.SetContinuity(2);
413 }
414 else {
415 theapprox.SetContinuity(3);
416 }
417
418 theapprox.SetConstraints(Cfirst,Clast);
419
420 if (knownp) {
421 math_Vector theParams(1,NbPoint);
422 // On recale les parametres entre 0 et 1.
423 theParams(1) = 0.;
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;;
429 }
430
431 theapprox.Init(dmin,dmax,tol3d,tol2d,nbit,Standard_True,
432 Approx_IsoParametric,Standard_True);
433 theapprox.SetParameters(theParams);
434 }
435 theapprox.Perform(multL);
436 theapprox.Error(mytol3d,mytol2d);
0797d9d3 437#ifdef OCCT_DEBUG
7fd59977 438 cout << " Tolerances obtenues --> 3d : "<< mytol3d << endl;
439 cout << " --> 2d : "<< mytol2d << endl;
440#endif
441 tol3dreached = mytol3d;
442 tol2dreached = mytol2d;
443 multC = theapprox.Value();
444 }
445 else {
446 //Variational algo
447 Handle(AppParCurves_HArray1OfConstraintCouple) TABofCC =
448 new AppParCurves_HArray1OfConstraintCouple(1, NbPoint);
449 AppParCurves_Constraint Constraint=AppParCurves_NoConstraint;
450
451 for(i = 1; i <= NbPoint; ++i) {
452 AppParCurves_ConstraintCouple ACC(i,Constraint);
453 TABofCC->SetValue(i,ACC);
454 }
455
456 TABofCC->ChangeValue(1).SetConstraint(Cfirst);
457 TABofCC->ChangeValue(NbPoint).SetConstraint(Clast);
458
f62de372 459 AppDef_Variational Variation(multL, 1, NbPoint, TABofCC);
7fd59977 460
461//===================================
462 Standard_Integer theMaxSegments = 1000;
463 Standard_Boolean theWithMinMax = Standard_False;
464 Standard_Boolean theWithCutting = Standard_True;
465//===================================
466
467 Variation.SetMaxDegree(dmax);
468 Variation.SetContinuity(continuity);
469 Variation.SetMaxSegment(theMaxSegments);
470
471 Variation.SetTolerance(tol3d);
472 Variation.SetWithMinMax(theWithMinMax);
473 Variation.SetWithCutting(theWithCutting);
474 Variation.SetNbIterations(nbit);
475
476 Variation.SetCriteriumWeight(critweights[0], critweights[1], critweights[2]);
477
478 if(!Variation.IsCreated()) {
479 return;
480 }
481
482 if(Variation.IsOverConstrained()) {
483 return;
484 }
485
486 try {
487 Variation.Approximate();
488 }
489 catch (Standard_Failure) {
490 return;
491 }
492
493 if(!Variation.IsDone()) {
494 return;
495 }
496
497 mytol3d = Variation.MaxError();
498 mytol2d = 0.;
0797d9d3 499#ifdef OCCT_DEBUG
7fd59977 500 cout << " Tolerances obtenues --> 3d : "<< mytol3d << endl;
501 cout << " --> 2d : "<< mytol2d << endl;
502#endif
503 tol3dreached = mytol3d;
504 tol2dreached = mytol2d;
505 multC = Variation.Value();
506 }
507 }
508
509 vdeg = multC.Degree();
510 NbVPoles = multC.NbPoles();
511
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();
517
518 if (knownp && !UseSmoothing) {
519 BSplCLib::Reparametrize(F.Parameter(Lin->Point(1)),
520 F.Parameter(Lin->Point(NbPoint)),
521 tabVKnots->ChangeArray1());
522 }
523
524 tabVMults = new TColStd_HArray1OfInteger (multC.Multiplicities().Lower(),
525 multC.Multiplicities().Upper());
526 tabVMults->ChangeArray1() = multC.Multiplicities();
527
528
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).
539 SetXYZ(newtabP(k).XYZ()/newtabP2d->Value(k).X());
540 tabWeights->SetValue(j,k,newtabP2d->Value(k).X());
541 }
542 }
543
544 for (j=1; j<=NbPoles2d; j++) {
545 newtabP2d = new TColgp_HArray1OfPnt2d(1,NbVPoles);
546 multC.Curve(NbUPoles+j,newtabP2d->ChangeArray1());
547 seqPoles2d.Append(newtabP2d);
548 }
549
550 done = Standard_True;
551}
552
553
554//=======================================================================
555//function : Perform
556//purpose :
557//=======================================================================
558
559void AppBlend_AppSurf::Perform(const Handle(TheLine)& Lin,
560 TheSectionGenerator& F,
561 const Standard_Integer NbMaxP)
562{
563 done = Standard_False;
564 if (Lin.IsNull()) {return;}
565 Standard_Integer i,j,k;
566 Standard_Integer NbUPoles,NbUKnots,NbPoles2d,NbVPoles;
567 Standard_Boolean withderiv;
568 AppParCurves_Constraint Cfirst=AppParCurves_NoConstraint,Clast=AppParCurves_NoConstraint;
569
570 Standard_Real mytol3d = 0.0, mytol2d = 0.0;
571 gp_XYZ newDv;
572
573 seqPoles2d.Clear();
574
575 Standard_Integer NbPointTot = Lin->NbPoints();
576
577 F.GetShape(NbUPoles,NbUKnots,udeg,NbPoles2d);
578
579 tabUKnots = new TColStd_HArray1OfReal (1,NbUKnots);
580 tabUMults = new TColStd_HArray1OfInteger (1,NbUKnots);
581
582 F.Knots(tabUKnots->ChangeArray1());
583 F.Mults(tabUMults->ChangeArray1());
584
585 TColgp_Array1OfPnt tabAppP(1,NbUPoles);
586 TColgp_Array1OfVec tabAppV(1,NbUPoles);
587 Standard_Real X,Y,Z,DX,DY,DZ;
588 X = Y = Z = RealLast();
589 DX = DY = DZ = RealFirst();
590
591 TColgp_Array1OfPnt2d tabP2d(1,Max(1,NbPoles2d));
592 TColgp_Array1OfVec2d tabV2d(1,Max(1,NbPoles2d));
593 TColStd_Array1OfReal X2d(1,Max(1,NbPoles2d));X2d.Init(RealLast());
594 TColStd_Array1OfReal Y2d(1,Max(1,NbPoles2d));Y2d.Init(RealLast());
595 TColStd_Array1OfReal DX2d(1,Max(1,NbPoles2d));DX2d.Init(RealFirst());
596 TColStd_Array1OfReal DY2d(1,Max(1,NbPoles2d));DY2d.Init(RealFirst());
597
598 TColStd_Array1OfReal tabW(1,NbUPoles),tabDW(1,NbUPoles);
599
600 TColgp_Array1OfPnt2d tabAppP2d(1,NbPoles2d+NbUPoles); // points2d + poids
601 TColgp_Array1OfVec2d tabAppV2d(1,NbPoles2d+NbUPoles);
602
603 // On calcule les boites de chaque ligne (box for all lines)
604 for(i = 1; i <= NbPointTot; i++){
605 F.Section(Lin->Point(i),tabAppP,tabAppV,tabP2d,tabV2d,tabW,tabDW);
606 Standard_Real x,y,z;
607 for(j = 1; j <= NbUPoles; j++){
608 tabAppP(j).Coord(x,y,z);
609 if(x < X) X = x; if(x > DX) DX = x;
610 if(y < Y) Y = y; if(y > DY) DY = y;
611 if(z < Z) Z = z; if(z > DZ) DZ = z;
612 }
613 for(j = 1; j <= NbPoles2d; j++){
614 tabP2d(j).Coord(x,y);
615 if(x < X2d(j)) X2d(j) = x; if(x > DX2d(j)) DX2d(j) = x;
616 if(y < Y2d(j)) Y2d(j) = y; if(y > DY2d(j)) DY2d(j) = y;
617 }
618 }
619 // On calcule pour chaque ligne la transformation vers 0 1.
620 Standard_Real seuil = 1000.*tol3d;
621 Standard_Real seuil2d = 1000.*tol2d;
622 if((DX - X) < seuil ){ DX = 1.; X = 0.; }
623 else{ DX = 1./(DX - X); X *= -DX; }
624 if((DY - Y) < seuil){ DY = 1.; Y = 0.; }
625 else{ DY = 1./(DY - Y); Y *= -DY; }
626 if((DZ - Z) < seuil){ DZ = 1.; Z = 0.; }
627 else{ DZ = 1./(DZ - Z); Z *= -DZ; }
628 for(j = 1; j <= NbPoles2d; j++){
629 if((DX2d(j) - X2d(j)) < seuil2d){ DX2d(j) = 1.; X2d(j) = 0.; }
630 else{ DX2d(j) = 1./(DX2d(j) - X2d(j)); X2d(j) *= -DX2d(j); }
631 if((DY2d(j) - Y2d(j)) < seuil2d){ DY2d(j) = 1.; Y2d(j) = 0.; }
632 else{ DY2d(j) = 1./(DY2d(j) - Y2d(j)); Y2d(j) *= -DY2d(j); }
633 }
634 if(!scal){
635 DX = 1.; X = 0.;
636 DY = 1.; Y = 0.;
637 DZ = 1.; Z = 0.;
638 for(j = 1; j <= NbPoles2d; j++){
639 DX2d(j) = 1.; X2d(j) = 0.;
640 DY2d(j) = 1.; Y2d(j) = 0.;
641 }
642 }
643// modified by eap Thu Jan 3 14:45:22 2002 ___BEGIN___
644 // Keep "inter-troncons" parameters, not only first and last
645// Standard_Real Ufirst=0,Ulast=0;
646 TColStd_SequenceOfReal aParamSeq;
647 if (knownp) {
648// Ufirst = F.Parameter(Lin->Point(1));
649// Ulast = F.Parameter(Lin->Point(NbPointTot));
650 aParamSeq.Append( F.Parameter (Lin->Point(1)) );
651 }
652// modified by EAP Thu Jan 3 14:45:41 2002 ___END___
653
654 Approx_MCurvesToBSpCurve concat;
655
656 //On calcule le nombre de troncons.
657 Standard_Integer nbtronc = NbPointTot/NbMaxP;
658 Standard_Integer reste = NbPointTot - (nbtronc * NbMaxP);
659 // On regarde si il faut prendre un troncon de plus.
660 Standard_Integer nmax = NbMaxP;
661 if(nbtronc > 0 && reste > 0){
662 nmax = NbPointTot/(nbtronc + 1);
663 if(nmax > (2*NbMaxP)/3) {
664 nbtronc++;
665 reste = NbPointTot - (nbtronc * nmax);
666 }
667 else nmax = NbMaxP;
668 }
669 else if(nbtronc == 0){
670 nbtronc = 1;
671 nmax = reste;
672 reste = 0;
673 }
674
675 // Approximate each "troncon" with nb of Bezier's using AppDef_Compute
676 // and concat them into BSpline with Approx_MCurvesToBSpCurve
677
678 TColStd_Array1OfInteger troncsize(1,nbtronc);
679 TColStd_Array1OfInteger troncstart(1,nbtronc);
680
681 Standard_Integer rab = reste/nbtronc + 1;
682 Standard_Integer start = 1;
683 Standard_Integer itronc ;
684 for( itronc = 1; itronc <= nbtronc; itronc++){
685 troncstart(itronc) = start;
686 Standard_Integer rabrab = Min(rab,reste);
687 if(reste > 0){ reste -= rabrab; }
688 troncsize(itronc) = nmax + rabrab + 1;
689 start += (nmax + rabrab);
690 }
691 troncsize(nbtronc) = troncsize(nbtronc) - 1;
692 for(itronc = 1; itronc <= nbtronc; itronc++){
693 Standard_Integer NbPoint = troncsize(itronc);
694 Standard_Integer StPoint = troncstart(itronc);
695 AppDef_MultiPointConstraint multP;
696 AppDef_MultiLine multL(NbPoint);
697
698 for (i=1; i<=NbPoint; i++) {
699 Standard_Integer iLin = StPoint + i - 1;
700 Standard_Real x,y,z;
701 withderiv = F.Section(Lin->Point(iLin),tabAppP,tabAppV,tabP2d,tabV2d,
702 tabW,tabDW);
7fd59977 703 if(AppBlend_GetContextApproxWithNoTgt()) withderiv = Standard_False;
7fd59977 704
705 for (j=1; j<=NbPoles2d; j++) {
706 tabP2d(j).Coord(x,y);
707 tabAppP2d(j).SetCoord(DX2d(j)*x+X2d(j),DY2d(j)*y+Y2d(j));
708 if (withderiv) {
709 tabV2d(j).Coord(x,y);
710 tabAppV2d(j).SetCoord(DX2d(j)*x,DY2d(j)*y);
711 }
712 }
713 for (j=1; j<=NbUPoles; j++) {
714 // pour les courbes rationnelles il faut multiplier les poles par
715 // leurs poids respectifs
716 if (withderiv) {
717 tabAppV2d(NbPoles2d+j).SetCoord(tabDW(j),0.);
718 newDv.SetLinearForm(tabDW(j),tabAppP(j).XYZ(),tabW(j),tabAppV(j).XYZ());
719 tabAppV(j).SetCoord(DX*newDv.X(),DY*newDv.Y(),DZ*newDv.Z());
720 }
721 tabAppP(j).SetXYZ(tabAppP(j).XYZ() * tabW(j));
722 tabAppP2d(NbPoles2d+j).SetCoord(tabW(j),0.);
723 tabAppP(j).Coord(x,y,z);
724 tabAppP(j).SetCoord(DX*x+X,DY*y+Y,DZ*z+Z);
725 }
726 if (withderiv) {
727 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d,tabAppV,tabAppV2d);
728 if(i == 1) Cfirst = AppParCurves_TangencyPoint;
729 else if(i == NbPoint) Clast = AppParCurves_TangencyPoint;
730 }
731 else {
732 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d);
733 if(i == 1) Cfirst = AppParCurves_PassPoint;
734 else if(i == NbPoint) Clast = AppParCurves_PassPoint;
735 }
736 multL.SetValue(i,multP);
737 }
738
739
740 //IFV 04.06.07 occ13904
741 if(NbPoint == 2) {
742 dmin = 1;
743 if(Cfirst == AppParCurves_PassPoint && Clast == AppParCurves_PassPoint) {
744 dmax = 1;
745 }
746 }
747
748// modified by EAP Thu Jan 3 15:44:13 2002 ___BEGIN___
749 Standard_Real Ufloc=0., Ulloc=0.;
750 AppDef_Compute theapprox (dmin,dmax,tol3d,tol2d,nbit);
751 if (knownp) {
752 math_Vector theParams(1,NbPoint);
753 // On recale les parametres entre 0 et 1.
754 /*Standard_Real*/ Ufloc = F.Parameter(Lin->Point(StPoint));
755 /*Standard_Real*/ Ulloc = F.Parameter(Lin->Point(StPoint+NbPoint-1));
756// modified by EAP Thu Jan 3 15:45:17 2002 ___END___
757 for (i=1; i <= NbPoint; i++) {
758 Standard_Integer iLin = StPoint + i - 1;
759 theParams(i) = (F.Parameter(Lin->Point(iLin))-Ufloc)/(Ulloc - Ufloc);
760 }
761 AppDef_Compute theAppDef1(theParams,dmin,dmax,tol3d,tol2d,nbit, Standard_True,Standard_True);
762 theapprox = theAppDef1;
763 }
764 theapprox.SetConstraints(Cfirst,Clast);
765 theapprox.Perform(multL);
766
767// modified by EAP Thu Jan 3 16:00:43 2002 ___BEGIN___
768 // To know internal parameters if multicurve is approximated by several Bezier's
769 TColStd_SequenceOfReal aPoleDistSeq;
770 Standard_Real aWholeDist=0;
771// modified by EAP Thu Jan 3 16:45:48 2002 ___END___
772 Standard_Real TheTol3d, TheTol2d;
773 for (Standard_Integer Index=1; Index<=theapprox.NbMultiCurves(); Index++) {
774 AppParCurves_MultiCurve& mucu = theapprox.ChangeValue(Index);
775 theapprox.Error(Index, TheTol3d, TheTol2d);
776 mytol3d = Max(TheTol3d/DX, mytol3d);
777 mytol3d = Max(TheTol3d/DY, mytol3d);
778 mytol3d = Max(TheTol3d/DZ, mytol3d);
779 for(j = 1; j <= NbUPoles; j++){
780 mucu.Transform(j,
781 -X/DX,1./DX,
782 -Y/DY,1./DY,
783 -Z/DZ,1./DZ);
784 }
785 for(j = 1; j <= NbPoles2d; j++){
786 mucu.Transform2d(j + NbUPoles,
787 -X2d(j)/DX2d(j),1./DX2d(j),
788 -Y2d(j)/DY2d(j),1./DY2d(j));
789 mytol2d = Max(TheTol2d/DX2d(j), mytol2d);
790 mytol2d = Max(TheTol2d/DY2d(j), mytol2d);
791 }
792 concat.Append(mucu);
793
794// modified by EAP Thu Jan 3 15:45:23 2002 ___BEGIN___
795 if (knownp && theapprox.NbMultiCurves() > 1)
796 {
797 gp_Pnt aFirstPole = mucu.Pole(Index, 1);
798 gp_Pnt aLastPole = mucu.Pole(Index, mucu.NbPoles());
799 aPoleDistSeq.Append (aFirstPole.Distance(aLastPole));
800 aWholeDist += aPoleDistSeq.Last();
801 }
802 }
803 if (knownp)
804 {
805 Standard_Integer iDist;
806 Standard_Real iU = Ufloc;
807 for (iDist=1; iDist<aPoleDistSeq.Length(); iDist++)
808 {
809 iU += aPoleDistSeq(iDist) / aWholeDist * (Ulloc - Ufloc);
810 //cout << "Internal: " << iU << endl;
811 aParamSeq.Append(iU);
812 }
813 aParamSeq.Append(Ulloc);
814 }
815// modified by EAP Thu Jan 3 15:45:27 2002 ___END___
816 }
0797d9d3 817#ifdef OCCT_DEBUG
7fd59977 818 cout << " Tolerances obtenues --> 3d : "<< mytol3d << endl;
819 cout << " --> 2d : "<< mytol2d << endl;
820#endif
821 tol3dreached = mytol3d;
822 tol2dreached = mytol2d;
823 concat.Perform();
824 const AppParCurves_MultiBSpCurve& multC = concat.Value();
825 vdeg = multC.Degree();
826 NbVPoles = multC.NbPoles();
827
828 tabPoles = new TColgp_HArray2OfPnt (1,NbUPoles,1,NbVPoles);
829 tabWeights = new TColStd_HArray2OfReal (1,NbUPoles,1,NbVPoles);
830 tabVKnots = new TColStd_HArray1OfReal (multC.Knots().Lower(),
831 multC.Knots().Upper());
832 tabVKnots->ChangeArray1() = multC.Knots();
833
834 if (knownp) {
835// modified by EAP Fri Jan 4 12:07:30 2002 ___BEGIN___
836 if (aParamSeq.Length() != tabVKnots->Length())
837 {
838 BSplCLib::Reparametrize(F.Parameter(Lin->Point(1)),
839 F.Parameter(Lin->Point(Lin->NbPoints())),
840 tabVKnots->ChangeArray1()
841 );
0797d9d3 842#ifdef OCCT_DEBUG
7fd59977 843 cout << "Warning: AppBlend_AppSurf::Perform(), bad length of aParamSeq: " <<
844 aParamSeq.Length() << " instead of " << tabVKnots->Length() << endl;
845#endif
846 }
847 else
848 {
849 Standard_Integer iKnot, iTabKnot = tabVKnots->Lower();
850 for (iKnot=1; iKnot<=aParamSeq.Length(); iKnot++, iTabKnot++)
851 {
852 //cout << "Replace " << tabVKnots->Value(iTabKnot) << " with " << aParamSeq(iKnot) << endl;
853 tabVKnots->SetValue(iTabKnot, aParamSeq(iKnot));
854 }
855 }
856// modified by EAP Fri Jan 4 12:07:35 2002 ___END___
857 }
858
859 tabVMults = new TColStd_HArray1OfInteger (multC.Multiplicities().Lower(),
860 multC.Multiplicities().Upper());
861 tabVMults->ChangeArray1() = multC.Multiplicities();
862
863
864 TColgp_Array1OfPnt newtabP(1,NbVPoles);
865 Handle(TColgp_HArray1OfPnt2d) newtabP2d =
866 new TColgp_HArray1OfPnt2d(1,NbVPoles);
867 for (j=1; j <=NbUPoles; j++) {
868 multC.Curve(j,newtabP);
869 multC.Curve(j+NbUPoles+NbPoles2d,newtabP2d->ChangeArray1());
870 for (k=1; k<=NbVPoles; k++) {
871 // pour les courbes rationnelles il faut maintenant diviser
872 // les poles par leurs poids respectifs
873 tabPoles->ChangeValue(j,k).
874 SetXYZ(newtabP(k).XYZ()/newtabP2d->Value(k).X());
875 tabWeights->SetValue(j,k,newtabP2d->Value(k).X());
876 }
877 }
878
879 for (j=1; j<=NbPoles2d; j++) {
880 newtabP2d = new TColgp_HArray1OfPnt2d(1,NbVPoles);
881 multC.Curve(NbUPoles+j,newtabP2d->ChangeArray1());
882 seqPoles2d.Append(newtabP2d);
883 }
884
885 done = Standard_True;
886}
887
888
889//=======================================================================
890//function : SurfShape
891//purpose :
892//=======================================================================
893
894void AppBlend_AppSurf::SurfShape (Standard_Integer& UDegree,
895 Standard_Integer& VDegree,
896 Standard_Integer& NbUPoles,
897 Standard_Integer& NbVPoles,
898 Standard_Integer& NbUKnots,
899 Standard_Integer& NbVKnots) const
900{
901 if (!done) {StdFail_NotDone::Raise();}
902 UDegree = udeg;
903 VDegree = vdeg;
904 NbUPoles = tabPoles->ColLength();
905 NbVPoles = tabPoles->RowLength();
906 NbUKnots = tabUKnots->Length();
907 NbVKnots = tabVKnots->Length();
908}
909
910
911void AppBlend_AppSurf::Surface(TColgp_Array2OfPnt& TPoles,
912 TColStd_Array2OfReal& TWeights,
913 TColStd_Array1OfReal& TUKnots,
914 TColStd_Array1OfReal& TVKnots,
915 TColStd_Array1OfInteger& TUMults,
916 TColStd_Array1OfInteger& TVMults) const
917
918{
919 if (!done) {StdFail_NotDone::Raise();}
920 TPoles = tabPoles->Array2();
921 TWeights = tabWeights->Array2();
922 TUKnots = tabUKnots->Array1();
923 TUMults = tabUMults->Array1();
924 TVKnots = tabVKnots->Array1();
925 TVMults = tabVMults->Array1();
926}
927
928//=======================================================================
929//function : Curves2dShape
930//purpose :
931//=======================================================================
932
933void AppBlend_AppSurf::Curves2dShape(Standard_Integer& Degree,
934 Standard_Integer& NbPoles,
935 Standard_Integer& NbKnots) const
936{
937 if (!done) {StdFail_NotDone::Raise();}
938 if (seqPoles2d.Length() == 0) {Standard_DomainError::Raise();}
939 Degree = vdeg;
940 NbPoles = tabPoles->ColLength();
941 NbKnots = tabVKnots->Length();
942}
943
944//=======================================================================
945//function : Curve2d
946//purpose :
947//=======================================================================
948
949void AppBlend_AppSurf::Curve2d(const Standard_Integer Index,
950 TColgp_Array1OfPnt2d& TPoles,
951 TColStd_Array1OfReal& TKnots,
952 TColStd_Array1OfInteger& TMults) const
953{
954 if (!done) {StdFail_NotDone::Raise();}
955 if (seqPoles2d.Length() == 0) {Standard_DomainError::Raise();}
956 TPoles = seqPoles2d(Index)->Array1();
957 TKnots = tabVKnots->Array1();
958 TMults = tabVMults->Array1();
959}
960
961//=======================================================================
962//function : TolCurveOnSurf
963//purpose :
964//=======================================================================
965
966Standard_Real AppBlend_AppSurf::TolCurveOnSurf(const Standard_Integer) const
967{
968 return tol3dreached; //On ne s'embete pas !!
969}
970
971
972