1 // Created on: 1994-04-13
2 // Created by: Joelle CHAUVET
3 // Copyright (c) 1994-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 22/09/1997 by PMN : Refonte du a l'introduction de F(t) dans
18 // le cas des 2 lignes guides
19 // Modified: Mon Jan 18 11:06:46 1999
20 // dans Init(Path, Nsections) :
21 // les parametres des sections doivent etre strict. croissants
22 // dans Init(Path, FirstSect, LastSect) :
23 // il faut placer les 2 sections au debut de la trajectoire
27 #include <GeomFill_Pipe.ixx>
29 #include <GeomFill_Line.hxx>
30 #include <GeomFill_SweepSectionGenerator.hxx>
31 #include <GeomFill_AppSweep.hxx>
32 #include <GeomFill_Profiler.hxx>
33 #include <GeomFill_CircularBlendFunc.hxx>
34 #include <GeomFill_UniformSection.hxx>
35 #include <GeomFill_Fixed.hxx>
36 #include <GeomFill_Frenet.hxx>
37 #include <GeomFill_CorrectedFrenet.hxx>
38 #include <GeomFill_ConstantBiNormal.hxx>
39 #include <GeomFill_CurveAndTrihedron.hxx>
40 #include <GeomFill_SectionPlacement.hxx>
41 #include <GeomFill_Sweep.hxx>
42 #include <GeomFill_NSections.hxx>
44 #include <GeomFill_GuideTrihedronAC.hxx>
46 #include <GeomFill_GuideTrihedronPlan.hxx>
47 #include <GeomFill_LocationGuide.hxx>
50 #include <Geom_BSplineCurve.hxx>
51 #include <Geom_Circle.hxx>
52 #include <Geom_Line.hxx>
53 #include <Geom_TrimmedCurve.hxx>
54 #include <Geom_BSplineSurface.hxx>
55 #include <Geom_ToroidalSurface.hxx>
56 #include <Geom_CylindricalSurface.hxx>
57 #include <Geom_SphericalSurface.hxx>
58 #include <Geom_Plane.hxx>
59 #include <Geom_ConicalSurface.hxx>
60 #include <Geom_RectangularTrimmedSurface.hxx>
61 #include <Geom_SurfaceOfLinearExtrusion.hxx>
63 #include <GeomAbs_SurfaceType.hxx>
64 #include <GeomAdaptor_Curve.hxx>
65 #include <GeomAdaptor_HCurve.hxx>
66 #include <GeomLProp_CLProps.hxx>
68 #include <Approx_SweepApproximation.hxx>
70 #include <gp_Torus.hxx>
74 #include <Precision.hxx>
77 #include <GeomLib.hxx>
79 #include <GeomFill_Darboux.hxx>
80 #include <Adaptor3d_CurveOnSurface.hxx>
81 #include <Adaptor3d_HCurveOnSurface.hxx>
82 #include <Geom2dAdaptor_HCurve.hxx>
83 #include <GeomAdaptor_HSurface.hxx>
84 #include <TColgp_Array1OfPnt.hxx>
85 #include <TColGeom_SequenceOfCurve.hxx>
88 static Standard_Boolean Affich = Standard_False;
89 static Standard_Integer NbSections = 0;
93 #include <DrawTrSurf.hxx>
96 static Standard_Boolean CheckSense(const TColGeom_SequenceOfCurve& Seq1,
97 TColGeom_SequenceOfCurve& Seq2)
100 Standard_Boolean no_sing = Standard_True;
103 Handle(Geom_Curve) C1 = Seq1.Value(1);
104 Standard_Real f = C1->FirstParameter(), l = C1->LastParameter();
105 Standard_Integer iP, NP = 21;
106 TColgp_Array1OfPnt Tab(1,NP);
107 Standard_Real u = f, h = Abs(f-l) / 20.;
108 for (iP=1;iP<=NP;iP++) {
111 if ((u-f)*(u-l)>0.0) u = l;
115 Standard_Boolean sing;
116 GeomLib::AxeOfInertia(Tab,AxeRef,sing);
118 // si la section est une droite, ca ne marche pas
119 if (sing) no_sing = Standard_False;
121 Pos = AxeRef.Location();
122 Standard_Real alpha1, alpha2, alpha3;
128 alpha1 = gp_Vec(Pos,P1).AngleWithRef(gp_Vec(Pos,P2),AxeRef.Direction());
132 alpha2 = gp_Vec(Pos,P1).AngleWithRef(gp_Vec(Pos,P2),AxeRef.Direction());
136 alpha3 = gp_Vec(Pos,P1).AngleWithRef(gp_Vec(Pos,P2),AxeRef.Direction());
139 for (Standard_Integer iseq=2; iseq<=Seq1.Length(); iseq++) {
140 // discretisation de C2
141 Handle(Geom_Curve) C2 = Seq1.Value(iseq);
142 f = C2->FirstParameter();
143 l = C2->LastParameter();
145 for (iP=1;iP<=NP;iP++) {
148 if ((u-f)*(u-l)>0.0) u = l;
150 GeomLib::AxeOfInertia(Tab,Axe,sing);
152 // si la section est une droite, ca ne marche pas
153 if (sing) no_sing = Standard_False;
155 Pos = Axe.Location();
156 Standard_Real beta1, beta2, beta3;
161 beta1 = gp_Vec(Pos,P1).AngleWithRef(gp_Vec(Pos,P2),AxeRef.Direction());
165 beta2 = gp_Vec(Pos,P1).AngleWithRef(gp_Vec(Pos,P2),AxeRef.Direction());
169 beta3 = gp_Vec(Pos,P1).AngleWithRef(gp_Vec(Pos,P2),AxeRef.Direction());
172 Standard_Boolean ok = Standard_True,
173 pasnul1 = ( Abs(alpha1) > Precision::Confusion() )
174 && ( Abs(beta1) > Precision::Confusion() ),
175 pasnul2 = ( Abs(alpha2) > Precision::Confusion() )
176 && ( Abs(beta2) > Precision::Confusion() ),
177 pasnul3 = ( Abs(alpha3) > Precision::Confusion() )
178 && ( Abs(beta3) > Precision::Confusion() );
179 if (pasnul1 && pasnul2 && pasnul3) {
180 if (alpha1*beta1>0.0)
181 ok = (alpha2*beta2>0.0) || (alpha3*beta3>0.0);
183 ok = (alpha2*beta2>0.0) && (alpha3*beta3>0.0);
185 else if (pasnul1 && pasnul2 && !pasnul3)
186 ok = (alpha1*beta1>0.0) || (alpha2*beta2>0.0);
187 else if (pasnul1 && !pasnul2 && pasnul3)
188 ok = (alpha1*beta1>0.0) || (alpha3*beta3>0.0);
189 else if (!pasnul1 && pasnul2 && pasnul3)
190 ok = (alpha2*beta2>0.0) || (alpha3*beta3>0.0);
192 ok = (alpha1*beta1>0.0);
194 ok = (alpha2*beta2>0.0);
196 ok = (alpha3*beta3>0.0);
198 if (no_sing && !ok) {
207 //=======================================================================
208 //function : GeomFill_Pipe
209 //purpose : constructor with no parameters.
210 //=======================================================================
212 GeomFill_Pipe::GeomFill_Pipe() : myExchUV(Standard_False),myKPart(Standard_False)
218 //=======================================================================
219 //function : GeomFill_Pipe
221 //=======================================================================
223 GeomFill_Pipe::GeomFill_Pipe(const Handle(Geom_Curve)& Path,
224 const Standard_Real Radius)
225 : myExchUV(Standard_False),myKPart(Standard_False)
231 //=======================================================================
232 //function : GeomFill_Pipe
234 //=======================================================================
236 GeomFill_Pipe::GeomFill_Pipe(const Handle(Geom_Curve)& Path,
237 const Handle(Geom_Curve)& FirstSect,
238 const GeomFill_Trihedron Option)
239 : myExchUV(Standard_False),myKPart(Standard_False)
242 Init(Path, FirstSect, Option);
245 //=======================================================================
246 //function : GeomFill_Pipe
248 //=======================================================================
250 GeomFill_Pipe::GeomFill_Pipe(const Handle(Geom2d_Curve)& Path,
251 const Handle(Geom_Surface)& Support,
252 const Handle(Geom_Curve)& FirstSect)
253 : myExchUV(Standard_False),myKPart(Standard_False)
256 Init(Path, Support, FirstSect);
259 //=======================================================================
260 //function : GeomFill_Pipe
262 //=======================================================================
264 GeomFill_Pipe::GeomFill_Pipe(const Handle(Geom_Curve)& Path,
265 const Handle(Geom_Curve)& FirstSect,
266 const Handle(Geom_Curve)& LastSect)
267 : myExchUV(Standard_False),myKPart(Standard_False)
270 Init(Path, FirstSect, LastSect);
274 //=======================================================================
275 //function : GeomFill_Pipe
277 //=======================================================================
279 GeomFill_Pipe::GeomFill_Pipe(const Handle(Geom_Curve)& Path,
280 const TColGeom_SequenceOfCurve& NSections)
281 : myExchUV(Standard_False),myKPart(Standard_False)
284 Init(Path, NSections);
287 //=======================================================================
288 //function : GeomFill_Pipe
290 //=======================================================================
292 GeomFill_Pipe::GeomFill_Pipe(const Handle(Geom_Curve)& Path,
293 const Handle(Geom_Curve)& Curve1,
294 const gp_Dir& Direction)
295 : myExchUV(Standard_False), myKPart(Standard_False)
297 Init(Path, Curve1, Direction);
299 //=======================================================================
300 //function : GeomFill_Pipe
302 //=======================================================================
304 GeomFill_Pipe::GeomFill_Pipe(const Handle(Geom_Curve)& Path,
305 const Handle(Geom_Curve)& Curve1,
306 const Handle(Geom_Curve)& Curve2,
307 const Standard_Real Radius)
308 : myExchUV(Standard_False),myKPart(Standard_False)
311 Handle(GeomAdaptor_HCurve) AdpPath =
312 new GeomAdaptor_HCurve( Path);
313 Handle(GeomAdaptor_HCurve) AdpCurve1 =
314 new GeomAdaptor_HCurve( Curve1);
315 Handle(GeomAdaptor_HCurve) AdpCurve2 =
316 new GeomAdaptor_HCurve( Curve2);
318 Init(AdpPath, AdpCurve1, AdpCurve2, Radius);
322 //=======================================================================
323 //function : GeomFill_Pipe
325 //=======================================================================
327 GeomFill_Pipe::GeomFill_Pipe(const Handle(Adaptor3d_HCurve)& Path,
328 const Handle(Adaptor3d_HCurve)& Curve1,
329 const Handle(Adaptor3d_HCurve)& Curve2,
330 const Standard_Real Radius)
331 : myExchUV(Standard_False),myKPart(Standard_False)
334 Init(Path,Curve1,Curve2,Radius);
338 //=======================================================================
341 //=======================================================================
342 //function : GeomFill_Pipe
343 //purpose : pipe avec courbe guide
344 //=======================================================================
346 GeomFill_Pipe::GeomFill_Pipe(const Handle(Geom_Curve)& Path,
347 const Handle(Adaptor3d_HCurve)& Guide,
348 const Handle(Geom_Curve)& FirstSect,
349 const Standard_Boolean byACR,
350 const Standard_Boolean rotat)
351 : myExchUV(Standard_False),myKPart(Standard_False)
352 // Path : trajectoire
353 // Guide : courbe guide
354 // FirstSect : section
355 // NbPt : nb de points pour le calcul du triedre
358 Init(Path, Guide, FirstSect, byACR, rotat);
363 //=======================================================================
365 //purpose : pipe avec courbe guide
366 //=======================================================================
368 void GeomFill_Pipe::Init(const Handle(Geom_Curve)& Path,
369 const Handle(Adaptor3d_HCurve)& Guide,
370 const Handle(Geom_Curve)& FirstSect,
371 const Standard_Boolean byACR,
372 const Standard_Boolean rotat)
373 // Path : trajectoire
374 // Guide : courbe guide
375 // FirstSect : section
376 // rotat : vrai si on veu la rotation false sinon
377 // triedre : AC pour absc. curv. ou P pour plan ortho
380 myAdpPath = new (GeomAdaptor_HCurve)
381 (Handle(Geom_Curve)::DownCast(Path->Copy()));
383 Handle (GeomFill_TrihedronWithGuide) TLaw;
387 TLaw = new (GeomFill_GuideTrihedronAC)(Guide);
388 TLaw->SetCurve(myAdpPath);
391 TLaw = new (GeomFill_GuideTrihedronPlan)(Guide);
392 TLaw->SetCurve(myAdpPath);
396 // loi de positionnement
397 Handle(GeomFill_LocationGuide) TheLoc =
398 new (GeomFill_LocationGuide) (TLaw);
399 TheLoc->SetCurve(myAdpPath);
401 GeomFill_SectionPlacement Place(TheLoc, FirstSect);
402 Place.Perform(Precision::Confusion());
405 mySec = new (GeomFill_UniformSection) (Place.Section(Standard_False),
406 myAdpPath->FirstParameter(),
407 myAdpPath->LastParameter());
411 char* Temp = "TheSect" ;
412 DrawTrSurf::Set(Temp, FirstSect );
413 // DrawTrSurf::Set("TheSect", FirstSect );
417 if (rotat) TheLoc->Set(mySec,rotat,
418 myAdpPath->FirstParameter(),
419 myAdpPath->LastParameter(),
425 //=======================================================================
428 //=======================================================================
430 void GeomFill_Pipe::Init()
435 myKPart = Standard_True;
436 myPolynomial = Standard_False;
438 myAdpFirstSect.Nullify();
439 myAdpLastSect.Nullify();
443 //=======================================================================
446 //=======================================================================
448 void GeomFill_Pipe::Init(const Handle(Geom_Curve)& Path,
449 const Standard_Real Radius)
457 myAdpPath = new (GeomAdaptor_HCurve) (Path);
458 Handle(Geom_Circle) C = new (Geom_Circle) (gp::XOY(), Radius);
459 C->Rotate(gp::OZ(),M_PI/2.);
461 mySec = new (GeomFill_UniformSection) (C, Path->FirstParameter(),
462 Path->LastParameter());
463 Handle (GeomFill_CorrectedFrenet)TLaw = new (GeomFill_CorrectedFrenet) ();
464 myLoc = new (GeomFill_CurveAndTrihedron) (TLaw);
465 myLoc->SetCurve(myAdpPath);
469 char* Temp = "TheSect" ;
470 DrawTrSurf::Set(Temp, C);
471 // DrawTrSurf::Set("TheSect", C);
477 //=======================================================================
480 //=======================================================================
482 void GeomFill_Pipe::Init(const Handle(Geom_Curve)& Path,
483 const Handle(Geom_Curve)& FirstSect,
484 const GeomFill_Trihedron Option)
486 Handle(Geom_Curve) Sect;
487 Handle(GeomFill_TrihedronLaw) TLaw;
488 myAdpPath = new (GeomAdaptor_HCurve)
489 (Handle(Geom_Curve)::DownCast(Path->Copy()));
490 Standard_Real param = Path->FirstParameter();
492 // Construction de la loi de triedre
494 case GeomFill_IsCorrectedFrenet :
496 TLaw = new (GeomFill_CorrectedFrenet) ();
500 case GeomFill_IsDarboux :
503 cout << "Option Darboux: non realisable" << endl;
506 case GeomFill_IsFrenet :
508 TLaw = new (GeomFill_Frenet) ();
512 case GeomFill_IsFixed :
514 Standard_Real Eps = 1.e-9;
515 gp_Vec V1(0,0,1), V2(0,1,0);
517 GeomLProp_CLProps CP(Path, param, 2, Eps);
518 if (CP.IsTangentDefined()) {
522 if (CP.Curvature() > Eps) {
528 gp_Pnt P0(0., 0., 0.);
530 D = Axe.XDirection ();
535 TLaw = new (GeomFill_Fixed) (V1, V2);
539 case GeomFill_IsConstantNormal :
541 TLaw = new (GeomFill_Frenet) ();
542 myLoc = new (GeomFill_CurveAndTrihedron) (TLaw);
543 myLoc->SetCurve(myAdpPath);
544 GeomFill_SectionPlacement Place(myLoc, FirstSect);
545 Place.Perform(Precision::Confusion());
546 Standard_Real ponsec = Place.ParameterOnSection();
548 Standard_Real Eps = 1.e-9;
551 GeomLProp_CLProps CP(FirstSect, ponsec, 2, Eps);
552 if (CP.IsTangentDefined()) {
554 if (CP.Curvature() > Eps) {
560 gp_Pnt P0(0., 0., 0.);
562 D = Axe.XDirection ();
567 TLaw = new (GeomFill_ConstantBiNormal) (V);
573 Standard_ConstructionError::Raise
574 ("GeomFill::Init : Unknown Option");
578 if (!TLaw.IsNull()) {
579 myLoc = new (GeomFill_CurveAndTrihedron) (TLaw);
580 myLoc->SetCurve(myAdpPath);
581 GeomFill_SectionPlacement Place(myLoc, FirstSect);
582 Place.Perform(Precision::Confusion());
583 param = Place.ParameterOnPath();
584 Sect = Place.Section(Standard_False);
588 char* Temp = "TheSect" ;
589 DrawTrSurf::Set(Temp,Sect);
590 // DrawTrSurf::Set("TheSect",Sect);
594 mySec = new (GeomFill_UniformSection) (Sect,
595 Path->FirstParameter(),
596 Path->LastParameter());
600 //=======================================================================
602 //purpose : sweep using Darboux's trihedron
603 //=======================================================================
605 void GeomFill_Pipe::Init(const Handle(Geom2d_Curve)& Path,
606 const Handle(Geom_Surface)& Support,
607 const Handle(Geom_Curve)& FirstSect)
609 Handle(Geom_Curve) Sect;
610 Handle(GeomFill_TrihedronLaw) TLaw = new (GeomFill_Darboux)();
612 new Adaptor3d_HCurveOnSurface(Adaptor3d_CurveOnSurface(
613 new Geom2dAdaptor_HCurve(Path),
614 new GeomAdaptor_HSurface(Support)));
616 myLoc = new (GeomFill_CurveAndTrihedron) (TLaw);
617 myLoc->SetCurve(myAdpPath);
618 GeomFill_SectionPlacement Place(myLoc, FirstSect);
619 Place.Perform(myAdpPath, Precision::Confusion());
620 Sect = Place.Section(Standard_False);
624 char* temp = "TheSect" ;
625 DrawTrSurf::Set(temp,Sect);
626 // DrawTrSurf::Set("TheSect",Sect);
630 mySec = new (GeomFill_UniformSection) (Sect,
631 myAdpPath->FirstParameter(),
632 myAdpPath->LastParameter());
635 //=======================================================================
638 //=======================================================================
640 void GeomFill_Pipe::Init(const Handle(Geom_Curve)& Path,
641 const Handle(Geom_Curve)& FirstSect,
642 const gp_Dir& Direction)
646 Handle(Geom_Curve) Sect;
647 myAdpPath = new (GeomAdaptor_HCurve)
648 (Handle(Geom_Curve)::DownCast(Path->Copy()));
650 V.SetXYZ(Direction.XYZ());
651 Handle (GeomFill_ConstantBiNormal) TLaw =
652 new (GeomFill_ConstantBiNormal) (V);
654 myLoc = new (GeomFill_CurveAndTrihedron) (TLaw);
655 myLoc->SetCurve(myAdpPath);
656 GeomFill_SectionPlacement Place(myLoc, FirstSect);
657 Place.Perform(Precision::Confusion());
658 Sect = Place.Section(Standard_False);
662 char* temp = "TheSect" ;
663 DrawTrSurf::Set(temp,Sect);
664 // DrawTrSurf::Set("TheSect",Sect);
667 mySec = new (GeomFill_UniformSection) (Sect,
668 Path->FirstParameter(),
669 Path->LastParameter());
672 //=======================================================================
675 //=======================================================================
677 void GeomFill_Pipe::Init(const Handle(Geom_Curve)& Path,
678 const TColGeom_SequenceOfCurve& NSections)
684 Handle(GeomFill_TrihedronLaw) TLaw;
685 TLaw = new (GeomFill_CorrectedFrenet) ();
686 myAdpPath = new (GeomAdaptor_HCurve)
687 (Handle(Geom_Curve)::DownCast(Path->Copy()));
688 if (!TLaw.IsNull()) {
689 myLoc = new (GeomFill_CurveAndTrihedron) (TLaw);
690 myLoc->SetCurve(myAdpPath);
691 TColGeom_SequenceOfCurve SeqC;
692 TColStd_SequenceOfReal SeqP;
696 for ( i = 1; i<=NSections.Length(); i++) {
697 GeomFill_SectionPlacement Place(myLoc, NSections(i));
698 Place.Perform(Precision::Confusion());
699 SeqP.Append(Place.ParameterOnPath());
700 SeqC.Append(Place.Section(Standard_False));
703 // verification des orientations
704 TColGeom_SequenceOfCurve NewSeq;
705 if (CheckSense(SeqC,NewSeq)) SeqC = NewSeq;
707 // verification des parametres
708 Standard_Boolean play_again = Standard_True;
710 play_again = Standard_False;
711 for (i = 1; i<=NSections.Length(); i++) {
712 for (Standard_Integer j = i; j<=NSections.Length(); j++) {
713 if (SeqP.Value(i)>SeqP.Value(j)) {
716 play_again = Standard_True;
721 for ( i = 1; i<NSections.Length(); i++) {
722 if ( Abs(SeqP.Value(i+1)-SeqP.Value(i)) < Precision::PConfusion()) {
723 Standard_ConstructionError::Raise
724 ("GeomFill_Pipe::Init with NSections : invalid parameters");
728 // creation de la NSections
729 Standard_Real first = Path->FirstParameter(),
730 last = Path->LastParameter();
731 Standard_Real deb,fin;
732 deb = SeqC.First()->FirstParameter();
733 fin = SeqC.First()->LastParameter();
734 mySec = new (GeomFill_NSections) (SeqC,SeqP,deb,fin,first,last);
739 //=======================================================================
742 //=======================================================================
744 void GeomFill_Pipe::Init(const Handle(Geom_Curve)& Path,
745 const Handle(Geom_Curve)& FirstSect,
746 const Handle(Geom_Curve)& LastSect)
751 Standard_Real first = Path->FirstParameter(),
752 last = Path->LastParameter();
753 Handle(GeomFill_TrihedronLaw) TLaw;
754 TLaw = new (GeomFill_CorrectedFrenet) ();
755 myAdpPath = new (GeomAdaptor_HCurve)
756 (Handle(Geom_Curve)::DownCast(Path->Copy()));
758 if (!TLaw.IsNull()) {
759 myLoc = new (GeomFill_CurveAndTrihedron) (TLaw);
760 myLoc->SetCurve(myAdpPath);
761 TColGeom_SequenceOfCurve SeqC;
762 TColStd_SequenceOfReal SeqP;
765 // sequence des sections
766 GeomFill_SectionPlacement Pl1(myLoc, FirstSect);
767 Pl1.Perform(first,Precision::Confusion());
768 SeqC.Append(Pl1.Section(Standard_False));
769 GeomFill_SectionPlacement Pl2(myLoc, LastSect);
770 Pl2.Perform(first,Precision::Confusion());
771 SeqC.Append(Pl2.Section(Standard_False));
772 // sequence des parametres associes
776 // verification de l'orientation
777 TColGeom_SequenceOfCurve NewSeq;
778 if (CheckSense(SeqC,NewSeq)) SeqC = NewSeq;
780 // creation de la NSections
781 Standard_Real deb,fin;
782 deb = SeqC.First()->FirstParameter();
783 fin = SeqC.First()->LastParameter();
784 mySec = new (GeomFill_NSections) (SeqC,SeqP,deb,fin,first,last);
788 //=======================================================================
791 //=======================================================================
793 void GeomFill_Pipe::Init(const Handle(Adaptor3d_HCurve)& Path,
794 const Handle(Adaptor3d_HCurve)& Curve1,
795 const Handle(Adaptor3d_HCurve)& Curve2,
796 const Standard_Real Radius)
802 myAdpFirstSect = Curve1;
803 myAdpLastSect = Curve2;
806 //=======================================================================
809 //=======================================================================
811 void GeomFill_Pipe::Perform(const Standard_Boolean WithParameters,
812 const Standard_Boolean Polynomial)
815 if ( (! myLoc.IsNull()) && (! mySec.IsNull()) ) {
816 Perform(1.e-4, Polynomial);
820 myPolynomial = Polynomial;
821 // on traite la cas tuyau sur arete Type = 4
823 ApproxSurf(WithParameters);
826 if ( !KPartT4() ) ApproxSurf(WithParameters);
830 //=======================================================================
833 //=======================================================================
834 void GeomFill_Pipe::Perform(const Standard_Real Tol,
835 const Standard_Boolean Polynomial,
836 const GeomAbs_Shape Conti,
837 const Standard_Integer DegMax,
838 const Standard_Integer NbMaxSegment)
840 GeomAbs_Shape TheConti;
844 TheConti = GeomAbs_C0;
850 TheConti = GeomAbs_C1;
856 TheConti = GeomAbs_C2;
860 TheConti = GeomAbs_C2;// On ne sait pas faire mieux !
862 Handle (Approx_SweepFunction) Func;
867 Func = new (GeomFill_CircularBlendFunc)(myAdpPath,
873 Approx_SweepApproximation App(Func);
874 App.Perform(myAdpPath->FirstParameter(),
875 myAdpPath->LastParameter(),
877 TheConti, DegMax, NbMaxSegment);
884 mySurface = new Geom_BSplineSurface(App.SurfPoles(),
892 myError = App.MaxErrorOnSurf();
895 Standard_ConstructionError::Raise
896 ("GeomFill_Pipe::Perform : Cannot make a surface");
900 else if ( (! myLoc.IsNull()) && (! mySec.IsNull()) ) {
901 GeomFill_Sweep Sweep(myLoc, myKPart);
902 Sweep.SetTolerance(Tol);
903 Sweep.Build(mySec, GeomFill_Location, TheConti, DegMax, NbMaxSegment);
904 if (Sweep.IsDone()) {
905 mySurface = Sweep.Surface();
906 myError = Sweep.ErrorOnSurface();
909 Standard_ConstructionError::Raise
910 ("GeomFill_Pipe::Perform : Cannot make a surface");
914 Perform(Standard_True, Polynomial);
919 //=======================================================================
921 //purpose : Pour gerer les cas particulier de type 4
922 //=======================================================================
923 Standard_Boolean GeomFill_Pipe::KPartT4()
925 Standard_Boolean Ok = Standard_False;
926 // ------- Cas du Cylindre --------------------------
927 if (myAdpPath->GetType() == GeomAbs_Line &&
928 myAdpFirstSect->GetType() == GeomAbs_Line &&
929 myAdpLastSect ->GetType() == GeomAbs_Line ) {
930 // try to generate a cylinder.
931 gp_Ax1 A0 = myAdpPath ->Line().Position();
932 gp_Ax1 A1 = myAdpFirstSect->Line().Position();
933 gp_Ax1 A2 = myAdpLastSect ->Line().Position();
934 // direction must be the same.
935 gp_Dir D0 = A0.Direction();
936 gp_Dir D1 = A1.Direction();
937 gp_Dir D2 = A2.Direction();
938 if (!D0.IsEqual(D1,Precision::Angular()) ||
939 !D1.IsEqual(D2,Precision::Angular()) ) {
943 // the length of the line must be te same
945 myAdpPath->LastParameter() - myAdpPath->FirstParameter();
947 myAdpFirstSect->LastParameter() - myAdpFirstSect->FirstParameter();
949 myAdpLastSect->LastParameter() - myAdpLastSect->FirstParameter();
950 if (Abs(L1-L0) > Precision::Confusion() ||
951 Abs(L2-L0) > Precision::Confusion() ) {
955 // the first points must be normal to the path.
956 gp_Pnt P0 = myAdpPath ->Value(myAdpPath ->FirstParameter());
957 gp_Pnt P1 = myAdpFirstSect->Value(myAdpFirstSect->FirstParameter());
958 gp_Pnt P2 = myAdpLastSect ->Value(myAdpLastSect ->FirstParameter());
959 gp_Dir V1(gp_Vec(P0,P1));
960 gp_Dir V2(gp_Vec(P0,P2));
961 if (Abs(V1.Dot(D0)) > Precision::Confusion() ||
962 Abs(V2.Dot(D0)) > Precision::Confusion() ) return Ok;
964 // the result is a cylindrical surface.
965 gp_Dir X(V1), Y(V2), ZRef;
968 gp_Ax3 Axis( A0.Location(), D0, X);
969 if ( ZRef.Dot(D0) < 0.)
972 // rotate the surface to set the iso U = 0 not in the result.
973 Axis.Rotate(gp_Ax1(P0,ZRef),-M_PI/2.);
975 mySurface = new Geom_CylindricalSurface( Axis, myRadius);
976 Standard_Real Alpha = V1.AngleWithRef(V2,ZRef);
978 new Geom_RectangularTrimmedSurface(mySurface,
981 myAdpPath->FirstParameter(),
982 myAdpPath->LastParameter());
983 Ok = Standard_True; //C'est bien un cylindre
985 // ----------- Cas du tore ----------------------------------
986 else if (myAdpPath->GetType() == GeomAbs_Circle &&
987 myAdpFirstSect->GetType() == GeomAbs_Circle &&
988 myAdpLastSect->GetType() == GeomAbs_Circle ) {
989 // try to generate a toroidal surface.
990 // les 3 cercles doivent avoir meme angle d'ouverture
992 myAdpPath->FirstParameter() - myAdpPath->LastParameter();
994 myAdpFirstSect->FirstParameter() - myAdpFirstSect->LastParameter();
996 myAdpLastSect->FirstParameter() - myAdpLastSect->LastParameter();
998 if (Abs(Alp0-Alp1) > Precision::Angular() ||
999 Abs(Alp0-Alp2) > Precision::Angular() ) return Ok;
1001 gp_Ax2 A0 = myAdpPath ->Circle().Position();
1002 gp_Ax2 A1 = myAdpFirstSect->Circle().Position();
1003 gp_Ax2 A2 = myAdpLastSect ->Circle().Position();
1004 gp_Dir D0 = A0.Direction();
1005 gp_Dir D1 = A1.Direction();
1006 gp_Dir D2 = A2.Direction();
1007 gp_Pnt P0 = myAdpPath ->Value(myAdpPath ->FirstParameter());
1008 gp_Pnt P1 = myAdpFirstSect->Value(myAdpFirstSect->FirstParameter());
1009 gp_Pnt P2 = myAdpLastSect ->Value(myAdpLastSect ->FirstParameter());
1011 // les 3 directions doivent etre egales.
1012 if (!D0.IsEqual(D1,Precision::Angular()) ||
1013 !D1.IsEqual(D2,Precision::Angular()) ) return Ok;
1015 // les 3 ax1 doivent etre confondus.
1016 gp_Lin L(A0.Axis());
1017 if (!L.Contains(A1.Location(),Precision::Confusion()) ||
1018 !L.Contains(A2.Location(),Precision::Confusion()) ) return Ok;
1020 // les 3 premiers points doivent etre dans la meme section.
1021 gp_Dir V1(gp_Vec(P0,P1));
1022 gp_Dir V2(gp_Vec(P0,P2));
1023 gp_Circ Ci = myAdpPath->Circle();
1025 ElCLib::CircleDN(myAdpPath->FirstParameter(),A0, Ci.Radius(), 1);
1026 if (Abs(V1.Dot(YRef)) > Precision::Confusion() ||
1027 Abs(V2.Dot(YRef)) > Precision::Confusion() ) return Ok;
1029 // OK it`s a Toroidal Surface !! OUF !!
1030 gp_Torus T(A0,Ci.Radius(),myRadius);
1031 gp_Vec XRef(A0.Location(),P0);
1032 // au maximum on fait un tore d`ouverture en V = PI
1033 Standard_Real VV1 = V1.AngleWithRef(XRef,YRef);
1034 Standard_Real VV2 = V2.AngleWithRef(XRef,YRef);
1035 Standard_Real deltaV = V2.AngleWithRef(V1,YRef);
1039 VV2 = 2*M_PI + VV1 - deltaV;
1041 mySurface = new Geom_RectangularTrimmedSurface
1042 (new Geom_ToroidalSurface(T),
1043 myAdpPath->FirstParameter(),myAdpPath->LastParameter(),VV1,VV2);
1044 myExchUV = Standard_True;
1051 //=======================================================================
1052 //function : ApproxSurf
1054 //=======================================================================
1055 void GeomFill_Pipe::ApproxSurf(const Standard_Boolean WithParameters) {
1057 // Traitment of general case.
1058 // generate a sequence of the section by <SweepSectionGenerator>
1059 // and approximate this sequence.
1061 if (myType != 4) Standard_ConstructionError::Raise("GeomFill_Pipe");
1062 GeomFill_SweepSectionGenerator Section(myAdpPath, myAdpFirstSect,
1063 myAdpLastSect,myRadius);
1065 Section.Perform(myPolynomial);
1069 Standard_Integer NbPoles,NbKnots,Degree,NbPoles2d;
1070 Section.GetShape(NbPoles,NbKnots,Degree,NbPoles2d);
1072 TColgp_Array1OfPnt Poles (1,NbPoles);
1073 TColgp_Array1OfPnt2d Poles2d(1,NbPoles);
1074 TColStd_Array1OfReal Weights(1,NbPoles);
1075 TColStd_Array1OfInteger Mults (1,NbKnots);
1076 TColStd_Array1OfReal Knots (1,NbKnots);
1077 Section.Knots(Knots);
1078 Section.Mults(Mults);
1080 for (Standard_Integer i = 1; i <= Section.NbSections(); i++) {
1082 Section.Section(i,Poles,Poles2d,Weights);
1083 Handle(Geom_BSplineCurve) BS =
1084 new Geom_BSplineCurve(Poles,Weights,Knots,Mults,Degree);
1087 sprintf(name,"SECT_%d",NbSections);
1088 DrawTrSurf::Set(name,BS);
1094 Handle(GeomFill_Line) Line = new GeomFill_Line(Section.NbSections());
1095 Standard_Integer NbIt = 0;
1096 Standard_Real T3d = Precision::Approximation();
1097 Standard_Real T2d = Precision::PApproximation();
1098 GeomFill_AppSweep App( 4, 8, T3d, T2d, NbIt, WithParameters);
1100 App.Perform( Line, Section, 30);
1102 if ( !App.IsDone()) {
1104 // on affiche les sections sous debug
1105 Standard_Integer NbPoles,NbKnots,Degree,NbPoles2d;
1106 Section.GetShape(NbPoles,NbKnots,Degree,NbPoles2d);
1108 TColgp_Array1OfPnt Poles (1,NbPoles);
1109 TColgp_Array1OfPnt2d Poles2d(1,NbPoles);
1110 TColStd_Array1OfReal Weights(1,NbPoles);
1111 TColStd_Array1OfInteger Mults (1,NbKnots);
1112 TColStd_Array1OfReal Knots (1,NbKnots);
1113 Section.Knots(Knots);
1114 Section.Mults(Mults);
1116 for (Standard_Integer i = 1; i <= Section.NbSections(); i++) {
1117 Section.Section(i,Poles,Poles2d,Weights);
1118 Handle(Geom_BSplineCurve) BS =
1119 new Geom_BSplineCurve(Poles,Weights,Knots,Mults,Degree);
1122 sprintf(name,"sect_%d",i);
1123 DrawTrSurf::Set(name,BS);
1127 StdFail_NotDone::Raise("Pipe : App not done");
1130 Standard_Integer UDegree, VDegree, NbUPoles, NbVPoles, NbUKnots,
1132 App.SurfShape(UDegree, VDegree, NbUPoles, NbVPoles, NbUKnots, NbVKnots);
1134 mySurface = new Geom_BSplineSurface(App.SurfPoles(),
1143 App.TolReached(myError, t2d);