Integration of OCCT 6.5.0 from SVN
[occt.git] / src / GeomFill / GeomFill_Sweep.cxx
CommitLineData
7fd59977 1// File: GeomFill_Sweep.cxx
2// Created: Fri Nov 21 15:18:22 1997
3// Author: Philippe MANGIN
4// <pmn@sgi29>
5
6// Modified by skv - Fri Feb 6 11:44:48 2004 OCC5073
7
8#include <GeomFill_Sweep.ixx>
9#include <GeomFill_SweepFunction.hxx>
10#include <GeomFill_LocFunction.hxx>
11
12#include <Standard_ErrorHandler.hxx>
13
14#include <gp_Pnt2d.hxx>
15#include <gp_Dir2d.hxx>
16#include <gp_Pnt.hxx>
17#include <gp_Dir.hxx>
18#include <gp_Lin.hxx>
19#include <gp_Circ.hxx>
20#include <gp_GTrsf.hxx>
21#include <gp_Mat.hxx>
22#include <gp_Ax2.hxx>
23
24#include <TColgp_Array1OfPnt.hxx>
25#include <TColgp_Array2OfPnt.hxx>
26#include <TColgp_HArray2OfPnt.hxx>
27//#include <GeomLib_Array1OfMat.hxx>
28#include <TColStd_Array1OfInteger.hxx>
29#include <TColStd_Array1OfReal.hxx>
30#include <TColStd_Array2OfReal.hxx>
31
32#include <GeomAbs_CurveType.hxx>
33#include <GeomAdaptor_Curve.hxx>
34#include <GeomLib.hxx>
35
36#include <Geom2d_Line.hxx>
37#include <Geom2d_BSplineCurve.hxx>
38#include <Geom2d_TrimmedCurve.hxx>
39
40#include <Geom_Circle.hxx>
41#include <Geom_Line.hxx>
42#include <Geom_BSplineSurface.hxx>
43#include <Geom_Plane.hxx>
44#include <Geom_SurfaceOfLinearExtrusion.hxx>
45#include <Geom_CylindricalSurface.hxx>
46#include <Geom_ConicalSurface.hxx>
47#include <Geom_ToroidalSurface.hxx>
48#include <Geom_SphericalSurface.hxx>
49#include <Geom_SurfaceOfRevolution.hxx>
50#include <Geom_RectangularTrimmedSurface.hxx>
51
52#include <Approx_SweepApproximation.hxx>
53#include <AdvApprox_PrefAndRec.hxx>
54#include <AdvApprox_ApproxAFunction.hxx>
55
56#include <Precision.hxx>
57#include <ElCLib.hxx>
58
59//=======================================================================
60//class : GeomFill_Sweep_Eval
61//purpose: The evaluator for curve approximation
62//=======================================================================
63
64class GeomFill_Sweep_Eval : public AdvApprox_EvaluatorFunction
65{
66 public:
67 GeomFill_Sweep_Eval (GeomFill_LocFunction& theTool)
68 : theAncore(theTool) {}
69
70 virtual void Evaluate (Standard_Integer *Dimension,
71 Standard_Real StartEnd[2],
72 Standard_Real *Parameter,
73 Standard_Integer *DerivativeRequest,
74 Standard_Real *Result, // [Dimension]
75 Standard_Integer *ErrorCode);
76
77 private:
78 GeomFill_LocFunction& theAncore;
79};
80
81void GeomFill_Sweep_Eval::Evaluate (Standard_Integer *,/*Dimension*/
82 Standard_Real StartEnd[2],
83 Standard_Real *Parameter,
84 Standard_Integer *DerivativeRequest,
85 Standard_Real *Result,// [Dimension]
86 Standard_Integer *ErrorCode)
87{
88 theAncore.DN (*Parameter,
89 StartEnd[0],
90 StartEnd[1],
91 *DerivativeRequest,
92 Result[0],
93 ErrorCode[0]);
94}
95
96//===============================================================
97// Function : Create
98// Purpose :
99//===============================================================
100GeomFill_Sweep::GeomFill_Sweep(const Handle(GeomFill_LocationLaw)& Location,
101 const Standard_Boolean WithKpart)
102{
103 done = Standard_False;
104
105 myLoc = Location;
106 myKPart = WithKpart;
107 SetTolerance(1.e-4);
108
109 myLoc->GetDomain(First, Last);
110 SFirst = SLast = 30.081996;
111 SError = RealLast();
112}
113
114//===============================================================
115// Function : SetDomain
116// Purpose :
117//===============================================================
118 void GeomFill_Sweep::SetDomain(const Standard_Real LocFirst,
119 const Standard_Real LocLast,
120 const Standard_Real SectionFirst,
121 const Standard_Real SectionLast)
122{
123 First = LocFirst;
124 Last = LocLast;
125 SFirst = SectionFirst;
126 SLast = SectionLast;
127}
128
129//===============================================================
130// Function : SetTolerance
131// Purpose :
132//===============================================================
133 void GeomFill_Sweep::SetTolerance(const Standard_Real Tolerance3d,
134 const Standard_Real BoundTolerance,
135 const Standard_Real Tolerance2d,
136 const Standard_Real ToleranceAngular)
137{
138 Tol3d = Tolerance3d;
139 BoundTol = BoundTolerance;
140 Tol2d =Tolerance2d;
141 TolAngular = ToleranceAngular;
142}
143
144//===============================================================
145// Function : ExchangeUV
146// Purpose :
147//===============================================================
148 Standard_Boolean GeomFill_Sweep::ExchangeUV() const
149{
150 return myExchUV;
151}
152
153//===============================================================
154// Function : UReversed
155// Purpose :
156//===============================================================
157 Standard_Boolean GeomFill_Sweep::UReversed() const
158{
159 return isUReversed;
160}
161
162//===============================================================
163// Function : VReversed
164// Purpose :
165//===============================================================
166 Standard_Boolean GeomFill_Sweep::VReversed() const
167{
168 return isVReversed;
169}
170
171//===============================================================
172// Function : Build
173// Purpose :
174//===============================================================
175 void GeomFill_Sweep::Build(const Handle(GeomFill_SectionLaw)& Section,
176 const GeomFill_ApproxStyle Methode,
177 const GeomAbs_Shape Continuity,
178 const Standard_Integer Degmax,
179 const Standard_Integer Segmax)
180{
181 // Inits
182 done = Standard_False;
183 myExchUV = Standard_False;
184 isUReversed = isVReversed = Standard_False;
185 mySec = Section;
186
187 if ((SFirst == SLast) && (SLast == 30.081996)) {
188 mySec->GetDomain(SFirst, SLast);
189 }
190
191 Standard_Boolean isKPart = Standard_False,
192 isProduct = Standard_False;
193
194 // Traitement des KPart
195 if (myKPart) isKPart = BuildKPart();
196
197 // Traitement des produits Formelles
198 if ((!isKPart) && (Methode == GeomFill_Location)) {
199 Handle(Geom_BSplineSurface) BS;
200 BS = mySec->BSplineSurface();
201 if (! BS.IsNull()) {
202 // Approx de la loi
203// isProduct = BuildProduct(Continuity, Degmax, Segmax);
204 }
205 }
206
207 if (isKPart || isProduct) {
208 // Approx du 2d
209 done = Build2d(Continuity, Degmax, Segmax);
210 }
211 else {
212 // Approx globale
213 done = BuildAll(Continuity, Degmax, Segmax);
214 }
215}
216
217//===============================================================
218// Function ::Build2d
219// Purpose :A venir...
220//===============================================================
221// Standard_Boolean GeomFill_Sweep::Build2d(const GeomAbs_Shape Continuity,
222 Standard_Boolean GeomFill_Sweep::Build2d(const GeomAbs_Shape ,
223// const Standard_Integer Degmax,
224 const Standard_Integer ,
225// const Standard_Integer Segmax)
226 const Standard_Integer )
227{
228 Standard_Boolean Ok = Standard_False;
229 if (myLoc->Nb2dCurves() == 0) {
230 Ok = Standard_True;
231 }
232 return Ok;
233}
234
235//===============================================================
236// Function : BuildAll
237// Purpose :
238//===============================================================
239 Standard_Boolean GeomFill_Sweep::BuildAll(const GeomAbs_Shape Continuity,
240 const Standard_Integer Degmax,
241 const Standard_Integer Segmax)
242{
243 Standard_Boolean Ok = Standard_False;
244 Standard_Integer nbsegmax = Segmax, nbspan = myLoc->NbIntervals(GeomAbs_C1);
245 if (Segmax < nbspan) nbsegmax = nbspan;
246
247 Handle(GeomFill_SweepFunction) Func
248 = new (GeomFill_SweepFunction) (mySec, myLoc, First, SFirst,
249 (SLast-SFirst)/(Last-First) );
250 Approx_SweepApproximation Approx( Func );
251
252 Approx.Perform(First, Last,
253 Tol3d, BoundTol, Tol2d, TolAngular,
254 Continuity, Degmax, Segmax);
255
256 if (Approx.IsDone()) {
257 Ok = Standard_True;
258
259#if DEB
260 Approx.Dump(cout);
261#endif
262
263 // La surface
264 Standard_Integer UDegree,VDegree,NbUPoles,
265 NbVPoles,NbUKnots,NbVKnots;
266 Approx.SurfShape(UDegree,VDegree,NbUPoles,
267 NbVPoles,NbUKnots,NbVKnots);
268
269 TColgp_Array2OfPnt Poles(1,NbUPoles, 1,NbVPoles);
270 TColStd_Array2OfReal Weights(1,NbUPoles, 1,NbVPoles);
271 TColStd_Array1OfReal UKnots(1, NbUKnots),VKnots(1, NbVKnots);
272 TColStd_Array1OfInteger UMults(1, NbUKnots), VMults(1, NbVKnots);
273
274 Approx.Surface(Poles, Weights,
275 UKnots,VKnots,
276 UMults,VMults);
277
278 mySurface = new (Geom_BSplineSurface)
279 (Poles, Weights,
280 UKnots,VKnots,
281 UMults,VMults,
282 Approx.UDegree(), Approx.VDegree(),
283 mySec->IsUPeriodic());
284 SError = Approx. MaxErrorOnSurf();
285
286 // Les Courbes 2d
287 myCurve2d = new (TColGeom2d_HArray1OfCurve) (1, 2+myLoc->TraceNumber());
288 CError = new (TColStd_HArray2OfReal) (1,2, 1, 2+myLoc->TraceNumber());
289 Standard_Integer kk,ii, ifin = 1, ideb;
290
291 if (myLoc->HasFirstRestriction()) {
292 ideb = 1;
293 }
294 else {
295 ideb = 2;
296 }
297 ifin += myLoc->TraceNumber();
298 if (myLoc->HasLastRestriction()) ifin++;
299
300 for (ii=ideb, kk=1; ii<=ifin; ii++, kk++) {
301 Handle(Geom2d_BSplineCurve) C
302 = new (Geom2d_BSplineCurve) (Approx.Curve2dPoles(kk),
303 Approx.Curves2dKnots(),
304 Approx.Curves2dMults(),
305 Approx.Curves2dDegree());
306 myCurve2d->SetValue(ii, C);
307 CError->SetValue(1, ii, Approx.Max2dError(kk));
308 CError->SetValue(2, ii, Approx.Max2dError(kk));
309 }
310
311 // Si les courbes de restriction, ne sont pas calcules, on prend
312 // les iso Bords.
313 if (! myLoc->HasFirstRestriction()) {
314 gp_Dir2d D(0., 1.);
315 gp_Pnt2d P(UKnots(UKnots.Lower()), 0);
316 Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
317 Handle(Geom2d_TrimmedCurve) TC = new (Geom2d_TrimmedCurve)
318 (LC, First, Last);
319
320 myCurve2d->SetValue(1, TC);
321 CError->SetValue(1, 1, 0.);
322 CError->SetValue(2, 1, 0.);
323 }
324
325 if (! myLoc->HasLastRestriction()) {
326 gp_Dir2d D(0., 1.);
327 gp_Pnt2d P(UKnots(UKnots.Upper()), 0);
328 Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
329 Handle(Geom2d_TrimmedCurve) TC =
330 new (Geom2d_TrimmedCurve) (LC, First, Last);
331 myCurve2d->SetValue(myCurve2d->Length(), TC);
332 CError->SetValue(1, myCurve2d->Length(), 0.);
333 CError->SetValue(2, myCurve2d->Length(), 0.);
334 }
335 }
336 return Ok;
337}
338
339//===============================================================
340// Function : BuildProduct
341// Purpose : A venir...
342//===============================================================
343 Standard_Boolean GeomFill_Sweep::BuildProduct(const GeomAbs_Shape Continuity,
344 const Standard_Integer Degmax,
345 const Standard_Integer Segmax)
346{
347 Standard_Boolean Ok = Standard_False;
348
349 Handle(Geom_BSplineSurface) BSurf;
350 BSurf = Handle(Geom_BSplineSurface)::DownCast(
351 mySec->BSplineSurface()->Copy());
352 if (BSurf.IsNull()) return Ok; // Ce mode de construction est impossible
353
354
355 Standard_Integer NbIntervalC2, NbIntervalC3;
356 GeomFill_LocFunction Func(myLoc);
357
358 NbIntervalC2 = myLoc->NbIntervals(GeomAbs_C2);
359 NbIntervalC3 = myLoc->NbIntervals(GeomAbs_C3);
360 TColStd_Array1OfReal Param_de_decoupeC2 (1, NbIntervalC2+1);
361 myLoc->Intervals(Param_de_decoupeC2, GeomAbs_C2);
362 TColStd_Array1OfReal Param_de_decoupeC3 (1, NbIntervalC3+1);
363 myLoc->Intervals(Param_de_decoupeC3, GeomAbs_C3);
364
365
366 AdvApprox_PrefAndRec Preferentiel(Param_de_decoupeC2,
367 Param_de_decoupeC3);
368
369 Handle(TColStd_HArray1OfReal) ThreeDTol = new (TColStd_HArray1OfReal) (1,4);
370 ThreeDTol->Init(Tol3d); // A Affiner...
371
372 GeomFill_Sweep_Eval eval (Func);
373 AdvApprox_ApproxAFunction Approx(0, 0, 4,
374 ThreeDTol,
375 ThreeDTol,
376 ThreeDTol,
377 First,
378 Last,
379 Continuity,
380 Degmax,
381 Segmax,
382 eval,
383 Preferentiel);
384#if DEB
385 Approx.Dump(cout);
386#endif
387
388 Ok = Approx.HasResult();
389 if (Ok) {
390/* TColgp_Array1OfMat TM(1, nbpoles);
391 Handle(TColgp_HArray2OfPnt) ResPoles;
392 ResPoles = Approx.Poles();
393
394 // Produit Tensoriel
395 for (ii=1; ii<=nbpoles; ii++) {
396 TM(ii).SetCols(ResPoles->Value(ii,2).XYZ(),
397 ResPoles->Value(ii,3).XYZ(),
398 ResPoles->Value(ii,4).XYZ());
399 TR(ii) = ResPoles->Value(ii,1);
400 }
401 GeomLib::TensorialProduct(BSurf, TM, TR,
402 Approx.Knots()->Array1(),
403 Approx.Multiplicities()->Array1());
404
405 // Somme
406 TColgp_Array1OfPnt TPoles(1, nbpoles);
407 for (ii=1; ii<=nbpoles; ii++) {
408 TPoles(ii) = ResPoles->Value(ii,1);
409 }
410 Handle(Geom_BsplineCurve) BS =
411 new (Geom_BsplineCurve) (Poles,
412 Approx.Knots()->Array1(),
413 Approx.Multiplicities()->Array1(),
414 Approx.Degree());
415 for (ii=1; ii<=BSurf->NbVKnots(); ii++)
416 BS->InsertKnot( BSurf->VKnot(ii),
417 BSurf->VMultiplicity(ii),
418 Precision::Confusion());
419 TColgp_Array2OfPnt SurfPoles (1, BSurf->NbUPoles());
420 for (ii=1;
421
422*/
423 mySurface = BSurf;
424 }
425 return Ok;
426}
427
428// Modified by skv - Thu Feb 5 18:05:03 2004 OCC5073 Begin
429// Conditions:
430// * theSec should be constant
431// * the type of section should be a line
432// * theLoc should represent a translation.
433
434static Standard_Boolean IsSweepParallelSpine (const Handle(GeomFill_LocationLaw) &theLoc,
435 const Handle(GeomFill_SectionLaw) &theSec,
436 const Standard_Real theTol)
437{
438 // Get the first and last transformations of the location
439 Standard_Real aFirst;
440 Standard_Real aLast;
441 gp_Vec VBegin;
442 gp_Vec VEnd;
443 gp_Mat M;
444 gp_GTrsf GTfBegin;
445 gp_Trsf TfBegin;
446 gp_GTrsf GTfEnd;
447 gp_Trsf TfEnd;
448
449 theLoc->GetDomain(aFirst, aLast);
450
451// Get the first transformation
452 theLoc->D0(aFirst, M, VBegin);
453
454 GTfBegin.SetVectorialPart(M);
455 GTfBegin.SetTranslationPart(VBegin.XYZ());
456
457 TfBegin.SetValues(GTfBegin(1,1), GTfBegin(1,2), GTfBegin(1,3), GTfBegin(1,4),
458 GTfBegin(2,1), GTfBegin(2,2), GTfBegin(2,3), GTfBegin(2,4),
459 GTfBegin(3,1), GTfBegin(3,2), GTfBegin(3,3), GTfBegin(3,4),
460 1.e-12, 1.e-14);
461
462// Get the last transformation
463 theLoc->D0(aLast, M, VEnd);
464
465 GTfEnd.SetVectorialPart(M);
466 GTfEnd.SetTranslationPart(VEnd.XYZ());
467
468 TfEnd.SetValues(GTfEnd(1,1), GTfEnd(1,2), GTfEnd(1,3), GTfEnd(1,4),
469 GTfEnd(2,1), GTfEnd(2,2), GTfEnd(2,3), GTfEnd(2,4),
470 GTfEnd(3,1), GTfEnd(3,2), GTfEnd(3,3), GTfEnd(3,4),
471 1.e-12, 1.e-14);
472
473 Handle(Geom_Surface) aSurf = theSec->BSplineSurface();
474 Standard_Real Umin;
475 Standard_Real Umax;
476 Standard_Real Vmin;
477 Standard_Real Vmax;
478
479 aSurf->Bounds(Umin, Umax, Vmin, Vmax);
480
481 // Get and transform the first section
482 Handle(Geom_Curve) FirstSection = theSec->ConstantSection();
483 GeomAdaptor_Curve ACFirst(FirstSection);
484
485 Standard_Real UFirst = ACFirst.FirstParameter();
486 gp_Lin L = ACFirst.Line();
487
488 L.Transform(TfBegin);
489
490 // Get and transform the last section
491 Handle(Geom_Curve) aLastSection = aSurf->VIso(Vmax);
492 Standard_Real aFirstParameter = aLastSection->FirstParameter();
493 gp_Pnt aPntLastSec = aLastSection->Value(aFirstParameter);
494
495 aPntLastSec.Transform(TfEnd);
496
497 gp_Pnt aPntFirstSec = ElCLib::Value( UFirst, L );
498 gp_Vec aVecSec( aPntFirstSec, aPntLastSec );
499 gp_Vec aVecSpine = VEnd - VBegin;
500
501 Standard_Boolean isParallel = aVecSec.IsParallel(aVecSpine, theTol);
502
503 return isParallel;
504}
505// Modified by skv - Thu Feb 5 18:05:01 2004 OCC5073 End
506
507//===============================================================
508// Function : BuildKPart
509// Purpose :
510//===============================================================
511 Standard_Boolean GeomFill_Sweep::BuildKPart()
512{
513 Standard_Boolean Ok = Standard_False;
514 Standard_Boolean isUPeriodic = Standard_False;
515 Standard_Boolean isVPeriodic = Standard_False;
516 Standard_Boolean IsTrsf = Standard_True;
517
518 isUPeriodic = mySec->IsUPeriodic();
519 Handle(Geom_Surface) S;
520 GeomAbs_CurveType SectionType;
521 gp_Vec V;
522 gp_Mat M;
523 Standard_Real levier, error = 0 ;
524 Standard_Real UFirst=0, VFirst=First, ULast=0, VLast=Last;
525 Standard_Real Tol = Min (Tol3d, BoundTol);
526
527 // (1) Trajectoire Rectilignes -------------------------
528 if (myLoc->IsTranslation(error)) {
529 // Donne de la translation
530 gp_Vec DP, DS;
531 myLoc->D0(1, M, DS);
532 myLoc->D0(0, M, V);
533 DP = DS - V;
534 DP.Normalize();
535 gp_GTrsf Tf;
536 gp_Trsf Tf2;
537 Tf.SetVectorialPart(M);
538 Tf.SetTranslationPart(V.XYZ());
539 try { // Pas joli mais il n'y as pas d'autre moyens de tester SetValues
540 OCC_CATCH_SIGNALS
541 Tf2.SetValues(Tf(1,1), Tf(1,2), Tf(1,3), Tf(1,4),
542 Tf(2,1), Tf(2,2), Tf(2,3), Tf(2,4),
543 Tf(3,1), Tf(3,2), Tf(3,3), Tf(3,4),
544 1.e-12, 1.e-14);
545 }
546 catch (Standard_ConstructionError) {
547 IsTrsf = Standard_False;
548 }
549 if (!IsTrsf) {
550 return Standard_False;
551 }
552
553 // (1.1) Cas Extrusion
554 if (mySec->IsConstant(error)) {
555 Handle(Geom_Curve) Section;
556 Section = mySec->ConstantSection();
557 GeomAdaptor_Curve AC(Section);
558 SectionType = AC.GetType();
559 UFirst = AC.FirstParameter();
560 ULast = AC.LastParameter();
561 // (1.1.a) Cas Plan
562 if ( (SectionType == GeomAbs_Line) && IsTrsf) {
563// Modified by skv - Thu Feb 5 11:39:06 2004 OCC5073 Begin
564 if (!IsSweepParallelSpine(myLoc, mySec, Tol))
565 return Standard_False;
566// Modified by skv - Thu Feb 5 11:39:08 2004 OCC5073 End
567 gp_Lin L = AC.Line();
568 L.Transform(Tf2);
569 DS.SetXYZ(L.Position().Direction().XYZ());
570 DS.Normalize();
571 levier = Abs(DS.Dot(DP));
572 SError = error + levier * Abs(Last-First);
573 if (SError <= Tol) {
574 Ok = Standard_True;
575 gp_Ax2 AxisOfPlane (L.Location(), DS^DP, DS);
576 S = new (Geom_Plane) (AxisOfPlane);
577 }
578 else SError = 0.;
579 }
580
581 // (1.1.b) Cas Cylindrique
582 if ( (SectionType == GeomAbs_Circle) && IsTrsf) {
583 gp_Circ C = AC.Circle();
584 C.Transform(Tf2);
585
586 DS.SetXYZ (C.Position().Direction().XYZ());
587 DS.Normalize();
588 levier = Abs(DS.CrossMagnitude(DP)) * C.Radius();
589 SError = levier * Abs(Last - First);
590 if (SError <= Tol) {
591 Ok = Standard_True;
592 gp_Ax3 axe (C.Location(), DP, C.Position().XDirection());
593 S = new (Geom_CylindricalSurface)
594 (axe, C.Radius());
595 if (C.Position().Direction().
596 IsOpposite(axe.Direction(), 0.1) ) {
597 Standard_Real f, l;
598 // L'orientation parametrique est inversee
599 l = 2*PI - UFirst;
600 f = 2*PI - ULast;
601 UFirst = f;
602 ULast = l;
603 isUReversed = Standard_True;
604 }
605 }
606 else SError = 0.;
607 }
608
609 // (1.1.c) C'est bien une extrusion
610 if (!Ok) {
611 if (IsTrsf) {
612 Section->Transform(Tf2);
613 S = new (Geom_SurfaceOfLinearExtrusion)
614 (Section, DP);
615 SError = 0.;
616 Ok = Standard_True;
617 }
618 else { // extrusion sur BSpline
619
620 }
621 }
622 }
623
624 // (1.2) Cas conique
625 else if (mySec->IsConicalLaw(error)) {
626
627 gp_Pnt P1, P2, Centre0, Centre1, Centre2;
628 gp_Vec dsection;
629 Handle(Geom_Curve) Section;
630 GeomAdaptor_Curve AC;
631 gp_Circ C;
632 Standard_Real R1, R2;
633
634
635 Section = mySec->CirclSection(SLast);
636 Section->Transform(Tf2);
637 Section->Translate(Last*DP);
638 AC.Load(Section);
639 C = AC.Circle();
640 Centre2 = C.Location();
641 AC.D1(0, P2, dsection);
642 R2 = C.Radius();
643
644 Section = mySec->CirclSection(SFirst);
645 Section->Transform(Tf2);
646 Section->Translate(First*DP);
647 AC.Load(Section);
648 C = AC.Circle();
649 Centre1 = C.Location();
650 P1 = AC.Value(0);
651 R1 = C.Radius();
652
653 Section = mySec->CirclSection(SFirst - First*(SLast-SFirst)/(Last-First));
654 Section->Transform(Tf2);
655 AC.Load(Section);
656 C = AC.Circle();
657 Centre0 = C.Location();
658
659 Standard_Real Angle;
660 gp_Vec N(Centre1, P1);
661 if (N.Magnitude() < 1.e-9) {
662 gp_Vec Bis(Centre2, P2);
663 N = Bis;
664 }
665 gp_Vec L(P1, P2), Dir(Centre1,Centre2);
666
667 Angle = L.Angle(Dir);
668 if ((Angle > 0.01) && (Angle < PI/2-0.01)) {
669 if (R2<R1) Angle = -Angle;
670 SError = error;
671 gp_Ax3 Axis(Centre0, Dir, N);
672 S = new (Geom_ConicalSurface)
673 (Axis, Angle, C.Radius());
674 // Calcul du glissement parametrique
675 VFirst = First / Cos(Angle);
676 VLast = Last / Cos(Angle);
677
678 // Bornes en U
679 UFirst = AC.FirstParameter();
680 ULast = AC.LastParameter();
681 gp_Vec diso;
682 gp_Pnt pbis;
683 S->VIso(VLast)->D1(0, pbis, diso);
684 if (diso.Magnitude()>1.e-9 && dsection.Magnitude()>1.e-9)
685 isUReversed = diso.IsOpposite(dsection, 0.1);
686 if (isUReversed ) {
687 Standard_Real f, l;
688 // L'orientation parametrique est inversee
689 l = 2*PI - UFirst;
690 f = 2*PI - ULast;
691 UFirst = f;
692 ULast = l;
693 }
694
695 // C'est un cone
696 Ok = Standard_True;
697 }
698 }
699 }
700
701 // (2) Trajectoire Circulaire
702 if (myLoc->IsRotation(error)) {
703 if (mySec->IsConstant(error)) {
704 // La trajectoire
705 gp_Pnt Centre;
706 isVPeriodic = (Abs(Last-First -2*PI) < 1.e-15);
707 Standard_Real RotRadius;
708 gp_Vec DP, DS, DN;
709 myLoc->D0(0.1, M, DS);
710 myLoc->D0(0, M, V);
711 myLoc->Rotation(Centre);
712
713 DP = DS - V;
714 DS.SetXYZ(V.XYZ() - Centre.XYZ());
715 RotRadius = DS.Magnitude();
716 if (RotRadius > 1.e-15) DS.Normalize();
717 else return Standard_False; // Pas de KPart, rotation degeneree
718 DN = DS ^ DP;
719 DN.Normalize();
720 DP = DN ^ DS;
721 DP.Normalize();
722
723 gp_GTrsf Tf;
724 gp_Trsf Tf2;
725 Tf.SetVectorialPart(M);
726 Tf.SetTranslationPart(V.XYZ());
727// try { // Pas joli mais il n'y as pas d'autre moyens de tester SetValues
728// OCC_CATCH_SIGNALS
729 Tf2.SetValues(Tf(1,1), Tf(1,2), Tf(1,3), Tf(1,4),
730 Tf(2,1), Tf(2,2), Tf(2,3), Tf(2,4),
731 Tf(3,1), Tf(3,2), Tf(3,3), Tf(3,4),
732 1.e-14, 1.e-15);
733// }
734// catch (Standard_ConstructionError) {
735// IsTrsf = Standard_False;
736// }
737 // La section
738 Handle(Geom_Curve) Section;
739 Section = mySec->ConstantSection();
740 GeomAdaptor_Curve AC(Section);
741 SectionType = AC.GetType();
742 UFirst = AC.FirstParameter();
743 ULast = AC.LastParameter();
744
745 // (2.1) Tore/Sphere ?
746 if ((SectionType == GeomAbs_Circle) && IsTrsf) {
747 gp_Circ C = AC.Circle();
748 Standard_Real Radius;
749 Standard_Boolean IsGoodSide = Standard_True;;
750 C.Transform(Tf2);
751 gp_Vec DC;
752 // On calcul le centre eventuel
753 DC.SetXYZ(C.Location().XYZ() - Centre.XYZ());
754 Centre.ChangeCoord() += (DC.Dot(DN))*DN.XYZ();
755 DC.SetXYZ(C.Location().XYZ() - Centre.XYZ());
756 Radius = DC.Magnitude(); //grand Rayon du tore
757 if ((Radius > Tol) && (DC.Dot(DS) < 0)) IsGoodSide = Standard_False;
758 if (Radius < Tol/100) DC = DS; // Pour definir le tore
759
760 // On verifie d'abord que le plan de la section est // a
761 // l'axe de rotation
762 gp_Vec NC;
763 NC.SetXYZ (C.Position().Direction().XYZ());
764 NC.Normalize();
765 error = Abs(NC.Dot(DN));
766 // Puis on evalue l'erreur commise sur la section,
767 // en pivotant son plan ( pour contenir l'axe de rotation)
768 error += Abs(NC.Dot(DS));
769 error *= C.Radius();
770 if (error <= Tol) {
771 SError = error;
772 error += Radius + Abs(RotRadius - C.Radius())/2;
773 if (error <= Tol) {
774 // (2.1.a) Sphere
775 Standard_Real f = UFirst , l = ULast;
776 SError = error;
777 Centre.BaryCenter(1.0, C.Location(), 1.0);
778 gp_Ax3 AxisOfSphere(Centre, DN, DS);
779 S = new (Geom_SphericalSurface)
780 (AxisOfSphere, (RotRadius + C.Radius())/2 );
781 // Pour les spheres on ne peut pas controler le parametre
782 // V (donc U car myExchUV = Standard_True)
783 // Il faut donc modifier UFirst, ULast...
784 if (C.Position().Direction().
785 IsOpposite(AxisOfSphere.YDirection(), 0.1) ) {
786 // L'orientation parametrique est inversee
787 l = 2*PI - UFirst;
788 f = 2*PI - ULast;
789 isUReversed = Standard_True;
790 }
791 // On calcul le "glissement" parametrique.
792 Standard_Real rot;
793 rot = C.Position().XDirection().AngleWithRef
794 (AxisOfSphere.XDirection(), AxisOfSphere.YDirection());
795 f -= rot;
796 l -= rot;
797
798 if ( (f >= -PI/2) && (l <= PI/2)) {
799 Ok = Standard_True;
800 myExchUV = Standard_True;
801 UFirst = f;
802 ULast = l;
803 }
804 else { // On restaure ce qu'il faut
805 isUReversed = Standard_False;
806 }
807 }
808 else if (IsGoodSide) {
809 // (2.1.b) Tore
810 gp_Ax3 AxisOfTore(Centre, DN, DC);
811 S = new (Geom_ToroidalSurface) (AxisOfTore,
812 Radius , C.Radius());
813
814 // Pour les tores on ne peut pas controler le parametre
815 // V (donc U car myExchUV = Standard_True)
816 // Il faut donc modifier UFirst, ULast...
817 Handle(Geom_Circle) Iso;
818 Iso = Handle(Geom_Circle)::DownCast(S->UIso(0.));
819 gp_Ax2 axeiso;
820 axeiso = Iso->Circ().Position();
821
822 if (C.Position().Direction().
823 IsOpposite(axeiso.Direction(), 0.1) ) {
824 Standard_Real f, l;
825 // L'orientation parametrique est inversee
826 l = 2*PI - UFirst;
827 f = 2*PI - ULast;
828 UFirst = f;
829 ULast = l;
830 isUReversed = Standard_True;
831 }
832 // On calcul le "glissement" parametrique.
833 Standard_Real rot;
834 rot = C.Position().XDirection().AngleWithRef
835 (axeiso.XDirection(), axeiso.Direction());
836 UFirst -= rot;
837 ULast -= rot;
838
839 myExchUV = Standard_True;
840 // Attention l'arete de couture dans le cas periodique
841 // n'est peut etre pas a la bonne place...
842 if (isUPeriodic && Abs(UFirst)>Precision::PConfusion())
843 isUPeriodic = Standard_False; //Pour trimmer la surface...
844 Ok = Standard_True;
845 }
846 }
847 else {
848 SError = 0.;
849 }
850 }
851 // (2.2) Cone / Cylindre
852 if ((SectionType == GeomAbs_Line) && IsTrsf) {
853 gp_Lin L = AC.Line();
854 L.Transform(Tf2);
855 gp_Vec DL;
856 DL.SetXYZ(L.Direction().XYZ());
857 levier = Max(Abs(AC.FirstParameter()), AC.LastParameter());
858 // si la line est ortogonale au cercle de rotation
859 SError = error + levier * Abs(DL.Dot(DP));
860 if (SError <= Tol) {
861 Standard_Boolean reverse;
862 gp_Lin Dir(Centre, DN);
863 Standard_Real aux;
864 aux = DL.Dot(DN);
865 reverse = (aux < 0); // On choisit ici le sens de parametrisation
866
867 // Calcul du centre du vecteur supportant la "XDirection"
868 gp_Pnt CentreOfSurf;
869 gp_Vec O1O2(Centre, L.Location()), trans;
870 trans = DN;
871 trans *= DN.Dot(O1O2);
872 CentreOfSurf = Centre.Translated(trans);
873 DS.SetXYZ(L.Location().XYZ() - CentreOfSurf.XYZ());
874
875 error = SError;
876 error += (DL.XYZ()).CrossMagnitude(DN.XYZ())*levier;
877 if (error <= Tol) {
878 // (2.2.a) Cylindre
879 // si la line est orthogonale au plan de rotation
880 SError = error;
881 gp_Ax3 Axis(CentreOfSurf, Dir.Direction(), DS);
882 S = new (Geom_CylindricalSurface)
883 (Axis, L.Distance(CentreOfSurf));
884 Ok = Standard_True;
885 myExchUV = Standard_True;
886 }
887 else {
888 // On evalue l'angle du cone
889 Standard_Real Angle = Abs(Dir.Angle(L));
890 if (Angle > PI/2) Angle = PI -Angle;
891 if (reverse) Angle = -Angle;
892 aux = DS.Dot(DL);
893 if (aux < 0) {
894 Angle = - Angle;
895 }
896 if (Abs(Abs(Angle) - PI/2) > 0.01) {
897 // (2.2.b) Cone
898 // si les 2 droites ne sont pas orthogonales
899 Standard_Real Radius = CentreOfSurf.Distance(L.Location());
900 gp_Ax3 Axis(CentreOfSurf, Dir.Direction(), DS);
901 S = new (Geom_ConicalSurface)
902 (Axis, Angle, Radius);
903 myExchUV = Standard_True;
904 Ok = Standard_True;
905 }
906 else {
907 // On n'as pas conclue, on remet l'erreur a 0.
908 SError = 0.;
909 }
910 }
911 if (Ok && reverse) {
912 // On reverse le parametre
913 Standard_Real uf, ul;
914 Handle(Geom_Line) CL = new (Geom_Line)(L);
915 uf = CL->ReversedParameter(ULast);
916 ul = CL->ReversedParameter(UFirst);
917 UFirst = uf;
918 ULast = ul;
919 isUReversed = Standard_True;
920 }
921 }
922 else SError = 0.;
923 }
924
925 // (2.3) Revolution
926 if (!Ok) {
927 if (IsTrsf) {
928 Section->Transform(Tf2);
929 gp_Ax1 Axis (Centre, DN);
930 S = new (Geom_SurfaceOfRevolution)
931 (Section, Axis);
932 myExchUV = Standard_True;
933 SError = 0.;
934 Ok = Standard_True;
935 }
936 }
937 }
938 }
939
940
941 if (Ok) { // On trimme la surface
942 if (myExchUV) {
943 Standard_Boolean b;
944 b = isUPeriodic; isUPeriodic = isVPeriodic; isVPeriodic = b;
945 Standard_Real r;
946 r = UFirst; UFirst = VFirst; VFirst = r;
947 r = ULast; ULast = VLast; VLast = r;
948 }
949
950 if (!isUPeriodic && !isVPeriodic)
951 mySurface = new (Geom_RectangularTrimmedSurface)
952 (S, UFirst, ULast, VFirst, VLast);
953 else if (isUPeriodic) {
954 if (isVPeriodic) mySurface = S;
955 else mySurface = new (Geom_RectangularTrimmedSurface)
956 (S, VFirst, VLast, Standard_False);
957 }
958 else
959 mySurface = new (Geom_RectangularTrimmedSurface)
960 (S,UFirst, ULast, Standard_True);
961
962#if DEB
963 if (isUPeriodic && !mySurface->IsUPeriodic())
964 cout<<"Pb de periodicite en U" << endl;
965 if (isUPeriodic && !mySurface->IsUClosed())
966 cout<<"Pb de fermeture en U" << endl;
967 if (isVPeriodic && !mySurface->IsVPeriodic())
968 cout << "Pb de periodicite en V" << endl;
969 if (isVPeriodic && !mySurface->IsVClosed())
970 cout<<"Pb de fermeture en V" << endl;
971#endif
972 }
973
974
975 return Ok;
976}
977
978//===============================================================
979// Function : IsDone
980// Purpose :
981//===============================================================
982 Standard_Boolean GeomFill_Sweep::IsDone() const
983{
984 return done;
985}
986
987//===============================================================
988// Function :ErrorOnSurface
989// Purpose :
990//===============================================================
991 Standard_Real GeomFill_Sweep::ErrorOnSurface() const
992{
993 return SError;
994}
995
996//===============================================================
997// Function ::ErrorOnRestriction
998// Purpose :
999//===============================================================
1000 void GeomFill_Sweep::ErrorOnRestriction(const Standard_Boolean IsFirst,
1001 Standard_Real& UError,
1002 Standard_Real& VError) const
1003{
1004 Standard_Integer ind;
1005 if (IsFirst) ind=1;
1006 else ind = myCurve2d->Length();
1007
1008 UError = CError->Value(1, ind);
1009 VError = CError->Value(2, ind);
1010}
1011
1012//===============================================================
1013// Function :ErrorOnTrace
1014// Purpose :
1015//===============================================================
1016 void GeomFill_Sweep::ErrorOnTrace(const Standard_Integer IndexOfTrace,
1017 Standard_Real& UError,
1018 Standard_Real& VError) const
1019{
1020 Standard_Integer ind = IndexOfTrace+1;
1021 if (IndexOfTrace > myLoc->TraceNumber())
1022 Standard_OutOfRange::Raise(" GeomFill_Sweep::ErrorOnTrace");
1023
1024 UError = CError->Value(1, ind);
1025 VError = CError->Value(2, ind);
1026}
1027
1028//===============================================================
1029// Function :Surface
1030// Purpose :
1031//===============================================================
1032 Handle(Geom_Surface) GeomFill_Sweep::Surface() const
1033{
1034 return mySurface;
1035}
1036
1037//===============================================================
1038// Function ::Restriction
1039// Purpose :
1040//===============================================================
1041 Handle(Geom2d_Curve) GeomFill_Sweep::Restriction(const Standard_Boolean IsFirst) const
1042{
1043 if (IsFirst)
1044 return myCurve2d->Value(1);
1045 return myCurve2d->Value(myCurve2d->Length());
1046
1047}
1048
1049//===============================================================
1050// Function :
1051// Purpose :
1052//===============================================================
1053 Standard_Integer GeomFill_Sweep::NumberOfTrace() const
1054{
1055 return myLoc->TraceNumber();
1056}
1057
1058//===============================================================
1059// Function :
1060// Purpose :
1061//===============================================================
1062 Handle(Geom2d_Curve)
1063 GeomFill_Sweep::Trace(const Standard_Integer IndexOfTrace) const
1064{
1065 Standard_Integer ind = IndexOfTrace+1;
1066 if (IndexOfTrace > myLoc->TraceNumber())
1067 Standard_OutOfRange::Raise(" GeomFill_Sweep::Trace");
1068 return myCurve2d->Value(ind);
1069}