1 // File: BRepFill_PipeShell.cxx
2 // Created: Wed Jul 22 10:52:44 1998
3 // Author: Philippe MANGIN
8 #include <BRepFill_PipeShell.ixx>
10 #include <BRep_Builder.hxx>
11 #include <BRep_Tool.hxx>
13 #include <TopTools_SequenceOfShape.hxx>
15 #include <TopoDS_Shell.hxx>
16 #include <TopoDS_Solid.hxx>
17 #include <TopoDS_Iterator.hxx>
18 #include <TopLoc_Location.hxx>
20 #include <BRepLib_MakeEdge.hxx>
21 #include <BRepLib_MakeFace.hxx>
22 #include <BRepAdaptor_HCompCurve.hxx>
23 #include <BRepClass3d_SolidClassifier.hxx>
25 #include <BRepFill.hxx>
26 #include <BRepFill_Sweep.hxx>
27 #include <BRepFill_SectionPlacement.hxx>
28 #include <BRepFill_Edge3DLaw.hxx>
29 #include <BRepFill_ACRLaw.hxx>
30 #include <BRepFill_EdgeOnSurfLaw.hxx>
31 #include <BRepFill_ShapeLaw.hxx>
32 #include <BRepFill_CompatibleWires.hxx>
33 #include <BRepFill_NSections.hxx>
34 #include <TColStd_HArray1OfReal.hxx>
36 #include <GeomFill_TrihedronLaw.hxx>
37 #include <GeomFill_CorrectedFrenet.hxx>
38 #include <GeomFill_Frenet.hxx>
39 #include <GeomFill_Fixed.hxx>
40 #include <GeomFill_ConstantBiNormal.hxx>
41 #include <GeomFill_SectionLaw.hxx>
42 #include <GeomFill_CurveAndTrihedron.hxx>
43 #include <GeomFill_GuideTrihedronAC.hxx>
44 #include <GeomFill_GuideTrihedronPlan.hxx>
45 #include <GeomFill_LocationGuide.hxx>
48 #include <GeomAdaptor_HCurve.hxx>
50 #include <gp_Trsf.hxx>
53 #include <Precision.hxx>
55 #include <Standard_NotImplemented.hxx>
56 #include <Standard_ConstructionError.hxx>
57 #include <StdFail_NotDone.hxx>
59 #include <BRepBuilderAPI_Copy.hxx>
63 #include <DrawTrSurf.hxx>
65 static Standard_Boolean Affich = 0;
68 #include <TopTools_ListIteratorOfListOfShape.hxx>
69 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
70 #include <TopoDS_Compound.hxx>
72 static Standard_Boolean UpdateMap(const TopoDS_Shape& theKey,
73 const TopoDS_Shape& theValue,
74 TopTools_DataMapOfShapeListOfShape& theMap);
76 static Standard_Boolean BuildBoundaries(const BRepFill_Sweep& theSweep,
77 const Handle(BRepFill_SectionLaw)& theSection,
78 TopoDS_Shape& theBottom,
79 TopoDS_Shape& theTop);
81 //=======================================================================
82 //function : ComputeSection
83 //purpose : Construit une section intermediaire
84 //=======================================================================
86 static Standard_Boolean ComputeSection(const TopoDS_Wire& W1,
87 const TopoDS_Wire& W2,
88 const Standard_Real p1,
89 const Standard_Real p2,
92 TColStd_SequenceOfReal SR;
93 TopTools_SequenceOfShape SSh;
100 BRepFill_CompatibleWires CW(SSh);
103 if (!CW.IsDone()) StdFail_NotDone::Raise("Uncompatible wires");
104 Handle(BRepFill_NSections) SL = new (BRepFill_NSections) (CW.Shape(),SR,0.,1.)
106 Standard_Real US = p1/(p1+p2);
108 return Standard_True;
113 //=======================================================================
114 //function : PerformTransition
115 //purpose : Modifie une loi de loc en fonction de Transition
116 //=======================================================================
118 static void PerformTransition(const BRepFill_TransitionStyle Mode,
119 Handle(BRepFill_LocationLaw)& Loc,
120 const Standard_Real angmin)
123 Loc->DeleteTransform();
124 if (Mode == BRepFill_Modified) Loc->TransformInG0Law();
125 else Loc->TransformInCompatibleLaw(angmin);
128 //=======================================================================
129 //function : PerformPlan
130 //purpose : Construit s'il existe un plan de remplissage
131 //=======================================================================
133 static Standard_Boolean PerformPlan(TopoDS_Shape& S)
135 Standard_Boolean isDegen = Standard_True;
136 TopExp_Explorer explo(S, TopAbs_EDGE);
137 for (; explo.More(); explo.Next())
139 const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
140 if (!BRep_Tool::Degenerated(anEdge))
141 isDegen = Standard_False;
146 return Standard_True;
149 TopoDS_Wire W = TopoDS::Wire(S);
150 Standard_Boolean Ok = Standard_False;
152 BRepLib_MakeFace mkplan(W, Standard_True);
153 if (mkplan.IsDone()) {
161 //=============================================================================
162 //function : IsSameOriented
163 //purpose : Checks whether aFace is oriented to the same side as aShell or not
164 //=============================================================================
166 static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace,
167 const TopoDS_Shape& aShell)
169 TopExp_Explorer Explo(aFace, TopAbs_EDGE);
170 TopoDS_Shape anEdge = Explo.Current();
171 TopAbs_Orientation Or1 = anEdge.Orientation();
173 TopTools_IndexedDataMapOfShapeListOfShape EFmap;
174 TopExp::MapShapesAndAncestors( aShell, TopAbs_EDGE, TopAbs_FACE, EFmap );
176 const TopoDS_Shape& AdjacentFace = EFmap.FindFromKey(anEdge).First();
177 TopoDS_Shape theEdge;
178 for (Explo.Init(AdjacentFace, TopAbs_EDGE); Explo.More(); Explo.Next())
180 theEdge = Explo.Current();
181 if (theEdge.IsSame(anEdge))
185 TopAbs_Orientation Or2 = theEdge.Orientation();
187 return Standard_False;
188 return Standard_True;
190 //=======================================================================
191 //function : BRepFill_PipeShell
193 //=======================================================================
194 BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
196 myTrihedron(GeomFill_IsCorrectedFrenet),
197 myTransition(BRepFill_Modified),
198 myStatus(GeomFill_PipeOk)
200 myLocation.Nullify();
205 // Attention aux wire closed non declare !
206 if (!mySpine.Closed()) {
207 TopoDS_Vertex Vf, Vl;
208 TopExp::Vertices(mySpine, Vf, Vl);
209 if (Vf.IsSame(Vl)) mySpine.Closed(Standard_True);
213 //=======================================================================
215 //purpose : Definie une loi de Frenet (Corrige)
216 //=======================================================================
217 void BRepFill_PipeShell::Set(const Standard_Boolean IsFrenet)
219 Handle(GeomFill_TrihedronLaw) TLaw;
221 myTrihedron = GeomFill_IsFrenet;
222 TLaw = new (GeomFill_Frenet) ();
225 myTrihedron = GeomFill_IsFrenet;
226 TLaw = new (GeomFill_CorrectedFrenet) ();
228 Handle(GeomFill_CurveAndTrihedron) Loc =
229 new (GeomFill_CurveAndTrihedron) (TLaw);
230 myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc);
231 mySection.Nullify(); //Il faut relocaliser les sections.
234 //=======================================================================
236 //purpose : Definie une loi Constante
237 //=======================================================================
238 void BRepFill_PipeShell::Set(const gp_Ax2& Axe)
240 myTrihedron = GeomFill_IsFixed;
242 V1.SetXYZ(Axe.Direction().XYZ());
243 V2.SetXYZ(Axe.XDirection().XYZ());
244 Handle(GeomFill_Fixed) TLaw = new (GeomFill_Fixed) (V1, V2);
245 Handle(GeomFill_CurveAndTrihedron) Loc =
246 new (GeomFill_CurveAndTrihedron) (TLaw);
247 myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc);
248 mySection.Nullify(); //Il faut relocaliser les sections.
251 //=======================================================================
253 //purpose : Construit une loi de location de type binormal fixe
254 //=======================================================================
255 void BRepFill_PipeShell::Set(const gp_Dir& BiNormal)
257 myTrihedron = GeomFill_IsConstantNormal;
259 Handle(GeomFill_ConstantBiNormal) TLaw =
260 new (GeomFill_ConstantBiNormal) (BiNormal);
261 Handle(GeomFill_CurveAndTrihedron) Loc =
262 new (GeomFill_CurveAndTrihedron) (TLaw);
263 myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc);
264 mySection.Nullify(); //Il faut relocaliser les sections.
267 //=======================================================================
269 //purpose : Construit une loi de location de type Darboux
270 //=======================================================================
271 Standard_Boolean BRepFill_PipeShell::Set(const TopoDS_Shape& SpineSupport)
275 // Il faut une loi de location speciale
276 Handle(BRepFill_EdgeOnSurfLaw) loc =
277 new (BRepFill_EdgeOnSurfLaw) (mySpine, SpineSupport);
278 B = loc->HasResult();
281 myTrihedron = GeomFill_IsDarboux;
282 mySection.Nullify(); //Il faut relocaliser les sections.
287 //=======================================================================
289 //purpose : Definit une loi a l'aide d'un contour guide
290 //=======================================================================
291 void BRepFill_PipeShell::Set(const TopoDS_Wire& AuxiliarySpine,
292 const Standard_Boolean CurvilinearEquivalence,
293 const Standard_Boolean KeepContact)
295 // Reorganisation du guide (pb d'orientation et d'origine)
296 TopoDS_Wire TheGuide;
297 TheGuide = AuxiliarySpine;
298 Standard_Boolean SpClose = mySpine.Closed(),
299 GuideClose = AuxiliarySpine.Closed();
301 if (!SpClose && !GuideClose) {
302 // Cas ouvert reorientation du guide
303 TopoDS_Wire sp = mySpine;
304 TopTools_SequenceOfShape Seq;
306 Seq.Append(TheGuide);
307 BRepFill_CompatibleWires CW(Seq);
310 if (!CW.IsDone()) StdFail_NotDone::Raise("Uncompatible wires");
311 TheGuide = TopoDS::Wire(CW.Shape().Value(2));
313 else if (GuideClose) {
314 // Cas guide ferme : Determination de l'origine
315 // & reorientation du guide
319 TopoDS_Vertex Vf, Vl;
321 TopExp::Vertices(mySpine, Vf, Vl);
322 SpOr = BRep_Tool::Pnt(Vf);
323 P = BRep_Tool::Pnt(Vl);
325 SpOr.BaryCenter(0.5, P, 0.5);
329 BRepAdaptor_CompCurve BC(mySpine);
332 BRepFill::SearchOrigin(TheGuide, SpOr, Dir, 100*myTol3d);
337 DBRep::Set("theguide", TheGuide);
339 // on transforme le guide en 1 seule courbe (periodic si posssible)
340 Handle(BRepAdaptor_HCompCurve) Guide =
341 new (BRepAdaptor_HCompCurve) (TheGuide);
342 Guide->ChangeCurve().SetPeriodic(Standard_True);
344 if (CurvilinearEquivalence) { // triedre par abscisse curviligne reduite
346 myTrihedron = GeomFill_IsGuideACWithContact; // avec rotation
348 myTrihedron = GeomFill_IsGuideAC; // sans rotation
350 Handle(GeomFill_GuideTrihedronAC) TLaw
351 = new (GeomFill_GuideTrihedronAC) (Guide);
352 Handle(GeomFill_LocationGuide) Loc =
353 new (GeomFill_LocationGuide) (TLaw);
354 myLocation = new (BRepFill_ACRLaw) (mySpine, Loc);
356 else {// triedre par plan
358 myTrihedron = GeomFill_IsGuidePlanWithContact; // avec rotation
360 myTrihedron = GeomFill_IsGuidePlan; // sans rotation
362 Handle(GeomFill_GuideTrihedronPlan) TLaw =
363 new (GeomFill_GuideTrihedronPlan) (Guide);
364 Handle(GeomFill_LocationGuide) Loc =
365 new (GeomFill_LocationGuide) (TLaw);
366 myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc);
368 mySection.Nullify(); //Il faut relocaliser les sections.
371 //=======================================================================
373 //purpose : Ajoute une Section
374 //=======================================================================
375 void BRepFill_PipeShell::Add(const TopoDS_Shape& Profile,
376 const Standard_Boolean WithContact,
377 const Standard_Boolean WithCorrection)
381 Add(Profile, V, WithContact, WithCorrection);
385 //=======================================================================
387 //purpose : Ajoute une Section
388 //=======================================================================
389 void BRepFill_PipeShell::Add(const TopoDS_Shape& Profile,
390 const TopoDS_Vertex& Location,
391 const Standard_Boolean WithContact,
392 const Standard_Boolean WithCorrection)
394 Delete(Profile); // Pas de duplication
395 BRepFill_Section S (Profile, Location, WithContact, WithCorrection);
401 //=======================================================================
403 //purpose : Section + Loi d'homothetie
404 //=======================================================================
405 void BRepFill_PipeShell::SetLaw(const TopoDS_Shape& Profile,
406 const Handle(Law_Function)& L,
407 const Standard_Boolean WithContact,
408 const Standard_Boolean WithCorrection)
412 SetLaw( Profile, L, V, WithContact, WithCorrection);
416 //=======================================================================
418 //purpose : Section + Loi d'homothetie
419 //=======================================================================
420 void BRepFill_PipeShell::SetLaw(const TopoDS_Shape& Profile,
421 const Handle(Law_Function)& L,
422 const TopoDS_Vertex& Location,
423 const Standard_Boolean WithContact,
424 const Standard_Boolean WithCorrection)
427 BRepFill_Section S (Profile, Location, WithContact, WithCorrection);
428 S.Set(Standard_True);
435 //=======================================================================
437 //purpose : Supprime une section
438 //=======================================================================
439 void BRepFill_PipeShell::Delete(const TopoDS_Shape& Profile)
441 Standard_Boolean isVertex = (Profile.ShapeType() == TopAbs_VERTEX);
443 Standard_Boolean Trouve=Standard_False;
445 for (ii=1; ii<=mySeq.Length() && !Trouve; ii++) {
446 Standard_Boolean found = Standard_False;
447 const TopoDS_Wire& aWire = mySeq.Value(ii).Wire();
450 TopExp_Explorer Explo(aWire, TopAbs_VERTEX);
451 for (; Explo.More(); Explo.Next())
452 if (Profile.IsSame(Explo.Current()))
453 found = Standard_True;
455 else if (Profile.IsSame(aWire))
456 found = Standard_True;
460 Trouve = Standard_True;
465 if (Trouve) mySection.Nullify();
470 //=======================================================================
473 //=======================================================================
474 Standard_Boolean BRepFill_PipeShell::IsReady() const
476 return (mySeq.Length() != 0);
478 //=======================================================================
479 //function : GetStatus
481 //=======================================================================
482 GeomFill_PipeError BRepFill_PipeShell::GetStatus() const
488 //=======================================================================
489 //function : SetTolerance
491 //=======================================================================
492 void BRepFill_PipeShell::SetTolerance(const Standard_Real Tol3d ,
493 const Standard_Real BoundTol,
494 const Standard_Real TolAngular)
497 myBoundTol = BoundTol;
498 myTolAngular = TolAngular;
501 //=======================================================================
502 //function : SetTransition
503 //purpose : Definit le mode de traitement des coins
504 //=======================================================================
505 void BRepFill_PipeShell::SetTransition(const BRepFill_TransitionStyle Mode,
506 const Standard_Real Angmin,
507 const Standard_Real Angmax)
509 if (myTransition != Mode)
510 mySection.Nullify(); //Il faut relocaliser les sections.
516 //=======================================================================
517 //function : Simulate
518 //purpose : Calcul N Sections
519 //=======================================================================
520 void BRepFill_PipeShell::Simulate(const Standard_Integer N,
521 TopTools_ListOfShape& List)
527 Standard_Real First, Last, Length, Delta, U,
529 Standard_Integer ii, NbL = myLocation->NbLaw();
530 Standard_Boolean Finis=Standard_False;
533 // Calcul des parametres de digitalisation
534 mySection->Law(1)->GetDomain(FirstS, Last);
535 DeltaS = Last - FirstS;
536 myLocation->CurvilinearBounds(NbL,First, Length);
538 if (N>1) Delta /= (N-1);
540 myLocation->CurvilinearBounds(1,First, Last); // Init de Last
541 for (U=0.0, ii=1; !Finis ; U+=Delta) {
544 Finis = Standard_True;
547 if (ii < NbL) myLocation->CurvilinearBounds(NbL,First, Last);
548 if (U > Last) U = (Last+First)/2; // On ne saute pas une arete
551 US = FirstS + (U/Length)*DeltaS;
552 // Calcul d'une section
553 mySection->D0(US, W);
554 myLocation->D0(U, W);
559 //=======================================================================
561 //purpose : Construit le Shell et l'historique
562 //=======================================================================
563 Standard_Boolean BRepFill_PipeShell::Build()
566 Standard_Real FirstS, LastS;
570 if (myStatus != GeomFill_PipeOk) {
574 myShape = Sh; // Nullify
575 return Standard_False;
578 // 2) Calcul de myFirst et myLast
579 mySection->Law(1)->GetDomain(FirstS, LastS);
580 mySection->D0(FirstS, myFirst);
581 myLocation->D0(0, myFirst);
582 if (mySection->IsVClosed() && myLocation->IsClosed()) {
583 if (myLocation->IsG1(0)>=0)
591 Standard_Real Length;
592 myLocation->CurvilinearBounds(myLocation->NbLaw(),
594 mySection->D0(LastS, myLast);
595 myLocation->D0(Length, myLast);
596 // eap 5 Jun 2002 occ332, myLast and myFirst must not share one TShape,
597 // tolerances of shapes built on them may be quite different
598 if (myFirst.IsPartner( myLast )) {
599 BRepBuilderAPI_Copy copy(myLast);
601 myLast = copy.Shape();
603 // eap 5 Jun 2002 occ332, end modif
607 DBRep::Set("PipeFirst", myFirst);
608 DBRep::Set("PipeLast", myLast);
613 BRepFill_Sweep MkSw(mySection, myLocation, Standard_True);
614 MkSw.SetTolerance(myTol3d, myBoundTol, 1.e-5, myTolAngular);
615 MkSw.SetAngularControl(angmin, angmax);
616 MkSw.SetBounds(TopoDS::Wire(myFirst),
617 TopoDS::Wire(myLast));
618 MkSw.Build(myTransition);
620 myStatus = myLocation->GetStatus();
621 Ok = (MkSw.IsDone() && (myStatus == GeomFill_PipeOk));
624 myShape = MkSw.Shape();
626 TopoDS_Shape aBottomWire = myFirst;
627 TopoDS_Shape aTopWire = myLast;
629 if(BuildBoundaries(MkSw, mySection, aBottomWire, aTopWire)) {
630 myFirst = aBottomWire;
634 if (mySection->IsUClosed())
636 TopExp_Explorer explo;
637 Standard_Boolean DegenFirst = Standard_True, DegenLast = Standard_True;
639 for (explo.Init(myFirst, TopAbs_EDGE); explo.More(); explo.Next())
641 const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
642 DegenFirst = DegenFirst && BRep_Tool::Degenerated(anEdge);
645 for (explo.Init(myLast, TopAbs_EDGE); explo.More(); explo.Next())
647 const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
648 DegenLast = DegenLast && BRep_Tool::Degenerated(anEdge);
651 if (DegenFirst && DegenLast)
652 myShape.Closed(Standard_True);
661 myShape = Sh; // Nullify
662 if (myStatus == GeomFill_PipeOk) myStatus = GeomFill_PipeNotOk;
667 //=======================================================================
668 //function : MakeSolid
670 //=======================================================================
671 Standard_Boolean BRepFill_PipeShell::MakeSolid()
673 if (myShape.IsNull())
674 StdFail_NotDone::Raise("PipeShell is not build");
675 Standard_Boolean B = myShape.Closed();
680 if(!myFirst.IsNull() && !myLast.IsNull()) {
681 B = (myFirst.Closed() && myLast.Closed());
684 // Il faut boucher les extremites
685 B = PerformPlan(myFirst);
687 B = PerformPlan(myLast);
689 if (!myFirst.IsNull() && !IsSameOriented( myFirst, myShape ))
691 if (!myLast.IsNull() && !IsSameOriented( myLast, myShape ))
694 if (!myFirst.IsNull())
695 BS.Add(myShape, TopoDS::Face(myFirst));
696 if (!myLast.IsNull())
697 BS.Add(myShape, TopoDS::Face(myLast));
699 myShape.Closed(Standard_True);
708 BS.Add(solid,TopoDS::Shell(myShape));
709 BRepClass3d_SolidClassifier SC(solid);
710 SC.PerformInfinitePoint(Precision::Confusion());
711 if ( SC.State() == TopAbs_IN) {
714 BS.Add(solid,TopoDS::Shell(myShape));
717 myShape.Closed(Standard_True);
722 //=======================================================================
724 //purpose : Renvoi le resultat
725 //=======================================================================
726 const TopoDS_Shape& BRepFill_PipeShell::Shape() const
731 //=======================================================================
732 //function : FirstShape
733 //purpose : Renvoi la section du debut
734 //=======================================================================
735 const TopoDS_Shape& BRepFill_PipeShell::FirstShape() const
740 //=======================================================================
741 //function : LastShape
742 //purpose : Renvoi la section de fin
743 //=======================================================================
744 const TopoDS_Shape& BRepFill_PipeShell::LastShape() const
749 //=======================================================================
750 //function : Generated
752 //=======================================================================
753 // void BRepFill_PipeShell::Generated(const TopoDS_Shape& ,
754 // TopTools_ListOfShape& )
755 void BRepFill_PipeShell::Generated(const TopoDS_Shape& theShape,
756 TopTools_ListOfShape& theList)
758 // Standard_NotImplemented::Raise("Generated:Pas Fait");
761 if(myGenMap.IsBound(theShape)) {
762 theList = myGenMap.Find(theShape);
766 //=======================================================================
768 //purpose : - Verifie que tout est pret
769 // - Construit la loi de section
770 // - Construit la loi de location si necessaire
771 // - Calcul First & Last
772 //=======================================================================
773 void BRepFill_PipeShell::Prepare()
776 if (!IsReady()) StdFail_NotDone::Raise("PipeShell");
777 if (!myLocation.IsNull() && !mySection.IsNull()) return; // C'est deja pret
779 //Check set of section for right configuration of punctual sections
781 TopoDS_Iterator iter;;
782 for (i = 2; i <= mySeq.Length()-1; i++)
784 Standard_Boolean wdeg = Standard_True;
785 for (iter.Initialize(mySeq(i).Wire()); iter.More(); iter.Next())
787 const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value());
788 wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
791 Standard_Failure::Raise("Wrong usage of punctual sections");
793 if (mySeq.Length() <= 2)
795 Standard_Boolean wdeg = Standard_True;
796 for (i = 1; i <= mySeq.Length(); i++)
797 for (iter.Initialize(mySeq(i).Wire()); iter.More(); iter.Next())
799 const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value());
800 wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
803 Standard_Failure::Raise("Wrong usage of punctual sections");
806 // Construction de la loi de location
807 if(myLocation.IsNull())
811 case GeomFill_IsCorrectedFrenet :
813 Handle(GeomFill_TrihedronLaw) TLaw =
814 new (GeomFill_CorrectedFrenet) ();
815 Handle(GeomFill_CurveAndTrihedron) Loc =
816 new (GeomFill_CurveAndTrihedron) (TLaw);
817 myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc);
822 Standard_ConstructionError::Raise("PipeShell");
827 //Transformation de la loi (Gestion Transition)
828 PerformTransition(myTransition, myLocation, angmin);
831 // Construction de la loi de section
832 if (mySeq.Length() == 1) {
834 Place(mySeq(1), theSect,p1);
835 TopoDS_Wire aLocalShape = theSect;
836 if (mySeq(1).IsLaw())
837 mySection = new BRepFill_ShapeLaw(aLocalShape, myLaw);
838 // mySection = new (BRepFill_ShapeLaw) (TopoDS_Wire(theSect), myLaw);
840 mySection = new BRepFill_ShapeLaw(aLocalShape);
841 // mySection = new (BRepFill_ShapeLaw) (TopoDS::Wire(theSect));
845 TColStd_SequenceOfReal Param;
846 TopTools_SequenceOfShape WSeq;
849 Standard_Integer NbL = myLocation->NbLaw();
850 Standard_Real V1, V2, param;
851 myLocation->CurvilinearBounds(NbL, V1, V2);
853 Standard_Integer ideb = 0, ifin = 0;
854 // for (Standard_Integer iseq=1;iseq<=mySeq.Length();iseq++) {
855 Standard_Integer iseq;
856 for (iseq=1;iseq<=mySeq.Length();iseq++) {
857 Place(mySeq(iseq), theSect, param);
859 WSeq.Append(theSect);
860 // WSeq.Append(TopoDS::Wire(theSect));
861 if (param==V1) ideb = iseq;
862 if (param==V2) ifin = iseq;
866 // sections bouclantes ?
867 if (myLocation->IsClosed()) {
869 // on place la section initiale en position finale
871 WSeq.Append(WSeq(ideb));
874 // on place la section finale en position initiale
876 WSeq.Append(WSeq(ifin));
879 // il faut trouver une section moyenne a imposer en V1 et en V2
880 Standard_Real pmin = Param.Value(1), pmax = Param.Value(1);
881 TopoDS_Wire Wmin = TopoDS::Wire(WSeq.Value(1)), Wmax;
882 for (iseq=2;iseq<=WSeq.Length();iseq++) {
883 if (Param.Value(iseq)<pmin) {
884 pmin = Param.Value(iseq);
885 Wmin = TopoDS::Wire(WSeq.Value(iseq));
887 if (Param.Value(iseq)>pmax) {
888 pmax = Param.Value(iseq);
889 Wmax = TopoDS::Wire(WSeq.Value(iseq));
892 // section moyenne entre Wmin et Wmax
894 Standard_Real dmin = Abs(pmin-V1);
895 Standard_Real dmax = Abs(pmax-V2);
896 if (ComputeSection(Wmin,Wmax,dmin,dmax,Wres)) {
897 // on impose la section Wres au debut et a la fin
908 // tri des sections par parametre croissant
909 Standard_Boolean play_again = Standard_True;
911 play_again = Standard_False;
912 for (iseq=1;iseq<=WSeq.Length();iseq++) {
913 for (Standard_Integer jseq=iseq+1;jseq<=WSeq.Length();jseq++) {
914 if (Param.Value(iseq)>Param.Value(jseq)) {
915 Param.Exchange(iseq,jseq);
916 WSeq.Exchange(iseq,jseq);
917 play_again = Standard_True;
925 char* name = new char[100];
926 Standard_Integer NBSECT = 0;
927 for (Standard_Integer i=1;i<=WSeq.Length();i++) {
929 sprintf(name,"WSeq_%d",NBSECT);
930 DBRep::Set(name,TopoDS::Wire(WSeq.Value(i)));
937 // Calcul des sections de travail
938 TopTools_SequenceOfShape WorkingSections;
939 WorkingSections.Clear();
940 TopTools_DataMapOfShapeListOfShape WorkingMap;
942 BRepFill_CompatibleWires Georges(WSeq);
943 Georges.SetPercent(0.1);
944 Georges.Perform(Standard_False);
945 if (Georges.IsDone()) {
946 WorkingSections = Georges.Shape();
947 WorkingMap = Georges.Generated();
950 Standard_ConstructionError::Raise("PipeShell : uncompatible wires");
952 mySection = new (BRepFill_NSections) (WorkingSections,Param,V1,V2);
956 // on modifie la loi de location si contact
957 if ( (myTrihedron == GeomFill_IsGuidePlanWithContact)
958 || (myTrihedron == GeomFill_IsGuideACWithContact) ) {
959 Standard_Real fs, f, l, Delta, Length;
960 Handle(GeomFill_LocationGuide) Loc;
961 Handle(GeomFill_SectionLaw) Sec = mySection->ConcatenedLaw();
962 myLocation->CurvilinearBounds(myLocation->NbLaw(), f, Length);
963 Sec->GetDomain(fs,l);
964 Delta = (l-fs)/Length;
966 Standard_Real angle, old_angle = 0;
967 for (Standard_Integer ipath=1; ipath<=myLocation->NbLaw(); ipath++) {
968 myLocation->CurvilinearBounds(ipath, f, l);
969 Loc = Handle(GeomFill_LocationGuide)::DownCast(myLocation->Law(ipath));
970 Loc->Set(Sec, Standard_True, fs + f*Delta, fs + l*Delta,
971 old_angle, angle); // on force la rotation
976 myStatus = myLocation->GetStatus();
979 //=======================================================================
981 //purpose : Met en Place une Section dans le repere local
982 // et retourne son parametre sur la trajectoire
983 //=======================================================================
984 void BRepFill_PipeShell::Place(const BRepFill_Section& Sec,
986 Standard_Real& param)
988 BRepFill_SectionPlacement Place(myLocation,
992 Sec.WithCorrection());
994 TopLoc_Location Loc2(Place.Transformation()), Loc1;
996 W.Location(Loc2.Multiplied(Loc1));
997 param = Place.AbscissaOnPath();
1001 //=======================================================================
1002 //function : ResetLoc
1003 //purpose : Supprime les references aux sections dans les loi de location
1004 //=======================================================================
1005 void BRepFill_PipeShell::ResetLoc()
1007 if ( (myTrihedron == GeomFill_IsGuidePlanWithContact)
1008 || (myTrihedron == GeomFill_IsGuideACWithContact) ) {
1009 Handle(GeomFill_LocationGuide) Loc;
1010 for (Standard_Integer isec=1; isec<=myLocation->NbLaw(); isec++) {
1011 Loc = Handle(GeomFill_LocationGuide)::DownCast(myLocation->Law(isec));
1012 Loc->EraseRotation();// on supprime la rotation
1017 //=======================================================================
1018 //function : BuildHistory
1019 //purpose : Builds history for edges of spine,
1020 // for built bottom shape of sweep,
1021 // for boundary vertices of bottom shape of sweep,
1022 // for boundary profiles
1023 //=======================================================================
1024 void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep)
1026 Handle(TopTools_HArray2OfShape) aFaces = theSweep.SubShape();
1027 Handle(TopTools_HArray2OfShape) aVEdges = theSweep.Sections();
1028 Handle(TopTools_HArray2OfShape) aUEdges = theSweep.InterFaces();
1029 Standard_Integer i = 0, j = 0;
1030 Standard_Boolean bPrevModified = Standard_False;
1032 for(i = 1; i <= mySection->NbLaw(); i++) {
1033 if((!aVEdges->Value(i, 1).IsNull()) && (aVEdges->Value(i, 1).ShapeType() == TopAbs_FACE)) {
1034 bPrevModified = Standard_True;
1039 for(j = myLocation->NbLaw(); j >= 1; j--) {
1040 Standard_Boolean ismodified = Standard_False;
1041 TopTools_ListOfShape aListOfFace;
1044 for(i = 1; i <= mySection->NbLaw(); i++) {
1045 Standard_Integer lessindex = j + 1;
1046 lessindex = (lessindex > myLocation->NbLaw()) ? 1 : lessindex;
1048 if((!aVEdges->Value(i, lessindex).IsNull()) && (aVEdges->Value(i, lessindex).ShapeType() == TopAbs_FACE)) {
1049 aListOfFace.Append(aVEdges->Value(i, lessindex));
1050 const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, 1);
1052 if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) {
1053 UpdateMap(aBottomEdge, aVEdges->Value(i, lessindex), myGenMap);
1058 bPrevModified = Standard_False;
1060 for(i = 1; i <= mySection->NbLaw(); i++) {
1061 if((!aVEdges->Value(i, j).IsNull()) && (aVEdges->Value(i, j).ShapeType() == TopAbs_FACE)) {
1062 aListOfFace.Append(aVEdges->Value(i, j));
1063 bPrevModified = Standard_True;
1065 const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, 1);
1067 if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) {
1068 UpdateMap(aBottomEdge, aVEdges->Value(i, j), myGenMap);
1072 if(aFaces->Value(i, j).ShapeType() == TopAbs_FACE) {
1073 aListOfFace.Append(aFaces->Value(i, j));
1074 const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, 1);
1076 if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) {
1077 UpdateMap(aBottomEdge, aFaces->Value(i, j), myGenMap);
1082 if(!myGenMap.IsBound(myLocation->Edge(j)))
1083 myGenMap.Bind(myLocation->Edge(j), aListOfFace);
1085 myGenMap.ChangeFind(myLocation->Edge(j)).Append(aListOfFace);
1087 // build history for free booundaries.begin
1088 if(!mySection->IsUClosed()) {
1089 TopoDS_Compound aFaceComp;
1091 aB.MakeCompound(aFaceComp);
1092 TopTools_ListIteratorOfListOfShape anIt(aListOfFace);
1094 for(; anIt.More(); anIt.Next()) {
1095 aB.Add(aFaceComp, anIt.Value());
1097 TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
1098 TopExp::MapShapesAndAncestors(aFaceComp, TopAbs_EDGE, TopAbs_FACE, aMapEF);
1099 Standard_Integer eit = 0;
1101 for(eit = aUEdges->LowerRow(); eit <= aUEdges->UpperRow(); eit++) {
1102 const TopoDS_Shape& aShape = aUEdges->Value(eit, j);
1104 if(aMapEF.Contains(aShape)) {
1105 const TopTools_ListOfShape& aList = aMapEF.FindFromKey(aShape);
1107 if(aList.Extent() < 2) {
1108 UpdateMap(myLocation->Edge(j), aShape, myGenMap);
1110 TopoDS_Shape aGenVertex;
1111 TopTools_IndexedDataMapOfShapeListOfShape aMapVE;
1113 for(i = 1; i <= mySection->NbLaw(); i++) {
1114 const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, aVEdges->LowerCol());
1116 if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) {
1117 TopExp::MapShapesAndAncestors(aBottomEdge, TopAbs_VERTEX, TopAbs_EDGE, aMapVE);
1120 const TopoDS_Shape& aFreeEdge = aUEdges->Value(eit, aUEdges->LowerCol());
1121 TopExp::MapShapesAndAncestors(aFreeEdge, TopAbs_VERTEX, TopAbs_EDGE, aMapVE);
1122 TopExp_Explorer anExpV(aFreeEdge, TopAbs_VERTEX);
1124 for(; anExpV.More(); anExpV.Next()) {
1125 if(aMapVE.Contains(anExpV.Current())) {
1126 const TopTools_ListOfShape& aListOfV = aMapVE.FindFromKey(anExpV.Current());
1128 if(aListOfV.Extent() >= 2) {
1129 aGenVertex = anExpV.Current();
1134 if(!aGenVertex.IsNull()) {
1135 UpdateMap(aGenVertex, aShape, myGenMap);
1140 // end for(eit = aUEdges->LowerRow...
1142 // build history for free booundaries.end
1145 // build history for boundary section wires. begin
1147 if(!mySeq.IsEmpty()) {
1148 Standard_Integer iseq;
1150 Standard_Real param = 0., aparmin = RealLast(), aparmax = -RealLast();
1151 Standard_Integer ideb = 1, ifin = mySeq.Length();
1153 for (iseq = 1;iseq <= mySeq.Length(); iseq++) {
1154 Place(mySeq(iseq), aSect, param);
1156 if(param < aparmin) {
1161 if(param > aparmax) {
1167 UpdateMap(mySeq(ideb).Wire(), myFirst, myGenMap);
1168 UpdateMap(mySeq(ifin).Wire(), myLast, myGenMap);
1170 // build history for boundary section wires. end
1173 // ---------------------------------------------------------------------------------
1174 // static function: UpdateMap
1176 // ---------------------------------------------------------------------------------
1177 Standard_Boolean UpdateMap(const TopoDS_Shape& theKey,
1178 const TopoDS_Shape& theValue,
1179 TopTools_DataMapOfShapeListOfShape& theMap) {
1181 if(!theMap.IsBound(theKey)) {
1182 TopTools_ListOfShape thelist;
1183 theMap.Bind(theKey, thelist);
1185 TopTools_ListOfShape& aList = theMap.ChangeFind(theKey);
1186 TopTools_ListIteratorOfListOfShape anIt(aList);
1187 Standard_Boolean found = Standard_False;
1189 for(; anIt.More(); anIt.Next()) {
1190 if(theValue.IsSame(anIt.Value())) {
1191 found = Standard_True;
1197 aList.Append(theValue);
1201 // ---------------------------------------------------------------------------------
1202 // static function: BuildBoundaries
1204 // ---------------------------------------------------------------------------------
1205 Standard_Boolean BuildBoundaries(const BRepFill_Sweep& theSweep,
1206 const Handle(BRepFill_SectionLaw)& theSection,
1207 TopoDS_Shape& theBottom,
1208 TopoDS_Shape& theTop) {
1210 TopoDS_Wire aBottomWire;
1211 TopoDS_Wire aTopWire;
1213 aB.MakeWire(aBottomWire);
1214 aB.MakeWire(aTopWire);
1215 Standard_Boolean bfoundbottom = Standard_False;
1216 Standard_Boolean bfoundtop = Standard_False;
1217 Handle(TopTools_HArray2OfShape) aVEdges = theSweep.Sections();
1218 Standard_Integer i = 0;
1219 Standard_Boolean bAllSame = Standard_True;
1221 for(i = 1; i <= theSection->NbLaw(); i++) {
1222 const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, aVEdges->LowerCol());
1224 if(!aBottomEdge.IsNull() && (aBottomEdge.ShapeType() == TopAbs_EDGE)) {
1225 aB.Add(aBottomWire, aBottomEdge);
1226 bfoundbottom = Standard_True;
1228 const TopoDS_Shape& aTopEdge = aVEdges->Value(i, aVEdges->UpperCol());
1230 if(!aTopEdge.IsNull() && (aTopEdge.ShapeType() == TopAbs_EDGE)) {
1231 aB.Add(aTopWire, aTopEdge);
1232 bfoundtop = Standard_True;
1235 if(!aBottomEdge.IsNull() && !aTopEdge.IsNull() && !aBottomEdge.IsSame(aTopEdge))
1236 bAllSame = Standard_False;
1239 if(theSection->IsUClosed()) {
1240 aBottomWire.Closed(Standard_True);
1241 aTopWire.Closed(Standard_True);
1245 theBottom = aBottomWire;
1252 if(bAllSame && bfoundbottom && bfoundtop)
1255 return bfoundbottom || bfoundtop;