1 // Created on: 1997-11-21
2 // Created by: Philippe MANGIN
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // Modified by skv - Fri Feb 6 11:44:48 2004 OCC5073
19 #include <GeomFill_Sweep.ixx>
20 #include <GeomFill_SweepFunction.hxx>
21 #include <GeomFill_LocFunction.hxx>
23 #include <Standard_ErrorHandler.hxx>
25 #include <gp_Pnt2d.hxx>
26 #include <gp_Dir2d.hxx>
30 #include <gp_Circ.hxx>
31 #include <gp_GTrsf.hxx>
34 #include <gp_Sphere.hxx>
36 #include <TColgp_Array1OfPnt.hxx>
37 #include <TColgp_Array2OfPnt.hxx>
38 #include <TColgp_HArray2OfPnt.hxx>
39 //#include <GeomLib_Array1OfMat.hxx>
40 #include <TColStd_Array1OfInteger.hxx>
41 #include <TColStd_Array1OfReal.hxx>
42 #include <TColStd_Array2OfReal.hxx>
44 #include <GeomAbs_CurveType.hxx>
45 #include <GeomAdaptor_Curve.hxx>
46 #include <GeomLib.hxx>
48 #include <Geom2d_Line.hxx>
49 #include <Geom2d_BSplineCurve.hxx>
50 #include <Geom2d_TrimmedCurve.hxx>
52 #include <Geom_Circle.hxx>
53 #include <Geom_Line.hxx>
54 #include <Geom_BSplineSurface.hxx>
55 #include <Geom_Plane.hxx>
56 #include <Geom_SurfaceOfLinearExtrusion.hxx>
57 #include <Geom_CylindricalSurface.hxx>
58 #include <Geom_ConicalSurface.hxx>
59 #include <Geom_ToroidalSurface.hxx>
60 #include <Geom_SphericalSurface.hxx>
61 #include <Geom_SurfaceOfRevolution.hxx>
62 #include <Geom_RectangularTrimmedSurface.hxx>
63 #include <Geom_TrimmedCurve.hxx>
65 #include <Approx_SweepApproximation.hxx>
66 #include <AdvApprox_PrefAndRec.hxx>
67 #include <AdvApprox_ApproxAFunction.hxx>
68 #include <GeomConvert_ApproxSurface.hxx>
70 #include <Precision.hxx>
74 //=======================================================================
75 //class : GeomFill_Sweep_Eval
76 //purpose: The evaluator for curve approximation
77 //=======================================================================
79 class GeomFill_Sweep_Eval : public AdvApprox_EvaluatorFunction
82 GeomFill_Sweep_Eval (GeomFill_LocFunction& theTool)
83 : theAncore(theTool) {}
85 virtual void Evaluate (Standard_Integer *Dimension,
86 Standard_Real StartEnd[2],
87 Standard_Real *Parameter,
88 Standard_Integer *DerivativeRequest,
89 Standard_Real *Result, // [Dimension]
90 Standard_Integer *ErrorCode);
93 GeomFill_LocFunction& theAncore;
96 void GeomFill_Sweep_Eval::Evaluate (Standard_Integer *,/*Dimension*/
97 Standard_Real StartEnd[2],
98 Standard_Real *Parameter,
99 Standard_Integer *DerivativeRequest,
100 Standard_Real *Result,// [Dimension]
101 Standard_Integer *ErrorCode)
103 theAncore.DN (*Parameter,
111 //===============================================================
114 //===============================================================
115 GeomFill_Sweep::GeomFill_Sweep(const Handle(GeomFill_LocationLaw)& Location,
116 const Standard_Boolean WithKpart)
118 done = Standard_False;
123 myForceApproxC1 = Standard_False;
125 myLoc->GetDomain(First, Last);
126 SFirst = SLast = 30.081996;
130 //===============================================================
131 // Function : SetDomain
133 //===============================================================
134 void GeomFill_Sweep::SetDomain(const Standard_Real LocFirst,
135 const Standard_Real LocLast,
136 const Standard_Real SectionFirst,
137 const Standard_Real SectionLast)
141 SFirst = SectionFirst;
145 //===============================================================
146 // Function : SetTolerance
148 //===============================================================
149 void GeomFill_Sweep::SetTolerance(const Standard_Real Tolerance3d,
150 const Standard_Real BoundTolerance,
151 const Standard_Real Tolerance2d,
152 const Standard_Real ToleranceAngular)
155 BoundTol = BoundTolerance;
157 TolAngular = ToleranceAngular;
160 //=======================================================================
161 //Function : SetForceApproxC1
162 //Purpose : Set the flag that indicates attempt to approximate
163 // a C1-continuous surface if a swept surface proved
165 //=======================================================================
166 void GeomFill_Sweep::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
168 myForceApproxC1 = ForceApproxC1;
172 //===============================================================
173 // Function : ExchangeUV
175 //===============================================================
176 Standard_Boolean GeomFill_Sweep::ExchangeUV() const
181 //===============================================================
182 // Function : UReversed
184 //===============================================================
185 Standard_Boolean GeomFill_Sweep::UReversed() const
190 //===============================================================
191 // Function : VReversed
193 //===============================================================
194 Standard_Boolean GeomFill_Sweep::VReversed() const
199 //===============================================================
202 //===============================================================
203 void GeomFill_Sweep::Build(const Handle(GeomFill_SectionLaw)& Section,
204 const GeomFill_ApproxStyle Methode,
205 const GeomAbs_Shape Continuity,
206 const Standard_Integer Degmax,
207 const Standard_Integer Segmax)
210 done = Standard_False;
211 myExchUV = Standard_False;
212 isUReversed = isVReversed = Standard_False;
215 if ((SFirst == SLast) && (SLast == 30.081996)) {
216 mySec->GetDomain(SFirst, SLast);
219 Standard_Boolean isKPart = Standard_False,
220 isProduct = Standard_False;
222 // Traitement des KPart
223 if (myKPart) isKPart = BuildKPart();
225 // Traitement des produits Formelles
226 if ((!isKPart) && (Methode == GeomFill_Location)) {
227 Handle(Geom_BSplineSurface) BS;
228 BS = mySec->BSplineSurface();
231 // isProduct = BuildProduct(Continuity, Degmax, Segmax);
235 if (isKPart || isProduct) {
237 done = Build2d(Continuity, Degmax, Segmax);
241 done = BuildAll(Continuity, Degmax, Segmax);
245 //===============================================================
246 // Function ::Build2d
247 // Purpose :A venir...
248 //===============================================================
249 // Standard_Boolean GeomFill_Sweep::Build2d(const GeomAbs_Shape Continuity,
250 Standard_Boolean GeomFill_Sweep::Build2d(const GeomAbs_Shape ,
251 // const Standard_Integer Degmax,
252 const Standard_Integer ,
253 // const Standard_Integer Segmax)
254 const Standard_Integer )
256 Standard_Boolean Ok = Standard_False;
257 if (myLoc->Nb2dCurves() == 0) {
263 //===============================================================
264 // Function : BuildAll
266 //===============================================================
267 Standard_Boolean GeomFill_Sweep::BuildAll(const GeomAbs_Shape Continuity,
268 const Standard_Integer Degmax,
269 const Standard_Integer Segmax)
271 Standard_Boolean Ok = Standard_False;
273 Handle(GeomFill_SweepFunction) Func
274 = new (GeomFill_SweepFunction) (mySec, myLoc, First, SFirst,
275 (SLast-SFirst)/(Last-First) );
276 Approx_SweepApproximation Approx( Func );
278 Approx.Perform(First, Last,
279 Tol3d, BoundTol, Tol2d, TolAngular,
280 Continuity, Degmax, Segmax);
282 if (Approx.IsDone()) {
290 Standard_Integer UDegree,VDegree,NbUPoles,
291 NbVPoles,NbUKnots,NbVKnots;
292 Approx.SurfShape(UDegree,VDegree,NbUPoles,
293 NbVPoles,NbUKnots,NbVKnots);
295 TColgp_Array2OfPnt Poles(1,NbUPoles, 1,NbVPoles);
296 TColStd_Array2OfReal Weights(1,NbUPoles, 1,NbVPoles);
297 TColStd_Array1OfReal UKnots(1, NbUKnots),VKnots(1, NbVKnots);
298 TColStd_Array1OfInteger UMults(1, NbUKnots), VMults(1, NbVKnots);
300 Approx.Surface(Poles, Weights,
304 mySurface = new (Geom_BSplineSurface)
308 Approx.UDegree(), Approx.VDegree(),
309 mySec->IsUPeriodic());
310 SError = Approx. MaxErrorOnSurf();
312 if (myForceApproxC1 && !mySurface->IsCNv(1))
314 Standard_Real theTol = 1.e-4;
315 GeomAbs_Shape theUCont = GeomAbs_C1, theVCont = GeomAbs_C1;
316 Standard_Integer degU = 14, degV = 14;
317 Standard_Integer nmax = 16;
318 Standard_Integer thePrec = 1;
320 GeomConvert_ApproxSurface ConvertApprox(mySurface,theTol,theUCont,theVCont,
321 degU,degV,nmax,thePrec);
322 if (ConvertApprox.HasResult())
324 mySurface = ConvertApprox.Surface();
325 myCurve2d = new (TColGeom2d_HArray1OfCurve) (1, 2);
326 CError = new (TColStd_HArray2OfReal) (1,2, 1,2);
328 Handle(Geom_BSplineSurface) BSplSurf (Handle(Geom_BSplineSurface)::DownCast(mySurface));
331 gp_Pnt2d P(BSplSurf->UKnot(1), 0);
332 Handle(Geom2d_Line) LC1 = new (Geom2d_Line) (P, D);
333 Handle(Geom2d_TrimmedCurve) TC1 =
334 new (Geom2d_TrimmedCurve) (LC1, 0, BSplSurf->VKnot(BSplSurf->NbVKnots()));
336 myCurve2d->SetValue(1, TC1);
337 CError->SetValue(1, 1, 0.);
338 CError->SetValue(2, 1, 0.);
340 P.SetCoord(BSplSurf->UKnot(BSplSurf->NbUKnots()), 0);
341 Handle(Geom2d_Line) LC2 = new (Geom2d_Line) (P, D);
342 Handle(Geom2d_TrimmedCurve) TC2 =
343 new (Geom2d_TrimmedCurve) (LC2, 0, BSplSurf->VKnot(BSplSurf->NbVKnots()));
345 myCurve2d->SetValue(myCurve2d->Length(), TC2);
346 CError->SetValue(1, myCurve2d->Length(), 0.);
347 CError->SetValue(2, myCurve2d->Length(), 0.);
351 } //if (!mySurface->IsCNv(1))
354 if (myCurve2d.IsNull())
356 myCurve2d = new (TColGeom2d_HArray1OfCurve) (1, 2+myLoc->TraceNumber());
357 CError = new (TColStd_HArray2OfReal) (1,2, 1, 2+myLoc->TraceNumber());
358 Standard_Integer kk,ii, ifin = 1, ideb;
360 if (myLoc->HasFirstRestriction()) {
366 ifin += myLoc->TraceNumber();
367 if (myLoc->HasLastRestriction()) ifin++;
369 for (ii=ideb, kk=1; ii<=ifin; ii++, kk++) {
370 Handle(Geom2d_BSplineCurve) C
371 = new (Geom2d_BSplineCurve) (Approx.Curve2dPoles(kk),
372 Approx.Curves2dKnots(),
373 Approx.Curves2dMults(),
374 Approx.Curves2dDegree());
375 myCurve2d->SetValue(ii, C);
376 CError->SetValue(1, ii, Approx.Max2dError(kk));
377 CError->SetValue(2, ii, Approx.Max2dError(kk));
380 // Si les courbes de restriction, ne sont pas calcules, on prend
382 if (! myLoc->HasFirstRestriction()) {
384 gp_Pnt2d P(UKnots(UKnots.Lower()), 0);
385 Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
386 Handle(Geom2d_TrimmedCurve) TC = new (Geom2d_TrimmedCurve)
389 myCurve2d->SetValue(1, TC);
390 CError->SetValue(1, 1, 0.);
391 CError->SetValue(2, 1, 0.);
394 if (! myLoc->HasLastRestriction()) {
396 gp_Pnt2d P(UKnots(UKnots.Upper()), 0);
397 Handle(Geom2d_Line) LC = new (Geom2d_Line) (P, D);
398 Handle(Geom2d_TrimmedCurve) TC =
399 new (Geom2d_TrimmedCurve) (LC, First, Last);
400 myCurve2d->SetValue(myCurve2d->Length(), TC);
401 CError->SetValue(1, myCurve2d->Length(), 0.);
402 CError->SetValue(2, myCurve2d->Length(), 0.);
404 } //if (myCurve2d.IsNull())
409 //===============================================================
410 // Function : BuildProduct
411 // Purpose : A venir...
412 //===============================================================
413 Standard_Boolean GeomFill_Sweep::BuildProduct(const GeomAbs_Shape Continuity,
414 const Standard_Integer Degmax,
415 const Standard_Integer Segmax)
417 Standard_Boolean Ok = Standard_False;
419 Handle(Geom_BSplineSurface) BSurf;
420 BSurf = Handle(Geom_BSplineSurface)::DownCast(
421 mySec->BSplineSurface()->Copy());
422 if (BSurf.IsNull()) return Ok; // Ce mode de construction est impossible
425 Standard_Integer NbIntervalC2, NbIntervalC3;
426 GeomFill_LocFunction Func(myLoc);
428 NbIntervalC2 = myLoc->NbIntervals(GeomAbs_C2);
429 NbIntervalC3 = myLoc->NbIntervals(GeomAbs_C3);
430 TColStd_Array1OfReal Param_de_decoupeC2 (1, NbIntervalC2+1);
431 myLoc->Intervals(Param_de_decoupeC2, GeomAbs_C2);
432 TColStd_Array1OfReal Param_de_decoupeC3 (1, NbIntervalC3+1);
433 myLoc->Intervals(Param_de_decoupeC3, GeomAbs_C3);
436 AdvApprox_PrefAndRec Preferentiel(Param_de_decoupeC2,
439 Handle(TColStd_HArray1OfReal) ThreeDTol = new (TColStd_HArray1OfReal) (1,4);
440 ThreeDTol->Init(Tol3d); // A Affiner...
442 GeomFill_Sweep_Eval eval (Func);
443 AdvApprox_ApproxAFunction Approx(0, 0, 4,
458 Ok = Approx.HasResult();
460 /* TColgp_Array1OfMat TM(1, nbpoles);
461 Handle(TColgp_HArray2OfPnt) ResPoles;
462 ResPoles = Approx.Poles();
465 for (ii=1; ii<=nbpoles; ii++) {
466 TM(ii).SetCols(ResPoles->Value(ii,2).XYZ(),
467 ResPoles->Value(ii,3).XYZ(),
468 ResPoles->Value(ii,4).XYZ());
469 TR(ii) = ResPoles->Value(ii,1);
471 GeomLib::TensorialProduct(BSurf, TM, TR,
472 Approx.Knots()->Array1(),
473 Approx.Multiplicities()->Array1());
476 TColgp_Array1OfPnt TPoles(1, nbpoles);
477 for (ii=1; ii<=nbpoles; ii++) {
478 TPoles(ii) = ResPoles->Value(ii,1);
480 Handle(Geom_BsplineCurve) BS =
481 new (Geom_BsplineCurve) (Poles,
482 Approx.Knots()->Array1(),
483 Approx.Multiplicities()->Array1(),
485 for (ii=1; ii<=BSurf->NbVKnots(); ii++)
486 BS->InsertKnot( BSurf->VKnot(ii),
487 BSurf->VMultiplicity(ii),
488 Precision::Confusion());
489 TColgp_Array2OfPnt SurfPoles (1, BSurf->NbUPoles());
498 // Modified by skv - Thu Feb 5 18:05:03 2004 OCC5073 Begin
500 // * theSec should be constant
501 // * the type of section should be a line
502 // * theLoc should represent a translation.
504 static Standard_Boolean IsSweepParallelSpine (const Handle(GeomFill_LocationLaw) &theLoc,
505 const Handle(GeomFill_SectionLaw) &theSec,
506 const Standard_Real theTol)
508 // Get the first and last transformations of the location
509 Standard_Real aFirst;
519 theLoc->GetDomain(aFirst, aLast);
521 // Get the first transformation
522 theLoc->D0(aFirst, M, VBegin);
524 GTfBegin.SetVectorialPart(M);
525 GTfBegin.SetTranslationPart(VBegin.XYZ());
527 TfBegin.SetValues(GTfBegin(1,1), GTfBegin(1,2), GTfBegin(1,3), GTfBegin(1,4),
528 GTfBegin(2,1), GTfBegin(2,2), GTfBegin(2,3), GTfBegin(2,4),
529 GTfBegin(3,1), GTfBegin(3,2), GTfBegin(3,3), GTfBegin(3,4));
531 // Get the last transformation
532 theLoc->D0(aLast, M, VEnd);
534 GTfEnd.SetVectorialPart(M);
535 GTfEnd.SetTranslationPart(VEnd.XYZ());
537 TfEnd.SetValues(GTfEnd(1,1), GTfEnd(1,2), GTfEnd(1,3), GTfEnd(1,4),
538 GTfEnd(2,1), GTfEnd(2,2), GTfEnd(2,3), GTfEnd(2,4),
539 GTfEnd(3,1), GTfEnd(3,2), GTfEnd(3,3), GTfEnd(3,4));
541 Handle(Geom_Surface) aSurf = theSec->BSplineSurface();
547 aSurf->Bounds(Umin, Umax, Vmin, Vmax);
549 // Get and transform the first section
550 Handle(Geom_Curve) FirstSection = theSec->ConstantSection();
551 GeomAdaptor_Curve ACFirst(FirstSection);
553 Standard_Real UFirst = ACFirst.FirstParameter();
554 gp_Lin L = ACFirst.Line();
556 L.Transform(TfBegin);
558 // Get and transform the last section
559 Handle(Geom_Curve) aLastSection = aSurf->VIso(Vmax);
560 Standard_Real aFirstParameter = aLastSection->FirstParameter();
561 gp_Pnt aPntLastSec = aLastSection->Value(aFirstParameter);
563 aPntLastSec.Transform(TfEnd);
565 gp_Pnt aPntFirstSec = ElCLib::Value( UFirst, L );
566 gp_Vec aVecSec( aPntFirstSec, aPntLastSec );
567 gp_Vec aVecSpine = VEnd - VBegin;
569 Standard_Boolean isParallel = aVecSec.IsParallel(aVecSpine, theTol);
573 // Modified by skv - Thu Feb 5 18:05:01 2004 OCC5073 End
575 //===============================================================
576 // Function : BuildKPart
578 //===============================================================
579 Standard_Boolean GeomFill_Sweep::BuildKPart()
581 Standard_Boolean Ok = Standard_False;
582 Standard_Boolean isUPeriodic = Standard_False;
583 Standard_Boolean isVPeriodic = Standard_False;
584 Standard_Boolean IsTrsf = Standard_True;
586 isUPeriodic = mySec->IsUPeriodic();
587 Handle(Geom_Surface) S;
588 GeomAbs_CurveType SectionType;
591 Standard_Real levier, error = 0 ;
592 Standard_Real UFirst=0, VFirst=First, ULast=0, VLast=Last;
593 Standard_Real Tol = Min (Tol3d, BoundTol);
595 // (1) Trajectoire Rectilignes -------------------------
596 if (myLoc->IsTranslation(error)) {
597 // Donne de la translation
605 Tf.SetVectorialPart(M);
606 Tf.SetTranslationPart(V.XYZ());
607 try { // Pas joli mais il n'y as pas d'autre moyens de tester SetValues
609 Tf2.SetValues(Tf(1,1), Tf(1,2), Tf(1,3), Tf(1,4),
610 Tf(2,1), Tf(2,2), Tf(2,3), Tf(2,4),
611 Tf(3,1), Tf(3,2), Tf(3,3), Tf(3,4));
613 catch (Standard_ConstructionError) {
614 IsTrsf = Standard_False;
617 return Standard_False;
620 // (1.1) Cas Extrusion
621 if (mySec->IsConstant(error)) {
622 Handle(Geom_Curve) Section;
623 Section = mySec->ConstantSection();
624 GeomAdaptor_Curve AC(Section);
625 SectionType = AC.GetType();
626 UFirst = AC.FirstParameter();
627 ULast = AC.LastParameter();
629 if ( (SectionType == GeomAbs_Line) && IsTrsf) {
630 // Modified by skv - Thu Feb 5 11:39:06 2004 OCC5073 Begin
631 if (!IsSweepParallelSpine(myLoc, mySec, Tol))
632 return Standard_False;
633 // Modified by skv - Thu Feb 5 11:39:08 2004 OCC5073 End
634 gp_Lin L = AC.Line();
636 DS.SetXYZ(L.Position().Direction().XYZ());
638 levier = Abs(DS.Dot(DP));
639 SError = error + levier * Abs(Last-First);
642 gp_Ax2 AxisOfPlane (L.Location(), DS^DP, DS);
643 S = new (Geom_Plane) (AxisOfPlane);
648 // (1.1.b) Cas Cylindrique
649 if ( (SectionType == GeomAbs_Circle) && IsTrsf) {
650 const Standard_Real TolProd = 1.e-6;
652 gp_Circ C = AC.Circle();
655 DS.SetXYZ (C.Position().Direction().XYZ());
657 levier = Abs(DS.CrossMagnitude(DP)) * C.Radius();
658 SError = levier * Abs(Last - First);
659 if (SError <= TolProd) {
661 gp_Ax3 axe (C.Location(), DP, C.Position().XDirection());
662 S = new (Geom_CylindricalSurface)
664 if (C.Position().Direction().
665 IsOpposite(axe.Direction(), 0.1) ) {
667 // L'orientation parametrique est inversee
672 isUReversed = Standard_True;
678 // (1.1.c) C'est bien une extrusion
681 Section->Transform(Tf2);
682 S = new (Geom_SurfaceOfLinearExtrusion)
687 else { // extrusion sur BSpline
694 else if (mySec->IsConicalLaw(error)) {
696 gp_Pnt P1, P2, Centre0, Centre1, Centre2;
698 Handle(Geom_Curve) Section;
699 GeomAdaptor_Curve AC;
701 Standard_Real R1, R2;
704 Section = mySec->CirclSection(SLast);
705 Section->Transform(Tf2);
706 Section->Translate(Last*DP);
709 Centre2 = C.Location();
710 AC.D1(0, P2, dsection);
713 Section = mySec->CirclSection(SFirst);
714 Section->Transform(Tf2);
715 Section->Translate(First*DP);
718 Centre1 = C.Location();
722 Section = mySec->CirclSection(SFirst - First*(SLast-SFirst)/(Last-First));
723 Section->Transform(Tf2);
726 Centre0 = C.Location();
729 gp_Vec N(Centre1, P1);
730 if (N.Magnitude() < 1.e-9) {
731 gp_Vec Bis(Centre2, P2);
734 gp_Vec L(P1, P2), Dir(Centre1,Centre2);
736 Angle = L.Angle(Dir);
737 if ((Angle > 0.01) && (Angle < M_PI/2-0.01)) {
738 if (R2<R1) Angle = -Angle;
740 gp_Ax3 Axis(Centre0, Dir, N);
741 S = new (Geom_ConicalSurface)
742 (Axis, Angle, C.Radius());
743 // Calcul du glissement parametrique
744 VFirst = First / Cos(Angle);
745 VLast = Last / Cos(Angle);
748 UFirst = AC.FirstParameter();
749 ULast = AC.LastParameter();
752 S->VIso(VLast)->D1(0, pbis, diso);
753 if (diso.Magnitude()>1.e-9 && dsection.Magnitude()>1.e-9)
754 isUReversed = diso.IsOpposite(dsection, 0.1);
757 // L'orientation parametrique est inversee
770 // (2) Trajectoire Circulaire
771 if (myLoc->IsRotation(error)) {
772 if (mySec->IsConstant(error)) {
775 isVPeriodic = (Abs(Last-First -2*M_PI) < 1.e-15);
776 Standard_Real RotRadius;
778 myLoc->D0(0.1, M, DS);
780 myLoc->Rotation(Centre);
783 DS.SetXYZ(V.XYZ() - Centre.XYZ());
784 RotRadius = DS.Magnitude();
785 if (RotRadius > 1.e-15) DS.Normalize();
786 else return Standard_False; // Pas de KPart, rotation degeneree
794 Tf.SetVectorialPart(M);
795 Tf.SetTranslationPart(V.XYZ());
796 // try { // Pas joli mais il n'y as pas d'autre moyens de tester SetValues
798 Tf2.SetValues(Tf(1,1), Tf(1,2), Tf(1,3), Tf(1,4),
799 Tf(2,1), Tf(2,2), Tf(2,3), Tf(2,4),
800 Tf(3,1), Tf(3,2), Tf(3,3), Tf(3,4));
802 // catch (Standard_ConstructionError) {
803 // IsTrsf = Standard_False;
806 Handle(Geom_Curve) Section;
807 Section = mySec->ConstantSection();
808 GeomAdaptor_Curve AC(Section);
809 SectionType = AC.GetType();
810 UFirst = AC.FirstParameter();
811 ULast = AC.LastParameter();
813 // (2.1) Tore/Sphere ?
814 if ((SectionType == GeomAbs_Circle) && IsTrsf) {
815 gp_Circ C = AC.Circle();
816 Standard_Real Radius;
817 Standard_Boolean IsGoodSide = Standard_True;;
820 // On calcul le centre eventuel
821 DC.SetXYZ(C.Location().XYZ() - Centre.XYZ());
822 Centre.ChangeCoord() += (DC.Dot(DN))*DN.XYZ();
823 DC.SetXYZ(C.Location().XYZ() - Centre.XYZ());
824 Radius = DC.Magnitude(); //grand Rayon du tore
825 if ((Radius > Tol) && (DC.Dot(DS) < 0)) IsGoodSide = Standard_False;
826 if (Radius < Tol/100) DC = DS; // Pour definir le tore
828 // On verifie d'abord que le plan de la section est // a
831 NC.SetXYZ (C.Position().Direction().XYZ());
833 error = Abs(NC.Dot(DN));
834 // Puis on evalue l'erreur commise sur la section,
835 // en pivotant son plan ( pour contenir l'axe de rotation)
836 error += Abs(NC.Dot(DS));
840 error += Radius + Abs(RotRadius - C.Radius())/2;
843 Standard_Real f = UFirst , l = ULast;
845 Centre.BaryCenter(1.0, C.Location(), 1.0);
846 gp_Ax3 AxisOfSphere(Centre, DN, DS);
847 gp_Sphere theSphere( AxisOfSphere, (RotRadius + C.Radius())/2 );
848 S = new Geom_SphericalSurface(theSphere);
849 // Pour les spheres on ne peut pas controler le parametre
850 // V (donc U car myExchUV = Standard_True)
851 // Il faut donc modifier UFirst, ULast...
852 Standard_Real fpar = AC.FirstParameter();
853 Standard_Real lpar = AC.LastParameter();
854 Handle(Geom_Curve) theSection = new Geom_TrimmedCurve(Section, fpar, lpar);
855 theSection->Transform(Tf2);
856 gp_Pnt FirstPoint = theSection->Value(theSection->FirstParameter());
857 gp_Pnt LastPoint = theSection->Value(theSection->LastParameter());
858 Standard_Real UfirstOnSec, VfirstOnSec, UlastOnSec, VlastOnSec;
859 ElSLib::Parameters(theSphere, FirstPoint, UfirstOnSec, VfirstOnSec);
860 ElSLib::Parameters(theSphere, LastPoint, UlastOnSec, VlastOnSec);
861 if (VfirstOnSec < VlastOnSec)
868 // L'orientation parametrique est inversee
871 isUReversed = Standard_True;
874 if ( (f >= -M_PI/2) && (l <= M_PI/2)) {
876 myExchUV = Standard_True;
880 else { // On restaure ce qu'il faut
881 isUReversed = Standard_False;
884 else if (IsGoodSide) {
886 gp_Ax3 AxisOfTore(Centre, DN, DC);
887 S = new (Geom_ToroidalSurface) (AxisOfTore,
888 Radius , C.Radius());
890 // Pour les tores on ne peut pas controler le parametre
891 // V (donc U car myExchUV = Standard_True)
892 // Il faut donc modifier UFirst, ULast...
893 Handle(Geom_Circle) Iso;
894 Iso = Handle(Geom_Circle)::DownCast(S->UIso(0.));
896 axeiso = Iso->Circ().Position();
898 if (C.Position().Direction().
899 IsOpposite(axeiso.Direction(), 0.1) ) {
901 // L'orientation parametrique est inversee
906 isUReversed = Standard_True;
908 // On calcul le "glissement" parametrique.
910 rot = C.Position().XDirection().AngleWithRef
911 (axeiso.XDirection(), axeiso.Direction());
915 myExchUV = Standard_True;
916 // Attention l'arete de couture dans le cas periodique
917 // n'est peut etre pas a la bonne place...
918 if (isUPeriodic && Abs(UFirst)>Precision::PConfusion())
919 isUPeriodic = Standard_False; //Pour trimmer la surface...
927 // (2.2) Cone / Cylindre
928 if ((SectionType == GeomAbs_Line) && IsTrsf) {
929 gp_Lin L = AC.Line();
932 DL.SetXYZ(L.Direction().XYZ());
933 levier = Max(Abs(AC.FirstParameter()), AC.LastParameter());
934 // si la line est ortogonale au cercle de rotation
935 SError = error + levier * Abs(DL.Dot(DP));
937 Standard_Boolean reverse;
938 gp_Lin Dir(Centre, DN);
941 reverse = (aux < 0); // On choisit ici le sens de parametrisation
943 // Calcul du centre du vecteur supportant la "XDirection"
945 gp_Vec O1O2(Centre, L.Location()), trans;
947 trans *= DN.Dot(O1O2);
948 CentreOfSurf = Centre.Translated(trans);
949 DS.SetXYZ(L.Location().XYZ() - CentreOfSurf.XYZ());
952 error += (DL.XYZ()).CrossMagnitude(DN.XYZ())*levier;
955 // si la line est orthogonale au plan de rotation
957 gp_Ax3 Axis(CentreOfSurf, Dir.Direction(), DS);
958 S = new (Geom_CylindricalSurface)
959 (Axis, L.Distance(CentreOfSurf));
961 myExchUV = Standard_True;
964 // On evalue l'angle du cone
965 Standard_Real Angle = Abs(Dir.Angle(L));
966 if (Angle > M_PI/2) Angle = M_PI -Angle;
967 if (reverse) Angle = -Angle;
972 if (Abs(Abs(Angle) - M_PI/2) > 0.01) {
974 // si les 2 droites ne sont pas orthogonales
975 Standard_Real Radius = CentreOfSurf.Distance(L.Location());
976 gp_Ax3 Axis(CentreOfSurf, Dir.Direction(), DS);
977 S = new (Geom_ConicalSurface)
978 (Axis, Angle, Radius);
979 myExchUV = Standard_True;
983 // On n'as pas conclue, on remet l'erreur a 0.
988 // On reverse le parametre
989 Standard_Real uf, ul;
990 Handle(Geom_Line) CL = new (Geom_Line)(L);
991 uf = CL->ReversedParameter(ULast);
992 ul = CL->ReversedParameter(UFirst);
995 isUReversed = Standard_True;
1004 Section->Transform(Tf2);
1005 gp_Ax1 Axis (Centre, DN);
1006 S = new (Geom_SurfaceOfRevolution)
1008 myExchUV = Standard_True;
1017 if (Ok) { // On trimme la surface
1020 b = isUPeriodic; isUPeriodic = isVPeriodic; isVPeriodic = b;
1022 r = UFirst; UFirst = VFirst; VFirst = r;
1023 r = ULast; ULast = VLast; VLast = r;
1026 if (!isUPeriodic && !isVPeriodic)
1027 mySurface = new (Geom_RectangularTrimmedSurface)
1028 (S, UFirst, ULast, VFirst, VLast);
1029 else if (isUPeriodic) {
1030 if (isVPeriodic) mySurface = S;
1031 else mySurface = new (Geom_RectangularTrimmedSurface)
1032 (S, VFirst, VLast, Standard_False);
1035 mySurface = new (Geom_RectangularTrimmedSurface)
1036 (S,UFirst, ULast, Standard_True);
1039 if (isUPeriodic && !mySurface->IsUPeriodic())
1040 cout<<"Pb de periodicite en U" << endl;
1041 if (isUPeriodic && !mySurface->IsUClosed())
1042 cout<<"Pb de fermeture en U" << endl;
1043 if (isVPeriodic && !mySurface->IsVPeriodic())
1044 cout << "Pb de periodicite en V" << endl;
1045 if (isVPeriodic && !mySurface->IsVClosed())
1046 cout<<"Pb de fermeture en V" << endl;
1054 //===============================================================
1055 // Function : IsDone
1057 //===============================================================
1058 Standard_Boolean GeomFill_Sweep::IsDone() const
1063 //===============================================================
1064 // Function :ErrorOnSurface
1066 //===============================================================
1067 Standard_Real GeomFill_Sweep::ErrorOnSurface() const
1072 //===============================================================
1073 // Function ::ErrorOnRestriction
1075 //===============================================================
1076 void GeomFill_Sweep::ErrorOnRestriction(const Standard_Boolean IsFirst,
1077 Standard_Real& UError,
1078 Standard_Real& VError) const
1080 Standard_Integer ind;
1082 else ind = myCurve2d->Length();
1084 UError = CError->Value(1, ind);
1085 VError = CError->Value(2, ind);
1088 //===============================================================
1089 // Function :ErrorOnTrace
1091 //===============================================================
1092 void GeomFill_Sweep::ErrorOnTrace(const Standard_Integer IndexOfTrace,
1093 Standard_Real& UError,
1094 Standard_Real& VError) const
1096 Standard_Integer ind = IndexOfTrace+1;
1097 if (IndexOfTrace > myLoc->TraceNumber())
1098 Standard_OutOfRange::Raise(" GeomFill_Sweep::ErrorOnTrace");
1100 UError = CError->Value(1, ind);
1101 VError = CError->Value(2, ind);
1104 //===============================================================
1105 // Function :Surface
1107 //===============================================================
1108 Handle(Geom_Surface) GeomFill_Sweep::Surface() const
1113 //===============================================================
1114 // Function ::Restriction
1116 //===============================================================
1117 Handle(Geom2d_Curve) GeomFill_Sweep::Restriction(const Standard_Boolean IsFirst) const
1120 return myCurve2d->Value(1);
1121 return myCurve2d->Value(myCurve2d->Length());
1125 //===============================================================
1128 //===============================================================
1129 Standard_Integer GeomFill_Sweep::NumberOfTrace() const
1131 return myLoc->TraceNumber();
1134 //===============================================================
1137 //===============================================================
1138 Handle(Geom2d_Curve)
1139 GeomFill_Sweep::Trace(const Standard_Integer IndexOfTrace) const
1141 Standard_Integer ind = IndexOfTrace+1;
1142 if (IndexOfTrace > myLoc->TraceNumber())
1143 Standard_OutOfRange::Raise(" GeomFill_Sweep::Trace");
1144 return myCurve2d->Value(ind);