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
9 // under the terms of the GNU Lesser General Public 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>
35 #include <TColgp_Array1OfPnt.hxx>
36 #include <TColgp_Array2OfPnt.hxx>
37 #include <TColgp_HArray2OfPnt.hxx>
38 //#include <GeomLib_Array1OfMat.hxx>
39 #include <TColStd_Array1OfInteger.hxx>
40 #include <TColStd_Array1OfReal.hxx>
41 #include <TColStd_Array2OfReal.hxx>
43 #include <GeomAbs_CurveType.hxx>
44 #include <GeomAdaptor_Curve.hxx>
45 #include <GeomLib.hxx>
47 #include <Geom2d_Line.hxx>
48 #include <Geom2d_BSplineCurve.hxx>
49 #include <Geom2d_TrimmedCurve.hxx>
51 #include <Geom_Circle.hxx>
52 #include <Geom_Line.hxx>
53 #include <Geom_BSplineSurface.hxx>
54 #include <Geom_Plane.hxx>
55 #include <Geom_SurfaceOfLinearExtrusion.hxx>
56 #include <Geom_CylindricalSurface.hxx>
57 #include <Geom_ConicalSurface.hxx>
58 #include <Geom_ToroidalSurface.hxx>
59 #include <Geom_SphericalSurface.hxx>
60 #include <Geom_SurfaceOfRevolution.hxx>
61 #include <Geom_RectangularTrimmedSurface.hxx>
63 #include <Approx_SweepApproximation.hxx>
64 #include <AdvApprox_PrefAndRec.hxx>
65 #include <AdvApprox_ApproxAFunction.hxx>
66 #include <GeomConvert_ApproxSurface.hxx>
68 #include <Precision.hxx>
71 //=======================================================================
72 //class : GeomFill_Sweep_Eval
73 //purpose: The evaluator for curve approximation
74 //=======================================================================
76 class GeomFill_Sweep_Eval : public AdvApprox_EvaluatorFunction
79 GeomFill_Sweep_Eval (GeomFill_LocFunction& theTool)
80 : theAncore(theTool) {}
82 virtual void Evaluate (Standard_Integer *Dimension,
83 Standard_Real StartEnd[2],
84 Standard_Real *Parameter,
85 Standard_Integer *DerivativeRequest,
86 Standard_Real *Result, // [Dimension]
87 Standard_Integer *ErrorCode);
90 GeomFill_LocFunction& theAncore;
93 void GeomFill_Sweep_Eval::Evaluate (Standard_Integer *,/*Dimension*/
94 Standard_Real StartEnd[2],
95 Standard_Real *Parameter,
96 Standard_Integer *DerivativeRequest,
97 Standard_Real *Result,// [Dimension]
98 Standard_Integer *ErrorCode)
100 theAncore.DN (*Parameter,
108 //===============================================================
111 //===============================================================
112 GeomFill_Sweep::GeomFill_Sweep(const Handle(GeomFill_LocationLaw)& Location,
113 const Standard_Boolean WithKpart)
115 done = Standard_False;
120 myForceApproxC1 = Standard_False;
122 myLoc->GetDomain(First, Last);
123 SFirst = SLast = 30.081996;
127 //===============================================================
128 // Function : SetDomain
130 //===============================================================
131 void GeomFill_Sweep::SetDomain(const Standard_Real LocFirst,
132 const Standard_Real LocLast,
133 const Standard_Real SectionFirst,
134 const Standard_Real SectionLast)
138 SFirst = SectionFirst;
142 //===============================================================
143 // Function : SetTolerance
145 //===============================================================
146 void GeomFill_Sweep::SetTolerance(const Standard_Real Tolerance3d,
147 const Standard_Real BoundTolerance,
148 const Standard_Real Tolerance2d,
149 const Standard_Real ToleranceAngular)
152 BoundTol = BoundTolerance;
154 TolAngular = ToleranceAngular;
157 //=======================================================================
158 //Function : SetForceApproxC1
159 //Purpose : Set the flag that indicates attempt to approximate
160 // a C1-continuous surface if a swept surface proved
162 //=======================================================================
163 void GeomFill_Sweep::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
165 myForceApproxC1 = ForceApproxC1;
169 //===============================================================
170 // Function : ExchangeUV
172 //===============================================================
173 Standard_Boolean GeomFill_Sweep::ExchangeUV() const
178 //===============================================================
179 // Function : UReversed
181 //===============================================================
182 Standard_Boolean GeomFill_Sweep::UReversed() const
187 //===============================================================
188 // Function : VReversed
190 //===============================================================
191 Standard_Boolean GeomFill_Sweep::VReversed() const
196 //===============================================================
199 //===============================================================
200 void GeomFill_Sweep::Build(const Handle(GeomFill_SectionLaw)& Section,
201 const GeomFill_ApproxStyle Methode,
202 const GeomAbs_Shape Continuity,
203 const Standard_Integer Degmax,
204 const Standard_Integer Segmax)
207 done = Standard_False;
208 myExchUV = Standard_False;
209 isUReversed = isVReversed = Standard_False;
212 if ((SFirst == SLast) && (SLast == 30.081996)) {
213 mySec->GetDomain(SFirst, SLast);
216 Standard_Boolean isKPart = Standard_False,
217 isProduct = Standard_False;
219 // Traitement des KPart
220 if (myKPart) isKPart = BuildKPart();
222 // Traitement des produits Formelles
223 if ((!isKPart) && (Methode == GeomFill_Location)) {
224 Handle(Geom_BSplineSurface) BS;
225 BS = mySec->BSplineSurface();
228 // isProduct = BuildProduct(Continuity, Degmax, Segmax);
232 if (isKPart || isProduct) {
234 done = Build2d(Continuity, Degmax, Segmax);
238 done = BuildAll(Continuity, Degmax, Segmax);
242 //===============================================================
243 // Function ::Build2d
244 // Purpose :A venir...
245 //===============================================================
246 // Standard_Boolean GeomFill_Sweep::Build2d(const GeomAbs_Shape Continuity,
247 Standard_Boolean GeomFill_Sweep::Build2d(const GeomAbs_Shape ,
248 // const Standard_Integer Degmax,
249 const Standard_Integer ,
250 // const Standard_Integer Segmax)
251 const Standard_Integer )
253 Standard_Boolean Ok = Standard_False;
254 if (myLoc->Nb2dCurves() == 0) {
260 //===============================================================
261 // Function : BuildAll
263 //===============================================================
264 Standard_Boolean GeomFill_Sweep::BuildAll(const GeomAbs_Shape Continuity,
265 const Standard_Integer Degmax,
266 const Standard_Integer Segmax)
268 Standard_Boolean Ok = Standard_False;
269 Standard_Integer nbsegmax = Segmax, nbspan = myLoc->NbIntervals(GeomAbs_C1);
270 if (Segmax < nbspan) nbsegmax = nbspan;
272 Handle(GeomFill_SweepFunction) Func
273 = new (GeomFill_SweepFunction) (mySec, myLoc, First, SFirst,
274 (SLast-SFirst)/(Last-First) );
275 Approx_SweepApproximation Approx( Func );
277 Approx.Perform(First, Last,
278 Tol3d, BoundTol, Tol2d, TolAngular,
279 Continuity, Degmax, Segmax);
281 if (Approx.IsDone()) {
289 Standard_Integer UDegree,VDegree,NbUPoles,
290 NbVPoles,NbUKnots,NbVKnots;
291 Approx.SurfShape(UDegree,VDegree,NbUPoles,
292 NbVPoles,NbUKnots,NbVKnots);
294 TColgp_Array2OfPnt Poles(1,NbUPoles, 1,NbVPoles);
295 TColStd_Array2OfReal Weights(1,NbUPoles, 1,NbVPoles);
296 TColStd_Array1OfReal UKnots(1, NbUKnots),VKnots(1, NbVKnots);
297 TColStd_Array1OfInteger UMults(1, NbUKnots), VMults(1, NbVKnots);
299 Approx.Surface(Poles, Weights,
303 mySurface = new (Geom_BSplineSurface)
307 Approx.UDegree(), Approx.VDegree(),
308 mySec->IsUPeriodic());
309 SError = Approx. MaxErrorOnSurf();
311 if (myForceApproxC1 && !mySurface->IsCNv(1))
313 Standard_Real theTol = 1.e-4;
314 GeomAbs_Shape theUCont = GeomAbs_C1, theVCont = GeomAbs_C1;
315 Standard_Integer degU = 14, degV = 14;
316 Standard_Integer nmax = 16;
317 Standard_Integer thePrec = 1;
319 GeomConvert_ApproxSurface ConvertApprox(mySurface,theTol,theUCont,theVCont,
320 degU,degV,nmax,thePrec);
321 if (ConvertApprox.HasResult())
323 mySurface = ConvertApprox.Surface();
324 myCurve2d = new (TColGeom2d_HArray1OfCurve) (1, 2);
325 CError = new (TColStd_HArray2OfReal) (1,2, 1,2);
327 const Handle(Geom_BSplineSurface)& BSplSurf =
328 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),
532 // Get the last transformation
533 theLoc->D0(aLast, M, VEnd);
535 GTfEnd.SetVectorialPart(M);
536 GTfEnd.SetTranslationPart(VEnd.XYZ());
538 TfEnd.SetValues(GTfEnd(1,1), GTfEnd(1,2), GTfEnd(1,3), GTfEnd(1,4),
539 GTfEnd(2,1), GTfEnd(2,2), GTfEnd(2,3), GTfEnd(2,4),
540 GTfEnd(3,1), GTfEnd(3,2), GTfEnd(3,3), GTfEnd(3,4),
543 Handle(Geom_Surface) aSurf = theSec->BSplineSurface();
549 aSurf->Bounds(Umin, Umax, Vmin, Vmax);
551 // Get and transform the first section
552 Handle(Geom_Curve) FirstSection = theSec->ConstantSection();
553 GeomAdaptor_Curve ACFirst(FirstSection);
555 Standard_Real UFirst = ACFirst.FirstParameter();
556 gp_Lin L = ACFirst.Line();
558 L.Transform(TfBegin);
560 // Get and transform the last section
561 Handle(Geom_Curve) aLastSection = aSurf->VIso(Vmax);
562 Standard_Real aFirstParameter = aLastSection->FirstParameter();
563 gp_Pnt aPntLastSec = aLastSection->Value(aFirstParameter);
565 aPntLastSec.Transform(TfEnd);
567 gp_Pnt aPntFirstSec = ElCLib::Value( UFirst, L );
568 gp_Vec aVecSec( aPntFirstSec, aPntLastSec );
569 gp_Vec aVecSpine = VEnd - VBegin;
571 Standard_Boolean isParallel = aVecSec.IsParallel(aVecSpine, theTol);
575 // Modified by skv - Thu Feb 5 18:05:01 2004 OCC5073 End
577 //===============================================================
578 // Function : BuildKPart
580 //===============================================================
581 Standard_Boolean GeomFill_Sweep::BuildKPart()
583 Standard_Boolean Ok = Standard_False;
584 Standard_Boolean isUPeriodic = Standard_False;
585 Standard_Boolean isVPeriodic = Standard_False;
586 Standard_Boolean IsTrsf = Standard_True;
588 isUPeriodic = mySec->IsUPeriodic();
589 Handle(Geom_Surface) S;
590 GeomAbs_CurveType SectionType;
593 Standard_Real levier, error = 0 ;
594 Standard_Real UFirst=0, VFirst=First, ULast=0, VLast=Last;
595 Standard_Real Tol = Min (Tol3d, BoundTol);
597 // (1) Trajectoire Rectilignes -------------------------
598 if (myLoc->IsTranslation(error)) {
599 // Donne de la translation
607 Tf.SetVectorialPart(M);
608 Tf.SetTranslationPart(V.XYZ());
609 try { // Pas joli mais il n'y as pas d'autre moyens de tester SetValues
611 Tf2.SetValues(Tf(1,1), Tf(1,2), Tf(1,3), Tf(1,4),
612 Tf(2,1), Tf(2,2), Tf(2,3), Tf(2,4),
613 Tf(3,1), Tf(3,2), Tf(3,3), Tf(3,4),
616 catch (Standard_ConstructionError) {
617 IsTrsf = Standard_False;
620 return Standard_False;
623 // (1.1) Cas Extrusion
624 if (mySec->IsConstant(error)) {
625 Handle(Geom_Curve) Section;
626 Section = mySec->ConstantSection();
627 GeomAdaptor_Curve AC(Section);
628 SectionType = AC.GetType();
629 UFirst = AC.FirstParameter();
630 ULast = AC.LastParameter();
632 if ( (SectionType == GeomAbs_Line) && IsTrsf) {
633 // Modified by skv - Thu Feb 5 11:39:06 2004 OCC5073 Begin
634 if (!IsSweepParallelSpine(myLoc, mySec, Tol))
635 return Standard_False;
636 // Modified by skv - Thu Feb 5 11:39:08 2004 OCC5073 End
637 gp_Lin L = AC.Line();
639 DS.SetXYZ(L.Position().Direction().XYZ());
641 levier = Abs(DS.Dot(DP));
642 SError = error + levier * Abs(Last-First);
645 gp_Ax2 AxisOfPlane (L.Location(), DS^DP, DS);
646 S = new (Geom_Plane) (AxisOfPlane);
651 // (1.1.b) Cas Cylindrique
652 if ( (SectionType == GeomAbs_Circle) && IsTrsf) {
653 gp_Circ C = AC.Circle();
656 DS.SetXYZ (C.Position().Direction().XYZ());
658 levier = Abs(DS.CrossMagnitude(DP)) * C.Radius();
659 SError = levier * Abs(Last - First);
662 gp_Ax3 axe (C.Location(), DP, C.Position().XDirection());
663 S = new (Geom_CylindricalSurface)
665 if (C.Position().Direction().
666 IsOpposite(axe.Direction(), 0.1) ) {
668 // L'orientation parametrique est inversee
673 isUReversed = Standard_True;
679 // (1.1.c) C'est bien une extrusion
682 Section->Transform(Tf2);
683 S = new (Geom_SurfaceOfLinearExtrusion)
688 else { // extrusion sur BSpline
695 else if (mySec->IsConicalLaw(error)) {
697 gp_Pnt P1, P2, Centre0, Centre1, Centre2;
699 Handle(Geom_Curve) Section;
700 GeomAdaptor_Curve AC;
702 Standard_Real R1, R2;
705 Section = mySec->CirclSection(SLast);
706 Section->Transform(Tf2);
707 Section->Translate(Last*DP);
710 Centre2 = C.Location();
711 AC.D1(0, P2, dsection);
714 Section = mySec->CirclSection(SFirst);
715 Section->Transform(Tf2);
716 Section->Translate(First*DP);
719 Centre1 = C.Location();
723 Section = mySec->CirclSection(SFirst - First*(SLast-SFirst)/(Last-First));
724 Section->Transform(Tf2);
727 Centre0 = C.Location();
730 gp_Vec N(Centre1, P1);
731 if (N.Magnitude() < 1.e-9) {
732 gp_Vec Bis(Centre2, P2);
735 gp_Vec L(P1, P2), Dir(Centre1,Centre2);
737 Angle = L.Angle(Dir);
738 if ((Angle > 0.01) && (Angle < M_PI/2-0.01)) {
739 if (R2<R1) Angle = -Angle;
741 gp_Ax3 Axis(Centre0, Dir, N);
742 S = new (Geom_ConicalSurface)
743 (Axis, Angle, C.Radius());
744 // Calcul du glissement parametrique
745 VFirst = First / Cos(Angle);
746 VLast = Last / Cos(Angle);
749 UFirst = AC.FirstParameter();
750 ULast = AC.LastParameter();
753 S->VIso(VLast)->D1(0, pbis, diso);
754 if (diso.Magnitude()>1.e-9 && dsection.Magnitude()>1.e-9)
755 isUReversed = diso.IsOpposite(dsection, 0.1);
758 // L'orientation parametrique est inversee
771 // (2) Trajectoire Circulaire
772 if (myLoc->IsRotation(error)) {
773 if (mySec->IsConstant(error)) {
776 isVPeriodic = (Abs(Last-First -2*M_PI) < 1.e-15);
777 Standard_Real RotRadius;
779 myLoc->D0(0.1, M, DS);
781 myLoc->Rotation(Centre);
784 DS.SetXYZ(V.XYZ() - Centre.XYZ());
785 RotRadius = DS.Magnitude();
786 if (RotRadius > 1.e-15) DS.Normalize();
787 else return Standard_False; // Pas de KPart, rotation degeneree
795 Tf.SetVectorialPart(M);
796 Tf.SetTranslationPart(V.XYZ());
797 // try { // Pas joli mais il n'y as pas d'autre moyens de tester SetValues
799 Tf2.SetValues(Tf(1,1), Tf(1,2), Tf(1,3), Tf(1,4),
800 Tf(2,1), Tf(2,2), Tf(2,3), Tf(2,4),
801 Tf(3,1), Tf(3,2), Tf(3,3), Tf(3,4),
804 // catch (Standard_ConstructionError) {
805 // IsTrsf = Standard_False;
808 Handle(Geom_Curve) Section;
809 Section = mySec->ConstantSection();
810 GeomAdaptor_Curve AC(Section);
811 SectionType = AC.GetType();
812 UFirst = AC.FirstParameter();
813 ULast = AC.LastParameter();
815 // (2.1) Tore/Sphere ?
816 if ((SectionType == GeomAbs_Circle) && IsTrsf) {
817 gp_Circ C = AC.Circle();
818 Standard_Real Radius;
819 Standard_Boolean IsGoodSide = Standard_True;;
822 // On calcul le centre eventuel
823 DC.SetXYZ(C.Location().XYZ() - Centre.XYZ());
824 Centre.ChangeCoord() += (DC.Dot(DN))*DN.XYZ();
825 DC.SetXYZ(C.Location().XYZ() - Centre.XYZ());
826 Radius = DC.Magnitude(); //grand Rayon du tore
827 if ((Radius > Tol) && (DC.Dot(DS) < 0)) IsGoodSide = Standard_False;
828 if (Radius < Tol/100) DC = DS; // Pour definir le tore
830 // On verifie d'abord que le plan de la section est // a
833 NC.SetXYZ (C.Position().Direction().XYZ());
835 error = Abs(NC.Dot(DN));
836 // Puis on evalue l'erreur commise sur la section,
837 // en pivotant son plan ( pour contenir l'axe de rotation)
838 error += Abs(NC.Dot(DS));
842 error += Radius + Abs(RotRadius - C.Radius())/2;
845 Standard_Real f = UFirst , l = ULast;
847 Centre.BaryCenter(1.0, C.Location(), 1.0);
848 gp_Ax3 AxisOfSphere(Centre, DN, DS);
849 S = new (Geom_SphericalSurface)
850 (AxisOfSphere, (RotRadius + C.Radius())/2 );
851 // Pour les spheres on ne peut pas controler le parametre
852 // V (donc U car myExchUV = Standard_True)
853 // Il faut donc modifier UFirst, ULast...
854 if (C.Position().Direction().
855 IsOpposite(AxisOfSphere.YDirection(), 0.1) ) {
856 // L'orientation parametrique est inversee
859 isUReversed = Standard_True;
861 // On calcul le "glissement" parametrique.
863 rot = C.Position().XDirection().AngleWithRef
864 (AxisOfSphere.XDirection(), AxisOfSphere.YDirection());
868 if ( (f >= -M_PI/2) && (l <= M_PI/2)) {
870 myExchUV = Standard_True;
874 else { // On restaure ce qu'il faut
875 isUReversed = Standard_False;
878 else if (IsGoodSide) {
880 gp_Ax3 AxisOfTore(Centre, DN, DC);
881 S = new (Geom_ToroidalSurface) (AxisOfTore,
882 Radius , C.Radius());
884 // Pour les tores on ne peut pas controler le parametre
885 // V (donc U car myExchUV = Standard_True)
886 // Il faut donc modifier UFirst, ULast...
887 Handle(Geom_Circle) Iso;
888 Iso = Handle(Geom_Circle)::DownCast(S->UIso(0.));
890 axeiso = Iso->Circ().Position();
892 if (C.Position().Direction().
893 IsOpposite(axeiso.Direction(), 0.1) ) {
895 // L'orientation parametrique est inversee
900 isUReversed = Standard_True;
902 // On calcul le "glissement" parametrique.
904 rot = C.Position().XDirection().AngleWithRef
905 (axeiso.XDirection(), axeiso.Direction());
909 myExchUV = Standard_True;
910 // Attention l'arete de couture dans le cas periodique
911 // n'est peut etre pas a la bonne place...
912 if (isUPeriodic && Abs(UFirst)>Precision::PConfusion())
913 isUPeriodic = Standard_False; //Pour trimmer la surface...
921 // (2.2) Cone / Cylindre
922 if ((SectionType == GeomAbs_Line) && IsTrsf) {
923 gp_Lin L = AC.Line();
926 DL.SetXYZ(L.Direction().XYZ());
927 levier = Max(Abs(AC.FirstParameter()), AC.LastParameter());
928 // si la line est ortogonale au cercle de rotation
929 SError = error + levier * Abs(DL.Dot(DP));
931 Standard_Boolean reverse;
932 gp_Lin Dir(Centre, DN);
935 reverse = (aux < 0); // On choisit ici le sens de parametrisation
937 // Calcul du centre du vecteur supportant la "XDirection"
939 gp_Vec O1O2(Centre, L.Location()), trans;
941 trans *= DN.Dot(O1O2);
942 CentreOfSurf = Centre.Translated(trans);
943 DS.SetXYZ(L.Location().XYZ() - CentreOfSurf.XYZ());
946 error += (DL.XYZ()).CrossMagnitude(DN.XYZ())*levier;
949 // si la line est orthogonale au plan de rotation
951 gp_Ax3 Axis(CentreOfSurf, Dir.Direction(), DS);
952 S = new (Geom_CylindricalSurface)
953 (Axis, L.Distance(CentreOfSurf));
955 myExchUV = Standard_True;
958 // On evalue l'angle du cone
959 Standard_Real Angle = Abs(Dir.Angle(L));
960 if (Angle > M_PI/2) Angle = M_PI -Angle;
961 if (reverse) Angle = -Angle;
966 if (Abs(Abs(Angle) - M_PI/2) > 0.01) {
968 // si les 2 droites ne sont pas orthogonales
969 Standard_Real Radius = CentreOfSurf.Distance(L.Location());
970 gp_Ax3 Axis(CentreOfSurf, Dir.Direction(), DS);
971 S = new (Geom_ConicalSurface)
972 (Axis, Angle, Radius);
973 myExchUV = Standard_True;
977 // On n'as pas conclue, on remet l'erreur a 0.
982 // On reverse le parametre
983 Standard_Real uf, ul;
984 Handle(Geom_Line) CL = new (Geom_Line)(L);
985 uf = CL->ReversedParameter(ULast);
986 ul = CL->ReversedParameter(UFirst);
989 isUReversed = Standard_True;
998 Section->Transform(Tf2);
999 gp_Ax1 Axis (Centre, DN);
1000 S = new (Geom_SurfaceOfRevolution)
1002 myExchUV = Standard_True;
1011 if (Ok) { // On trimme la surface
1014 b = isUPeriodic; isUPeriodic = isVPeriodic; isVPeriodic = b;
1016 r = UFirst; UFirst = VFirst; VFirst = r;
1017 r = ULast; ULast = VLast; VLast = r;
1020 if (!isUPeriodic && !isVPeriodic)
1021 mySurface = new (Geom_RectangularTrimmedSurface)
1022 (S, UFirst, ULast, VFirst, VLast);
1023 else if (isUPeriodic) {
1024 if (isVPeriodic) mySurface = S;
1025 else mySurface = new (Geom_RectangularTrimmedSurface)
1026 (S, VFirst, VLast, Standard_False);
1029 mySurface = new (Geom_RectangularTrimmedSurface)
1030 (S,UFirst, ULast, Standard_True);
1033 if (isUPeriodic && !mySurface->IsUPeriodic())
1034 cout<<"Pb de periodicite en U" << endl;
1035 if (isUPeriodic && !mySurface->IsUClosed())
1036 cout<<"Pb de fermeture en U" << endl;
1037 if (isVPeriodic && !mySurface->IsVPeriodic())
1038 cout << "Pb de periodicite en V" << endl;
1039 if (isVPeriodic && !mySurface->IsVClosed())
1040 cout<<"Pb de fermeture en V" << endl;
1048 //===============================================================
1049 // Function : IsDone
1051 //===============================================================
1052 Standard_Boolean GeomFill_Sweep::IsDone() const
1057 //===============================================================
1058 // Function :ErrorOnSurface
1060 //===============================================================
1061 Standard_Real GeomFill_Sweep::ErrorOnSurface() const
1066 //===============================================================
1067 // Function ::ErrorOnRestriction
1069 //===============================================================
1070 void GeomFill_Sweep::ErrorOnRestriction(const Standard_Boolean IsFirst,
1071 Standard_Real& UError,
1072 Standard_Real& VError) const
1074 Standard_Integer ind;
1076 else ind = myCurve2d->Length();
1078 UError = CError->Value(1, ind);
1079 VError = CError->Value(2, ind);
1082 //===============================================================
1083 // Function :ErrorOnTrace
1085 //===============================================================
1086 void GeomFill_Sweep::ErrorOnTrace(const Standard_Integer IndexOfTrace,
1087 Standard_Real& UError,
1088 Standard_Real& VError) const
1090 Standard_Integer ind = IndexOfTrace+1;
1091 if (IndexOfTrace > myLoc->TraceNumber())
1092 Standard_OutOfRange::Raise(" GeomFill_Sweep::ErrorOnTrace");
1094 UError = CError->Value(1, ind);
1095 VError = CError->Value(2, ind);
1098 //===============================================================
1099 // Function :Surface
1101 //===============================================================
1102 Handle(Geom_Surface) GeomFill_Sweep::Surface() const
1107 //===============================================================
1108 // Function ::Restriction
1110 //===============================================================
1111 Handle(Geom2d_Curve) GeomFill_Sweep::Restriction(const Standard_Boolean IsFirst) const
1114 return myCurve2d->Value(1);
1115 return myCurve2d->Value(myCurve2d->Length());
1119 //===============================================================
1122 //===============================================================
1123 Standard_Integer GeomFill_Sweep::NumberOfTrace() const
1125 return myLoc->TraceNumber();
1128 //===============================================================
1131 //===============================================================
1132 Handle(Geom2d_Curve)
1133 GeomFill_Sweep::Trace(const Standard_Integer IndexOfTrace) const
1135 Standard_Integer ind = IndexOfTrace+1;
1136 if (IndexOfTrace > myLoc->TraceNumber())
1137 Standard_OutOfRange::Raise(" GeomFill_Sweep::Trace");
1138 return myCurve2d->Value(ind);