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 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 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
25 #include <GeomFill_Pipe.hxx>
27 #include <Adaptor3d_CurveOnSurface.hxx>
28 #include <Adaptor3d_Curve.hxx>
29 #include <Approx_SweepApproximation.hxx>
31 #include <Geom2d_Curve.hxx>
32 #include <Geom2dAdaptor_Curve.hxx>
33 #include <Geom_BSplineCurve.hxx>
34 #include <Geom_BSplineSurface.hxx>
35 #include <Geom_Circle.hxx>
36 #include <Geom_ConicalSurface.hxx>
37 #include <Geom_Curve.hxx>
38 #include <Geom_CylindricalSurface.hxx>
39 #include <Geom_Line.hxx>
40 #include <Geom_Plane.hxx>
41 #include <Geom_RectangularTrimmedSurface.hxx>
42 #include <Geom_SphericalSurface.hxx>
43 #include <Geom_Surface.hxx>
44 #include <Geom_SurfaceOfLinearExtrusion.hxx>
45 #include <Geom_ToroidalSurface.hxx>
46 #include <Geom_TrimmedCurve.hxx>
47 #include <GeomAbs_SurfaceType.hxx>
48 #include <GeomAdaptor_Curve.hxx>
49 #include <GeomAdaptor_Surface.hxx>
50 #include <GeomFill_AppSweep.hxx>
51 #include <GeomFill_CircularBlendFunc.hxx>
52 #include <GeomFill_ConstantBiNormal.hxx>
53 #include <GeomFill_CorrectedFrenet.hxx>
54 #include <GeomFill_CurveAndTrihedron.hxx>
55 #include <GeomFill_Darboux.hxx>
56 #include <GeomFill_Fixed.hxx>
57 #include <GeomFill_Frenet.hxx>
58 #include <GeomFill_GuideTrihedronAC.hxx>
59 #include <GeomFill_GuideTrihedronPlan.hxx>
60 #include <GeomFill_Line.hxx>
61 #include <GeomFill_LocationGuide.hxx>
62 #include <GeomFill_LocationLaw.hxx>
63 #include <GeomFill_NSections.hxx>
64 #include <GeomFill_Profiler.hxx>
65 #include <GeomFill_SectionLaw.hxx>
66 #include <GeomFill_SectionPlacement.hxx>
67 #include <GeomFill_Sweep.hxx>
68 #include <GeomFill_SweepSectionGenerator.hxx>
69 #include <GeomFill_UniformSection.hxx>
70 #include <GeomLib.hxx>
71 #include <GeomLProp_CLProps.hxx>
75 #include <gp_Torus.hxx>
76 #include <Precision.hxx>
77 #include <Standard_ConstructionError.hxx>
78 #include <TColGeom_SequenceOfCurve.hxx>
79 #include <TColgp_Array1OfPnt.hxx>
83 static Standard_Boolean Affich = Standard_False;
84 static Standard_Integer NbSections = 0;
88 #include <DrawTrSurf.hxx>
89 #include <Geom_Curve.hxx>
92 static Standard_Boolean CheckSense(const TColGeom_SequenceOfCurve& Seq1,
93 TColGeom_SequenceOfCurve& Seq2)
96 Standard_Boolean no_sing = Standard_True;
99 Handle(Geom_Curve) C1 = Seq1.Value(1);
100 Standard_Real f = C1->FirstParameter(), l = C1->LastParameter();
101 Standard_Integer iP, NP = 21;
102 TColgp_Array1OfPnt Tab(1,NP);
103 Standard_Real u = f, h = Abs(f-l) / 20.;
104 for (iP=1;iP<=NP;iP++) {
107 if ((u-f)*(u-l)>0.0) u = l;
111 Standard_Boolean sing;
112 GeomLib::AxeOfInertia(Tab,AxeRef,sing);
114 // si la section est une droite, ca ne marche pas
115 if (sing) no_sing = Standard_False;
117 Pos = AxeRef.Location();
118 Standard_Real alpha1, alpha2, alpha3;
124 alpha1 = gp_Vec(Pos,P1).AngleWithRef(gp_Vec(Pos,P2),AxeRef.Direction());
128 alpha2 = gp_Vec(Pos,P1).AngleWithRef(gp_Vec(Pos,P2),AxeRef.Direction());
132 alpha3 = gp_Vec(Pos,P1).AngleWithRef(gp_Vec(Pos,P2),AxeRef.Direction());
135 for (Standard_Integer iseq=2; iseq<=Seq1.Length(); iseq++) {
136 // discretisation de C2
137 Handle(Geom_Curve) C2 = Seq1.Value(iseq);
138 f = C2->FirstParameter();
139 l = C2->LastParameter();
141 for (iP=1;iP<=NP;iP++) {
144 if ((u-f)*(u-l)>0.0) u = l;
146 GeomLib::AxeOfInertia(Tab,Axe,sing);
148 // si la section est une droite, ca ne marche pas
149 if (sing) no_sing = Standard_False;
151 Pos = Axe.Location();
152 Standard_Real beta1, beta2, beta3;
157 beta1 = gp_Vec(Pos,P1).AngleWithRef(gp_Vec(Pos,P2),AxeRef.Direction());
161 beta2 = gp_Vec(Pos,P1).AngleWithRef(gp_Vec(Pos,P2),AxeRef.Direction());
165 beta3 = gp_Vec(Pos,P1).AngleWithRef(gp_Vec(Pos,P2),AxeRef.Direction());
168 Standard_Boolean ok = Standard_True,
169 pasnul1 = ( Abs(alpha1) > Precision::Confusion() )
170 && ( Abs(beta1) > Precision::Confusion() ),
171 pasnul2 = ( Abs(alpha2) > Precision::Confusion() )
172 && ( Abs(beta2) > Precision::Confusion() ),
173 pasnul3 = ( Abs(alpha3) > Precision::Confusion() )
174 && ( Abs(beta3) > Precision::Confusion() );
175 if (pasnul1 && pasnul2 && pasnul3) {
176 if (alpha1*beta1>0.0)
177 ok = (alpha2*beta2>0.0) || (alpha3*beta3>0.0);
179 ok = (alpha2*beta2>0.0) && (alpha3*beta3>0.0);
181 else if (pasnul1 && pasnul2 && !pasnul3)
182 ok = (alpha1*beta1>0.0) || (alpha2*beta2>0.0);
183 else if (pasnul1 && !pasnul2 && pasnul3)
184 ok = (alpha1*beta1>0.0) || (alpha3*beta3>0.0);
185 else if (!pasnul1 && pasnul2 && pasnul3)
186 ok = (alpha2*beta2>0.0) || (alpha3*beta3>0.0);
188 ok = (alpha1*beta1>0.0);
190 ok = (alpha2*beta2>0.0);
192 ok = (alpha3*beta3>0.0);
194 if (no_sing && !ok) {
203 //=======================================================================
204 //function : GeomFill_Pipe
205 //purpose : constructor with no parameters.
206 //=======================================================================
208 GeomFill_Pipe::GeomFill_Pipe() : myIsDone(Standard_False),myExchUV(Standard_False),myKPart(Standard_False)
214 //=======================================================================
215 //function : GeomFill_Pipe
217 //=======================================================================
219 GeomFill_Pipe::GeomFill_Pipe(const Handle(Geom_Curve)& Path,
220 const Standard_Real Radius)
221 : myIsDone(Standard_False),myExchUV(Standard_False),myKPart(Standard_False)
227 //=======================================================================
228 //function : GeomFill_Pipe
230 //=======================================================================
232 GeomFill_Pipe::GeomFill_Pipe(const Handle(Geom_Curve)& Path,
233 const Handle(Geom_Curve)& FirstSect,
234 const GeomFill_Trihedron Option)
235 : myIsDone(Standard_False),myExchUV(Standard_False),myKPart(Standard_False)
238 Init(Path, FirstSect, Option);
241 //=======================================================================
242 //function : GeomFill_Pipe
244 //=======================================================================
246 GeomFill_Pipe::GeomFill_Pipe(const Handle(Geom2d_Curve)& Path,
247 const Handle(Geom_Surface)& Support,
248 const Handle(Geom_Curve)& FirstSect)
249 : myIsDone(Standard_False),myExchUV(Standard_False),myKPart(Standard_False)
252 Init(Path, Support, FirstSect);
255 //=======================================================================
256 //function : GeomFill_Pipe
258 //=======================================================================
260 GeomFill_Pipe::GeomFill_Pipe(const Handle(Geom_Curve)& Path,
261 const Handle(Geom_Curve)& FirstSect,
262 const Handle(Geom_Curve)& LastSect)
263 : myIsDone(Standard_False),myExchUV(Standard_False),myKPart(Standard_False)
266 Init(Path, FirstSect, LastSect);
270 //=======================================================================
271 //function : GeomFill_Pipe
273 //=======================================================================
275 GeomFill_Pipe::GeomFill_Pipe(const Handle(Geom_Curve)& Path,
276 const TColGeom_SequenceOfCurve& NSections)
277 : myIsDone(Standard_False),myExchUV(Standard_False),myKPart(Standard_False)
280 Init(Path, NSections);
283 //=======================================================================
284 //function : GeomFill_Pipe
286 //=======================================================================
288 GeomFill_Pipe::GeomFill_Pipe(const Handle(Geom_Curve)& Path,
289 const Handle(Geom_Curve)& Curve1,
290 const gp_Dir& Direction)
291 : myIsDone(Standard_False),myExchUV(Standard_False), myKPart(Standard_False)
293 Init(Path, Curve1, Direction);
295 //=======================================================================
296 //function : GeomFill_Pipe
298 //=======================================================================
300 GeomFill_Pipe::GeomFill_Pipe(const Handle(Geom_Curve)& Path,
301 const Handle(Geom_Curve)& Curve1,
302 const Handle(Geom_Curve)& Curve2,
303 const Standard_Real Radius)
304 : myIsDone(Standard_False),myExchUV(Standard_False),myKPart(Standard_False)
307 Handle(GeomAdaptor_Curve) AdpPath =
308 new GeomAdaptor_Curve( Path);
309 Handle(GeomAdaptor_Curve) AdpCurve1 =
310 new GeomAdaptor_Curve( Curve1);
311 Handle(GeomAdaptor_Curve) AdpCurve2 =
312 new GeomAdaptor_Curve( Curve2);
314 Init(AdpPath, AdpCurve1, AdpCurve2, Radius);
318 //=======================================================================
319 //function : GeomFill_Pipe
321 //=======================================================================
323 GeomFill_Pipe::GeomFill_Pipe(const Handle(Adaptor3d_Curve)& Path,
324 const Handle(Adaptor3d_Curve)& Curve1,
325 const Handle(Adaptor3d_Curve)& Curve2,
326 const Standard_Real Radius)
327 : myIsDone(Standard_False),myExchUV(Standard_False),myKPart(Standard_False)
330 Init(Path,Curve1,Curve2,Radius);
334 //=======================================================================
337 //=======================================================================
338 //function : GeomFill_Pipe
339 //purpose : pipe avec courbe guide
340 //=======================================================================
342 GeomFill_Pipe::GeomFill_Pipe(const Handle(Geom_Curve)& Path,
343 const Handle(Adaptor3d_Curve)& Guide,
344 const Handle(Geom_Curve)& FirstSect,
345 const Standard_Boolean byACR,
346 const Standard_Boolean rotat)
347 : myIsDone(Standard_False),myExchUV(Standard_False),myKPart(Standard_False)
348 // Path : trajectoire
349 // Guide : courbe guide
350 // FirstSect : section
351 // NbPt : nb de points pour le calcul du triedre
354 Init(Path, Guide, FirstSect, byACR, rotat);
359 //=======================================================================
361 //purpose : pipe avec courbe guide
362 //=======================================================================
364 void GeomFill_Pipe::Init(const Handle(Geom_Curve)& Path,
365 const Handle(Adaptor3d_Curve)& Guide,
366 const Handle(Geom_Curve)& FirstSect,
367 const Standard_Boolean byACR,
368 const Standard_Boolean rotat)
369 // Path : trajectoire
370 // Guide : courbe guide
371 // FirstSect : section
372 // rotat : vrai si on veu la rotation false sinon
373 // triedre : AC pour absc. curv. ou P pour plan ortho
376 myAdpPath = new (GeomAdaptor_Curve)
377 (Handle(Geom_Curve)::DownCast(Path->Copy()));
379 Handle (GeomFill_TrihedronWithGuide) TLaw;
383 TLaw = new (GeomFill_GuideTrihedronAC)(Guide);
384 TLaw->SetCurve(myAdpPath);
387 TLaw = new (GeomFill_GuideTrihedronPlan)(Guide);
388 TLaw->SetCurve(myAdpPath);
392 // loi de positionnement
393 Handle(GeomFill_LocationGuide) TheLoc =
394 new (GeomFill_LocationGuide) (TLaw);
395 TheLoc->SetCurve(myAdpPath);
397 GeomFill_SectionPlacement Place(TheLoc, FirstSect);
398 Place.Perform(Precision::Confusion());
401 mySec = new (GeomFill_UniformSection) (Place.Section(Standard_False),
402 myAdpPath->FirstParameter(),
403 myAdpPath->LastParameter());
407 char* Temp = "TheSect" ;
408 DrawTrSurf::Set(Temp, FirstSect );
409 // DrawTrSurf::Set("TheSect", FirstSect );
413 if (rotat) TheLoc->Set(mySec,rotat,
414 myAdpPath->FirstParameter(),
415 myAdpPath->LastParameter(),
421 //=======================================================================
424 //=======================================================================
426 void GeomFill_Pipe::Init()
431 myKPart = Standard_True;
432 myPolynomial = Standard_False;
434 myAdpFirstSect.Nullify();
435 myAdpLastSect.Nullify();
439 //=======================================================================
442 //=======================================================================
444 void GeomFill_Pipe::Init(const Handle(Geom_Curve)& Path,
445 const Standard_Real Radius)
453 myAdpPath = new (GeomAdaptor_Curve) (Path);
454 Handle(Geom_Circle) C = new (Geom_Circle) (gp::XOY(), Radius);
455 C->Rotate(gp::OZ(),M_PI/2.);
457 mySec = new (GeomFill_UniformSection) (C, Path->FirstParameter(),
458 Path->LastParameter());
459 Handle (GeomFill_CorrectedFrenet)TLaw = new (GeomFill_CorrectedFrenet) ();
460 myLoc = new (GeomFill_CurveAndTrihedron) (TLaw);
461 myLoc->SetCurve(myAdpPath);
465 char* Temp = "TheSect" ;
466 DrawTrSurf::Set(Temp, C);
467 // DrawTrSurf::Set("TheSect", C);
473 //=======================================================================
476 //=======================================================================
478 void GeomFill_Pipe::Init(const Handle(Geom_Curve)& Path,
479 const Handle(Geom_Curve)& FirstSect,
480 const GeomFill_Trihedron Option)
482 Handle(Geom_Curve) Sect;
483 Handle(GeomFill_TrihedronLaw) TLaw;
484 myAdpPath = new (GeomAdaptor_Curve)
485 (Handle(Geom_Curve)::DownCast(Path->Copy()));
486 Standard_Real param = Path->FirstParameter();
488 // Construction de la loi de triedre
490 case GeomFill_IsCorrectedFrenet :
492 TLaw = new (GeomFill_CorrectedFrenet) ();
496 case GeomFill_IsDarboux :
499 std::cout << "Option Darboux: non realisable" << std::endl;
502 case GeomFill_IsFrenet :
504 TLaw = new (GeomFill_Frenet) ();
508 case GeomFill_IsFixed :
510 Standard_Real Eps = 1.e-9;
511 gp_Vec V1(0,0,1), V2(0,1,0);
513 GeomLProp_CLProps CP(Path, param, 2, Eps);
514 if (CP.IsTangentDefined()) {
518 if (CP.Curvature() > Eps) {
524 gp_Pnt P0(0., 0., 0.);
526 D = Axe.XDirection ();
531 TLaw = new (GeomFill_Fixed) (V1, V2);
535 case GeomFill_IsConstantNormal :
537 TLaw = new (GeomFill_Frenet) ();
538 myLoc = new (GeomFill_CurveAndTrihedron) (TLaw);
539 myLoc->SetCurve(myAdpPath);
540 GeomFill_SectionPlacement Place(myLoc, FirstSect);
541 Place.Perform(Precision::Confusion());
542 Standard_Real ponsec = Place.ParameterOnSection();
544 Standard_Real Eps = 1.e-9;
547 GeomLProp_CLProps CP(FirstSect, ponsec, 2, Eps);
548 if (CP.IsTangentDefined()) {
550 if (CP.Curvature() > Eps) {
556 gp_Pnt P0(0., 0., 0.);
558 D = Axe.XDirection ();
563 TLaw = new (GeomFill_ConstantBiNormal) (V);
569 throw Standard_ConstructionError("GeomFill::Init : Unknown Option");
573 if (!TLaw.IsNull()) {
574 myLoc = new (GeomFill_CurveAndTrihedron) (TLaw);
575 myLoc->SetCurve(myAdpPath);
576 GeomFill_SectionPlacement Place(myLoc, FirstSect);
577 Place.Perform(Precision::Confusion());
578 param = Place.ParameterOnPath();
579 Sect = Place.Section(Standard_False);
583 char* Temp = "TheSect" ;
584 DrawTrSurf::Set(Temp,Sect);
585 // DrawTrSurf::Set("TheSect",Sect);
589 mySec = new (GeomFill_UniformSection) (Sect,
590 Path->FirstParameter(),
591 Path->LastParameter());
595 //=======================================================================
597 //purpose : sweep using Darboux's trihedron
598 //=======================================================================
600 void GeomFill_Pipe::Init(const Handle(Geom2d_Curve)& Path,
601 const Handle(Geom_Surface)& Support,
602 const Handle(Geom_Curve)& FirstSect)
604 Handle(Geom_Curve) Sect;
605 Handle(GeomFill_TrihedronLaw) TLaw = new (GeomFill_Darboux)();
607 new Adaptor3d_CurveOnSurface(Adaptor3d_CurveOnSurface(
608 new Geom2dAdaptor_Curve(Path),
609 new GeomAdaptor_Surface(Support)));
611 myLoc = new (GeomFill_CurveAndTrihedron) (TLaw);
612 myLoc->SetCurve(myAdpPath);
613 GeomFill_SectionPlacement Place(myLoc, FirstSect);
614 Place.Perform(myAdpPath, Precision::Confusion());
615 Sect = Place.Section(Standard_False);
619 char* temp = "TheSect" ;
620 DrawTrSurf::Set(temp,Sect);
621 // DrawTrSurf::Set("TheSect",Sect);
625 mySec = new (GeomFill_UniformSection) (Sect,
626 myAdpPath->FirstParameter(),
627 myAdpPath->LastParameter());
630 //=======================================================================
633 //=======================================================================
635 void GeomFill_Pipe::Init(const Handle(Geom_Curve)& Path,
636 const Handle(Geom_Curve)& FirstSect,
637 const gp_Dir& Direction)
641 Handle(Geom_Curve) Sect;
642 myAdpPath = new (GeomAdaptor_Curve)
643 (Handle(Geom_Curve)::DownCast(Path->Copy()));
645 V.SetXYZ(Direction.XYZ());
646 Handle (GeomFill_ConstantBiNormal) TLaw =
647 new (GeomFill_ConstantBiNormal) (V);
649 myLoc = new (GeomFill_CurveAndTrihedron) (TLaw);
650 myLoc->SetCurve(myAdpPath);
651 GeomFill_SectionPlacement Place(myLoc, FirstSect);
652 Place.Perform(Precision::Confusion());
653 Sect = Place.Section(Standard_False);
657 char* temp = "TheSect" ;
658 DrawTrSurf::Set(temp,Sect);
659 // DrawTrSurf::Set("TheSect",Sect);
662 mySec = new (GeomFill_UniformSection) (Sect,
663 Path->FirstParameter(),
664 Path->LastParameter());
667 //=======================================================================
670 //=======================================================================
672 void GeomFill_Pipe::Init(const Handle(Geom_Curve)& Path,
673 const TColGeom_SequenceOfCurve& NSections)
679 Handle(GeomFill_TrihedronLaw) TLaw;
680 TLaw = new (GeomFill_CorrectedFrenet) ();
681 myAdpPath = new (GeomAdaptor_Curve)
682 (Handle(Geom_Curve)::DownCast(Path->Copy()));
683 if (!TLaw.IsNull()) {
684 myLoc = new (GeomFill_CurveAndTrihedron) (TLaw);
685 myLoc->SetCurve(myAdpPath);
686 TColGeom_SequenceOfCurve SeqC;
687 TColStd_SequenceOfReal SeqP;
691 for ( i = 1; i<=NSections.Length(); i++) {
692 GeomFill_SectionPlacement Place(myLoc, NSections(i));
693 Place.Perform(Precision::Confusion());
694 SeqP.Append(Place.ParameterOnPath());
695 SeqC.Append(Place.Section(Standard_False));
698 // verification des orientations
699 TColGeom_SequenceOfCurve NewSeq;
700 if (CheckSense(SeqC,NewSeq)) SeqC = NewSeq;
702 // verification des parametres
703 Standard_Boolean play_again = Standard_True;
705 play_again = Standard_False;
706 for (i = 1; i<=NSections.Length(); i++) {
707 for (Standard_Integer j = i; j<=NSections.Length(); j++) {
708 if (SeqP.Value(i)>SeqP.Value(j)) {
711 play_again = Standard_True;
716 for ( i = 1; i<NSections.Length(); i++) {
717 if ( Abs(SeqP.Value(i+1)-SeqP.Value(i)) < Precision::PConfusion()) {
718 throw Standard_ConstructionError("GeomFill_Pipe::Init with NSections : invalid parameters");
722 // creation de la NSections
723 Standard_Real first = Path->FirstParameter(),
724 last = Path->LastParameter();
725 Standard_Real deb,fin;
726 deb = SeqC.First()->FirstParameter();
727 fin = SeqC.First()->LastParameter();
728 mySec = new (GeomFill_NSections) (SeqC,SeqP,deb,fin,first,last);
733 //=======================================================================
736 //=======================================================================
738 void GeomFill_Pipe::Init(const Handle(Geom_Curve)& Path,
739 const Handle(Geom_Curve)& FirstSect,
740 const Handle(Geom_Curve)& LastSect)
745 Standard_Real first = Path->FirstParameter(),
746 last = Path->LastParameter();
747 Handle(GeomFill_TrihedronLaw) TLaw;
748 TLaw = new (GeomFill_CorrectedFrenet) ();
749 myAdpPath = new (GeomAdaptor_Curve)
750 (Handle(Geom_Curve)::DownCast(Path->Copy()));
752 if (!TLaw.IsNull()) {
753 myLoc = new (GeomFill_CurveAndTrihedron) (TLaw);
754 myLoc->SetCurve(myAdpPath);
755 TColGeom_SequenceOfCurve SeqC;
756 TColStd_SequenceOfReal SeqP;
759 // sequence des sections
760 GeomFill_SectionPlacement Pl1(myLoc, FirstSect);
761 Pl1.Perform(first,Precision::Confusion());
762 SeqC.Append(Pl1.Section(Standard_False));
763 GeomFill_SectionPlacement Pl2(myLoc, LastSect);
764 Pl2.Perform(first,Precision::Confusion());
765 SeqC.Append(Pl2.Section(Standard_False));
766 // sequence des parametres associes
770 // verification de l'orientation
771 TColGeom_SequenceOfCurve NewSeq;
772 if (CheckSense(SeqC,NewSeq)) SeqC = NewSeq;
774 // creation de la NSections
775 Standard_Real deb,fin;
776 deb = SeqC.First()->FirstParameter();
777 fin = SeqC.First()->LastParameter();
778 mySec = new (GeomFill_NSections) (SeqC,SeqP,deb,fin,first,last);
782 //=======================================================================
785 //=======================================================================
787 void GeomFill_Pipe::Init(const Handle(Adaptor3d_Curve)& Path,
788 const Handle(Adaptor3d_Curve)& Curve1,
789 const Handle(Adaptor3d_Curve)& Curve2,
790 const Standard_Real Radius)
796 myAdpFirstSect = Curve1;
797 myAdpLastSect = Curve2;
800 //=======================================================================
803 //=======================================================================
805 void GeomFill_Pipe::Perform(const Standard_Boolean WithParameters,
806 const Standard_Boolean Polynomial)
809 if ( (! myLoc.IsNull()) && (! mySec.IsNull()) ) {
810 Perform(1.e-4, Polynomial);
814 myPolynomial = Polynomial;
815 // on traite la cas tuyau sur arete Type = 4
817 ApproxSurf(WithParameters);
820 if ( !KPartT4() ) ApproxSurf(WithParameters);
824 //=======================================================================
827 //=======================================================================
828 void GeomFill_Pipe::Perform(const Standard_Real Tol,
829 const Standard_Boolean Polynomial,
830 const GeomAbs_Shape Conti,
831 const Standard_Integer DegMax,
832 const Standard_Integer NbMaxSegment)
834 GeomAbs_Shape TheConti;
838 TheConti = GeomAbs_C0;
844 TheConti = GeomAbs_C1;
850 TheConti = GeomAbs_C2;
854 TheConti = GeomAbs_C2;// On ne sait pas faire mieux !
856 Handle (Approx_SweepFunction) Func;
861 Func = new (GeomFill_CircularBlendFunc)(myAdpPath,
867 Approx_SweepApproximation App(Func);
868 App.Perform(myAdpPath->FirstParameter(),
869 myAdpPath->LastParameter(),
871 TheConti, DegMax, NbMaxSegment);
873 std::cout << "Tuyau : ";
875 std::cout << std::endl;
878 mySurface = new Geom_BSplineSurface(App.SurfPoles(),
886 myError = App.MaxErrorOnSurf();
887 myIsDone = Standard_True;
890 // throw Standard_ConstructionError("GeomFill_Pipe::Perform : Cannot make a surface");
894 else if ( (! myLoc.IsNull()) && (! mySec.IsNull()) ) {
895 GeomFill_Sweep Sweep(myLoc, myKPart);
896 Sweep.SetTolerance(Tol);
897 Sweep.Build(mySec, GeomFill_Location, TheConti, DegMax, NbMaxSegment);
898 if (Sweep.IsDone()) {
899 mySurface = Sweep.Surface();
900 myError = Sweep.ErrorOnSurface();
901 myIsDone = Standard_True;
904 // throw Standard_ConstructionError("GeomFill_Pipe::Perform : Cannot make a surface");
908 Perform(Standard_True, Polynomial);
913 //=======================================================================
915 //purpose : Pour gerer les cas particulier de type 4
916 //=======================================================================
917 Standard_Boolean GeomFill_Pipe::KPartT4()
919 Standard_Boolean Ok = Standard_False;
920 // ------- Cas du Cylindre --------------------------
921 if (myAdpPath->GetType() == GeomAbs_Line &&
922 myAdpFirstSect->GetType() == GeomAbs_Line &&
923 myAdpLastSect ->GetType() == GeomAbs_Line ) {
924 // try to generate a cylinder.
925 gp_Ax1 A0 = myAdpPath ->Line().Position();
926 gp_Ax1 A1 = myAdpFirstSect->Line().Position();
927 gp_Ax1 A2 = myAdpLastSect ->Line().Position();
928 // direction must be the same.
929 gp_Dir D0 = A0.Direction();
930 gp_Dir D1 = A1.Direction();
931 gp_Dir D2 = A2.Direction();
932 if (!D0.IsEqual(D1,Precision::Angular()) ||
933 !D1.IsEqual(D2,Precision::Angular()) ) {
937 // the length of the line must be te same
939 myAdpPath->LastParameter() - myAdpPath->FirstParameter();
941 myAdpFirstSect->LastParameter() - myAdpFirstSect->FirstParameter();
943 myAdpLastSect->LastParameter() - myAdpLastSect->FirstParameter();
944 if (Abs(L1-L0) > Precision::Confusion() ||
945 Abs(L2-L0) > Precision::Confusion() ) {
949 // the first points must be normal to the path.
950 gp_Pnt P0 = myAdpPath ->Value(myAdpPath ->FirstParameter());
951 gp_Pnt P1 = myAdpFirstSect->Value(myAdpFirstSect->FirstParameter());
952 gp_Pnt P2 = myAdpLastSect ->Value(myAdpLastSect ->FirstParameter());
953 gp_Dir V1(gp_Vec(P0,P1));
954 gp_Dir V2(gp_Vec(P0,P2));
955 if (Abs(V1.Dot(D0)) > Precision::Confusion() ||
956 Abs(V2.Dot(D0)) > Precision::Confusion() ) return Ok;
958 // the result is a cylindrical surface.
959 gp_Dir X(V1), Y(V2), ZRef;
962 gp_Ax3 Axis( A0.Location(), D0, X);
963 if ( ZRef.Dot(D0) < 0.)
966 // rotate the surface to set the iso U = 0 not in the result.
967 Axis.Rotate(gp_Ax1(P0,ZRef),-M_PI/2.);
969 mySurface = new Geom_CylindricalSurface( Axis, myRadius);
970 Standard_Real Alpha = V1.AngleWithRef(V2,ZRef);
972 new Geom_RectangularTrimmedSurface(mySurface,
975 myAdpPath->FirstParameter(),
976 myAdpPath->LastParameter());
977 Ok = Standard_True; //C'est bien un cylindre
978 myIsDone = Standard_True;
980 // ----------- Cas du tore ----------------------------------
981 else if (myAdpPath->GetType() == GeomAbs_Circle &&
982 myAdpFirstSect->GetType() == GeomAbs_Circle &&
983 myAdpLastSect->GetType() == GeomAbs_Circle ) {
984 // try to generate a toroidal surface.
985 // les 3 cercles doivent avoir meme angle d'ouverture
987 myAdpPath->FirstParameter() - myAdpPath->LastParameter();
989 myAdpFirstSect->FirstParameter() - myAdpFirstSect->LastParameter();
991 myAdpLastSect->FirstParameter() - myAdpLastSect->LastParameter();
993 if (Abs(Alp0-Alp1) > Precision::Angular() ||
994 Abs(Alp0-Alp2) > Precision::Angular() ) return Ok;
996 gp_Ax2 A0 = myAdpPath ->Circle().Position();
997 gp_Ax2 A1 = myAdpFirstSect->Circle().Position();
998 gp_Ax2 A2 = myAdpLastSect ->Circle().Position();
999 gp_Dir D0 = A0.Direction();
1000 gp_Dir D1 = A1.Direction();
1001 gp_Dir D2 = A2.Direction();
1002 gp_Pnt P0 = myAdpPath ->Value(myAdpPath ->FirstParameter());
1003 gp_Pnt P1 = myAdpFirstSect->Value(myAdpFirstSect->FirstParameter());
1004 gp_Pnt P2 = myAdpLastSect ->Value(myAdpLastSect ->FirstParameter());
1006 // les 3 directions doivent etre egales.
1007 if (!D0.IsEqual(D1,Precision::Angular()) ||
1008 !D1.IsEqual(D2,Precision::Angular()) ) return Ok;
1010 // les 3 ax1 doivent etre confondus.
1011 gp_Lin L(A0.Axis());
1012 if (!L.Contains(A1.Location(),Precision::Confusion()) ||
1013 !L.Contains(A2.Location(),Precision::Confusion()) ) return Ok;
1015 // les 3 premiers points doivent etre dans la meme section.
1016 gp_Dir V1(gp_Vec(P0,P1));
1017 gp_Dir V2(gp_Vec(P0,P2));
1018 gp_Circ Ci = myAdpPath->Circle();
1020 ElCLib::CircleDN(myAdpPath->FirstParameter(),A0, Ci.Radius(), 1);
1021 if (Abs(V1.Dot(YRef)) > Precision::Confusion() ||
1022 Abs(V2.Dot(YRef)) > Precision::Confusion() ) return Ok;
1024 // OK it`s a Toroidal Surface !! OUF !!
1025 gp_Torus T(A0,Ci.Radius(),myRadius);
1026 gp_Vec XRef(A0.Location(),P0);
1027 // au maximum on fait un tore d`ouverture en V = PI
1028 Standard_Real VV1 = V1.AngleWithRef(XRef,YRef);
1029 Standard_Real VV2 = V2.AngleWithRef(XRef,YRef);
1030 Standard_Real deltaV = V2.AngleWithRef(V1,YRef);
1034 VV2 = 2*M_PI + VV1 - deltaV;
1036 mySurface = new Geom_RectangularTrimmedSurface
1037 (new Geom_ToroidalSurface(T),
1038 myAdpPath->FirstParameter(),myAdpPath->LastParameter(),VV1,VV2);
1039 myExchUV = Standard_True;
1041 myIsDone = Standard_True;
1047 //=======================================================================
1048 //function : ApproxSurf
1050 //=======================================================================
1051 void GeomFill_Pipe::ApproxSurf(const Standard_Boolean WithParameters) {
1053 // Traitment of general case.
1054 // generate a sequence of the section by <SweepSectionGenerator>
1055 // and approximate this sequence.
1057 if (myType != 4) throw Standard_ConstructionError("GeomFill_Pipe");
1058 GeomFill_SweepSectionGenerator Section(myAdpPath, myAdpFirstSect,
1059 myAdpLastSect,myRadius);
1061 Section.Perform(myPolynomial);
1065 Standard_Integer NbPoles,NbKnots,Degree,NbPoles2d;
1066 Section.GetShape(NbPoles,NbKnots,Degree,NbPoles2d);
1068 TColgp_Array1OfPnt Poles (1,NbPoles);
1069 TColgp_Array1OfPnt2d Poles2d(1,NbPoles);
1070 TColStd_Array1OfReal Weights(1,NbPoles);
1071 TColStd_Array1OfInteger Mults (1,NbKnots);
1072 TColStd_Array1OfReal Knots (1,NbKnots);
1073 Section.Knots(Knots);
1074 Section.Mults(Mults);
1076 for (Standard_Integer i = 1; i <= Section.NbSections(); i++) {
1078 Section.Section(i,Poles,Poles2d,Weights);
1079 Handle(Geom_BSplineCurve) BS =
1080 new Geom_BSplineCurve(Poles,Weights,Knots,Mults,Degree);
1083 sprintf(name,"SECT_%d",NbSections);
1084 DrawTrSurf::Set(name,BS);
1090 Handle(GeomFill_Line) Line = new GeomFill_Line(Section.NbSections());
1091 Standard_Integer NbIt = 0;
1092 Standard_Real T3d = Precision::Approximation();
1093 Standard_Real T2d = Precision::PApproximation();
1094 GeomFill_AppSweep App( 4, 8, T3d, T2d, NbIt, WithParameters);
1096 App.Perform( Line, Section, 30);
1098 if ( !App.IsDone()) {
1100 // on affiche les sections sous debug
1101 Standard_Integer NbPoles,NbKnots,Degree,NbPoles2d;
1102 Section.GetShape(NbPoles,NbKnots,Degree,NbPoles2d);
1104 TColgp_Array1OfPnt Poles (1,NbPoles);
1105 TColgp_Array1OfPnt2d Poles2d(1,NbPoles);
1106 TColStd_Array1OfReal Weights(1,NbPoles);
1107 TColStd_Array1OfInteger Mults (1,NbKnots);
1108 TColStd_Array1OfReal Knots (1,NbKnots);
1109 Section.Knots(Knots);
1110 Section.Mults(Mults);
1112 for (Standard_Integer i = 1; i <= Section.NbSections(); i++) {
1113 Section.Section(i,Poles,Poles2d,Weights);
1114 Handle(Geom_BSplineCurve) BS =
1115 new Geom_BSplineCurve(Poles,Weights,Knots,Mults,Degree);
1118 sprintf(name,"sect_%d",i);
1119 DrawTrSurf::Set(name,BS);
1123 //throw StdFail_NotDone("Pipe : App not done");
1126 Standard_Integer UDegree, VDegree, NbUPoles, NbVPoles, NbUKnots,
1128 App.SurfShape(UDegree, VDegree, NbUPoles, NbVPoles, NbUKnots, NbVKnots);
1130 mySurface = new Geom_BSplineSurface(App.SurfPoles(),
1139 App.TolReached(myError, t2d);
1140 myIsDone = Standard_True;