0022627: Change OCCT memory management defaults
[occt.git] / src / BRepFill / BRepFill_PipeShell.cxx
CommitLineData
7fd59977 1// File: BRepFill_PipeShell.cxx
2// Created: Wed Jul 22 10:52:44 1998
3// Author: Philippe MANGIN
4// <pmn@sgi29>
5
6#include <stdio.h>
7
8#include <BRepFill_PipeShell.ixx>
9
10#include <BRep_Builder.hxx>
11#include <BRep_Tool.hxx>
12#include <TopExp.hxx>
13#include <TopTools_SequenceOfShape.hxx>
14#include <TopoDS.hxx>
15#include <TopoDS_Shell.hxx>
16#include <TopoDS_Solid.hxx>
17#include <TopoDS_Iterator.hxx>
18#include <TopLoc_Location.hxx>
19
20#include <BRepLib_MakeEdge.hxx>
21#include <BRepLib_MakeFace.hxx>
22#include <BRepAdaptor_HCompCurve.hxx>
23#include <BRepClass3d_SolidClassifier.hxx>
24
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>
35
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>
46
0d969553 47//Specification Guide
7fd59977 48#include <GeomAdaptor_HCurve.hxx>
49
50#include <gp_Trsf.hxx>
51#include <gp_Dir.hxx>
52#include <gp_Vec.hxx>
53#include <Precision.hxx>
54
55#include <Standard_NotImplemented.hxx>
56#include <Standard_ConstructionError.hxx>
57#include <StdFail_NotDone.hxx>
58
59#include <BRepBuilderAPI_Copy.hxx>
60
61#ifdef DRAW
62#include <Draw.hxx>
63#include <DrawTrSurf.hxx>
64#include <DBRep.hxx>
65static Standard_Boolean Affich = 0;
66#endif
67
68#include <TopTools_ListIteratorOfListOfShape.hxx>
69#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
70#include <TopoDS_Compound.hxx>
71
72static Standard_Boolean UpdateMap(const TopoDS_Shape& theKey,
73 const TopoDS_Shape& theValue,
74 TopTools_DataMapOfShapeListOfShape& theMap);
75
76static Standard_Boolean BuildBoundaries(const BRepFill_Sweep& theSweep,
77 const Handle(BRepFill_SectionLaw)& theSection,
78 TopoDS_Shape& theBottom,
79 TopoDS_Shape& theTop);
80
81//=======================================================================
82//function : ComputeSection
0d969553 83//purpose : Construct an intermediary section
7fd59977 84//=======================================================================
85
86static Standard_Boolean ComputeSection(const TopoDS_Wire& W1,
87 const TopoDS_Wire& W2,
88 const Standard_Real p1,
89 const Standard_Real p2,
90 TopoDS_Wire& Wres)
91{
92 TColStd_SequenceOfReal SR;
93 TopTools_SequenceOfShape SSh;
94 SR.Clear();
95 SR.Append(0.);
96 SR.Append(1.);
97 SSh.Clear();
98 SSh.Append(W1);
99 SSh.Append(W2);
100 BRepFill_CompatibleWires CW(SSh);
101 CW.SetPercent(0.1);
102 CW.Perform();
103 if (!CW.IsDone()) StdFail_NotDone::Raise("Uncompatible wires");
d7325741
J
104 GeomFill_SequenceOfTrsf EmptyTrsfs;
105 Handle(BRepFill_NSections) SL = new (BRepFill_NSections) (CW.Shape(),EmptyTrsfs,SR,0.,1.);
7fd59977 106 Standard_Real US = p1/(p1+p2);
107 SL->D0(US, Wres);
108 return Standard_True;
109}
110
111
112
113//=======================================================================
114//function : PerformTransition
0d969553 115//purpose : Modify a law of location depending on Transition
7fd59977 116//=======================================================================
117
118static void PerformTransition(const BRepFill_TransitionStyle Mode,
119 Handle(BRepFill_LocationLaw)& Loc,
120 const Standard_Real angmin)
121{
122 if (!Loc.IsNull()) {
123 Loc->DeleteTransform();
124 if (Mode == BRepFill_Modified) Loc->TransformInG0Law();
125 else Loc->TransformInCompatibleLaw(angmin);
126 }
127}
128//=======================================================================
129//function : PerformPlan
0d969553 130//purpose : Construct a plane of filling if exists
7fd59977 131//=======================================================================
132
133static Standard_Boolean PerformPlan(TopoDS_Shape& S)
134{
135 Standard_Boolean isDegen = Standard_True;
136 TopExp_Explorer explo(S, TopAbs_EDGE);
137 for (; explo.More(); explo.Next())
138 {
139 const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
140 if (!BRep_Tool::Degenerated(anEdge))
141 isDegen = Standard_False;
142 }
143 if (isDegen)
144 {
145 S.Nullify();
146 return Standard_True;
147 }
148
149 TopoDS_Wire W = TopoDS::Wire(S);
150 Standard_Boolean Ok = Standard_False;
151 if (!W.IsNull()) {
152 BRepLib_MakeFace mkplan(W, Standard_True);
153 if (mkplan.IsDone()) {
154 S = mkplan.Face();
155 Ok = Standard_True;
156 }
157 }
158 return Ok;
159}
160
161//=============================================================================
162//function : IsSameOriented
163//purpose : Checks whether aFace is oriented to the same side as aShell or not
164//=============================================================================
165
166static Standard_Boolean IsSameOriented(const TopoDS_Shape& aFace,
167 const TopoDS_Shape& aShell)
168{
169 TopExp_Explorer Explo(aFace, TopAbs_EDGE);
170 TopoDS_Shape anEdge = Explo.Current();
171 TopAbs_Orientation Or1 = anEdge.Orientation();
172
173 TopTools_IndexedDataMapOfShapeListOfShape EFmap;
174 TopExp::MapShapesAndAncestors( aShell, TopAbs_EDGE, TopAbs_FACE, EFmap );
175
176 const TopoDS_Shape& AdjacentFace = EFmap.FindFromKey(anEdge).First();
177 TopoDS_Shape theEdge;
178 for (Explo.Init(AdjacentFace, TopAbs_EDGE); Explo.More(); Explo.Next())
179 {
180 theEdge = Explo.Current();
181 if (theEdge.IsSame(anEdge))
182 break;
183 }
184
185 TopAbs_Orientation Or2 = theEdge.Orientation();
186 if (Or1 == Or2)
187 return Standard_False;
188 return Standard_True;
189}
190//=======================================================================
191//function : BRepFill_PipeShell
192//purpose :
193//=======================================================================
194BRepFill_PipeShell::BRepFill_PipeShell(const TopoDS_Wire& Spine)
195 : mySpine(Spine),
196 myTrihedron(GeomFill_IsCorrectedFrenet),
197 myTransition(BRepFill_Modified),
198 myStatus(GeomFill_PipeOk)
199{
200 myLocation.Nullify();
201 mySection.Nullify();
202 myLaw.Nullify();
203 SetTolerance();
204
0d969553 205 // Attention to closed non-declared wire !
7fd59977 206 if (!mySpine.Closed()) {
207 TopoDS_Vertex Vf, Vl;
208 TopExp::Vertices(mySpine, Vf, Vl);
209 if (Vf.IsSame(Vl)) mySpine.Closed(Standard_True);
210 }
211}
212
213//=======================================================================
214//function : Set
0d969553 215//purpose : Define a law of Frenet (Correct)
7fd59977 216//=======================================================================
217 void BRepFill_PipeShell::Set(const Standard_Boolean IsFrenet)
218{
219 Handle(GeomFill_TrihedronLaw) TLaw;
220 if (IsFrenet) {
221 myTrihedron = GeomFill_IsFrenet;
222 TLaw = new (GeomFill_Frenet) ();
223 }
224 else {
225 myTrihedron = GeomFill_IsFrenet;
226 TLaw = new (GeomFill_CorrectedFrenet) ();
227 }
228 Handle(GeomFill_CurveAndTrihedron) Loc =
229 new (GeomFill_CurveAndTrihedron) (TLaw);
230 myLocation = new (BRepFill_Edge3DLaw) (mySpine, Loc);
0d969553 231 mySection.Nullify(); //It is required to relocalize sections.
7fd59977 232}
233
234//=======================================================================
235//function : Set
0d969553 236//purpose : Define a law Constant
7fd59977 237//=======================================================================
238 void BRepFill_PipeShell::Set(const gp_Ax2& Axe)
239{
240 myTrihedron = GeomFill_IsFixed;
241 gp_Vec V1, V2;
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);
0d969553 248 mySection.Nullify(); //It is required to relocalize sections.
7fd59977 249}
250
251//=======================================================================
252//function : Set
0d969553 253//purpose : Construct a law of location of binormal fixed type
7fd59977 254//=======================================================================
255 void BRepFill_PipeShell::Set(const gp_Dir& BiNormal)
256{
257 myTrihedron = GeomFill_IsConstantNormal;
258
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.
265}
266
267//=======================================================================
268//function : Set
0d969553 269//purpose : Construct a law of location of Darboux type
7fd59977 270//=======================================================================
271 Standard_Boolean BRepFill_PipeShell::Set(const TopoDS_Shape& SpineSupport)
272{
273 Standard_Boolean B;
274
0d969553 275 // A special law of location is required
7fd59977 276 Handle(BRepFill_EdgeOnSurfLaw) loc =
277 new (BRepFill_EdgeOnSurfLaw) (mySpine, SpineSupport);
278 B = loc->HasResult();
279 if (B) {
280 myLocation = loc;
281 myTrihedron = GeomFill_IsDarboux;
0d969553 282 mySection.Nullify(); //It is required to relocalize the sections.
7fd59977 283 }
284 return B;
285}
286
287//=======================================================================
288//function : Set
0d969553 289//purpose : Defines a lawv with help of a guided contour
7fd59977 290//=======================================================================
291 void BRepFill_PipeShell::Set(const TopoDS_Wire& AuxiliarySpine,
292 const Standard_Boolean CurvilinearEquivalence,
293 const Standard_Boolean KeepContact)
294{
0d969553 295 // Reorganization of the guide (pb of orientation and origin)
7fd59977 296 TopoDS_Wire TheGuide;
297 TheGuide = AuxiliarySpine;
298 Standard_Boolean SpClose = mySpine.Closed(),
299 GuideClose = AuxiliarySpine.Closed();
300
301 if (!SpClose && !GuideClose) {
0d969553 302 // Case open reorientation of the guide
7fd59977 303 TopoDS_Wire sp = mySpine;
304 TopTools_SequenceOfShape Seq;
305 Seq.Append(sp);
306 Seq.Append(TheGuide);
307 BRepFill_CompatibleWires CW(Seq);
308 CW.SetPercent(0.1);
309 CW.Perform();
310 if (!CW.IsDone()) StdFail_NotDone::Raise("Uncompatible wires");
311 TheGuide = TopoDS::Wire(CW.Shape().Value(2));
312 }
313 else if (GuideClose) {
0d969553
Y
314 // Case guide closed : Determination of the origin
315 // & reorientation of the guide
7fd59977 316 gp_Vec Dir;
317 gp_Pnt SpOr;
318 if (!SpClose) {
319 TopoDS_Vertex Vf, Vl;
320 gp_Pnt P;
321 TopExp::Vertices(mySpine, Vf, Vl);
322 SpOr = BRep_Tool::Pnt(Vf);
323 P = BRep_Tool::Pnt(Vl);
324 gp_Vec V(P, SpOr);
325 SpOr.BaryCenter(0.5, P, 0.5);
326 Dir = V;
327 }
328 else {
329 BRepAdaptor_CompCurve BC(mySpine);
330 BC.D1(0,SpOr,Dir);
331 }
332 BRepFill::SearchOrigin(TheGuide, SpOr, Dir, 100*myTol3d);
333 }
334
335#ifdef DRAW
336 if (Affich)
337 DBRep::Set("theguide", TheGuide);
338#endif
0d969553 339 // transform the guide in a single curve (periodic if posssible)
7fd59977 340 Handle(BRepAdaptor_HCompCurve) Guide =
341 new (BRepAdaptor_HCompCurve) (TheGuide);
342 Guide->ChangeCurve().SetPeriodic(Standard_True);
343
0d969553 344 if (CurvilinearEquivalence) { // trihedron by curvilinear reduced abscissa
7fd59977 345 if (KeepContact)
0d969553 346 myTrihedron = GeomFill_IsGuideACWithContact; // with rotation
7fd59977 347 else
0d969553 348 myTrihedron = GeomFill_IsGuideAC; // without rotation
7fd59977 349
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);
355 }
0d969553 356 else {// trihedron by plane
7fd59977 357 if (KeepContact)
0d969553 358 myTrihedron = GeomFill_IsGuidePlanWithContact; // with rotation
7fd59977 359 else
0d969553 360 myTrihedron = GeomFill_IsGuidePlan; // without rotation
7fd59977 361
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);
367 }
0d969553 368 mySection.Nullify(); //It is required to relocalize the sections.
7fd59977 369}
370
371//=======================================================================
372//function : Add
0d969553 373//purpose : Add a Section
7fd59977 374//=======================================================================
375 void BRepFill_PipeShell::Add(const TopoDS_Shape& Profile,
376 const Standard_Boolean WithContact,
377 const Standard_Boolean WithCorrection)
378{
379 TopoDS_Vertex V;
380 V.Nullify();
381 Add(Profile, V, WithContact, WithCorrection);
382 ResetLoc();
383}
384
385//=======================================================================
386//function : Add
0d969553 387//purpose : Add a Section
7fd59977 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)
393{
0d969553 394 Delete(Profile); // No duplication
7fd59977 395 BRepFill_Section S (Profile, Location, WithContact, WithCorrection);
396 mySeq.Append(S);
397 mySection.Nullify();
398 ResetLoc();
399}
400
401//=======================================================================
402//function : SetLaw
0d969553 403//purpose : Section + law of homothety
7fd59977 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)
409{
410 TopoDS_Vertex V;
411 V.Nullify();
412 SetLaw( Profile, L, V, WithContact, WithCorrection);
413 ResetLoc();
414}
415
416//=======================================================================
417//function : SetLaw
0d969553 418//purpose : Section + Law of homothety
7fd59977 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)
425{
426 mySeq.Clear();
427 BRepFill_Section S (Profile, Location, WithContact, WithCorrection);
428 S.Set(Standard_True);
429 mySeq.Append(S);
430 myLaw = L;
431 mySection.Nullify();
432 ResetLoc();
433}
434
435//=======================================================================
436//function : Delete
0d969553 437//purpose : Delete a section
7fd59977 438//=======================================================================
439 void BRepFill_PipeShell::Delete(const TopoDS_Shape& Profile)
440{
441 Standard_Boolean isVertex = (Profile.ShapeType() == TopAbs_VERTEX);
442
443 Standard_Boolean Trouve=Standard_False;
444 Standard_Integer ii;
445 for (ii=1; ii<=mySeq.Length() && !Trouve; ii++) {
446 Standard_Boolean found = Standard_False;
447 const TopoDS_Wire& aWire = mySeq.Value(ii).Wire();
448 if (isVertex)
449 {
450 TopExp_Explorer Explo(aWire, TopAbs_VERTEX);
451 for (; Explo.More(); Explo.Next())
452 if (Profile.IsSame(Explo.Current()))
453 found = Standard_True;
454 }
455 else if (Profile.IsSame(aWire))
456 found = Standard_True;
457
458 if (found)
459 {
460 Trouve = Standard_True;
461 mySeq.Remove(ii);
462 }
463 }
464
465 if (Trouve) mySection.Nullify();
466 ResetLoc();
467}
468
469
470//=======================================================================
471//function : IsReady
472//purpose :
473//=======================================================================
474 Standard_Boolean BRepFill_PipeShell::IsReady() const
475{
476 return (mySeq.Length() != 0);
477}
478//=======================================================================
479//function : GetStatus
480//purpose :
481//=======================================================================
482 GeomFill_PipeError BRepFill_PipeShell::GetStatus() const
483{
484 return myStatus;
485}
486
487
488//=======================================================================
489//function : SetTolerance
490//purpose :
491//=======================================================================
492 void BRepFill_PipeShell::SetTolerance(const Standard_Real Tol3d ,
493 const Standard_Real BoundTol,
494 const Standard_Real TolAngular)
495{
496 myTol3d = Tol3d;
497 myBoundTol = BoundTol;
498 myTolAngular = TolAngular;
499}
500
501//=======================================================================
502//function : SetTransition
0d969553 503//purpose : Defines the mode of processing of corners
7fd59977 504//=======================================================================
505 void BRepFill_PipeShell::SetTransition(const BRepFill_TransitionStyle Mode,
506 const Standard_Real Angmin,
507 const Standard_Real Angmax)
508{
509 if (myTransition != Mode)
0d969553 510 mySection.Nullify(); //It is required to relocalize the sections.
7fd59977 511 myTransition = Mode;
512 angmin = Angmin;
513 angmax = Angmax;
514}
515
516//=======================================================================
517//function : Simulate
0d969553 518//purpose : Calculate N Sections
7fd59977 519//=======================================================================
520 void BRepFill_PipeShell::Simulate(const Standard_Integer N,
521 TopTools_ListOfShape& List)
522{
523 // Preparation
524 Prepare();
525 List.Clear();
526
527 Standard_Real First, Last, Length, Delta, U,
528 US, DeltaS,FirstS;
529 Standard_Integer ii, NbL = myLocation->NbLaw();
530 Standard_Boolean Finis=Standard_False;
531 TopoDS_Shape W;
532
0d969553 533 // Calculate the parameters of digitalization
7fd59977 534 mySection->Law(1)->GetDomain(FirstS, Last);
535 DeltaS = Last - FirstS;
536 myLocation->CurvilinearBounds(NbL,First, Length);
537 Delta = Length;
538 if (N>1) Delta /= (N-1);
539
0d969553 540 myLocation->CurvilinearBounds(1,First, Last); // Initiation of Last
7fd59977 541 for (U=0.0, ii=1; !Finis ; U+=Delta) {
542 if (U >= Length) {
543 U = Length;
544 Finis = Standard_True;
545 }
546 else {
547 if (ii < NbL) myLocation->CurvilinearBounds(NbL,First, Last);
0d969553 548 if (U > Last) U = (Last+First)/2; // The edge is not skipped
7fd59977 549 if (U> First) ii++;
550 }
551 US = FirstS + (U/Length)*DeltaS;
552 // Calcul d'une section
553 mySection->D0(US, W);
554 myLocation->D0(U, W);
555 List.Append(W);
556 }
557}
558
559//=======================================================================
560//function : Build
0d969553 561//purpose : Construct the Shell and the history
7fd59977 562//=======================================================================
563 Standard_Boolean BRepFill_PipeShell::Build()
564{
565 Standard_Boolean Ok;
566 Standard_Real FirstS, LastS;
567 // 1) Preparation
568 Prepare();
569
570 if (myStatus != GeomFill_PipeOk) {
571 BRep_Builder B;
572 TopoDS_Shell Sh;
573 B.MakeShell(Sh);
574 myShape = Sh; // Nullify
575 return Standard_False;
576 }
577
0d969553 578 // 2) Calculate myFirst and myLast
7fd59977 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)
584 myLast = myFirst;
585 else {
586 myFirst.Nullify();
587 myLast.Nullify();
588 }
589 }
590 else {
591 Standard_Real Length;
592 myLocation->CurvilinearBounds(myLocation->NbLaw(),
593 FirstS, Length);
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);
600 if (copy.IsDone())
601 myLast = copy.Shape();
602 }
603 // eap 5 Jun 2002 occ332, end modif
604 }
605#if DRAW
606 if (Affich) {
607 DBRep::Set("PipeFirst", myFirst);
608 DBRep::Set("PipeLast", myLast);
609 }
610#endif
611
612 // 3) Construction
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);
619
620 myStatus = myLocation->GetStatus();
621 Ok = (MkSw.IsDone() && (myStatus == GeomFill_PipeOk));
622
623 if (Ok) {
624 myShape = MkSw.Shape();
625
626 TopoDS_Shape aBottomWire = myFirst;
627 TopoDS_Shape aTopWire = myLast;
628
629 if(BuildBoundaries(MkSw, mySection, aBottomWire, aTopWire)) {
630 myFirst = aBottomWire;
631 myLast = aTopWire;
632 }
633
634 if (mySection->IsUClosed())
635 {
636 TopExp_Explorer explo;
637 Standard_Boolean DegenFirst = Standard_True, DegenLast = Standard_True;
638
639 for (explo.Init(myFirst, TopAbs_EDGE); explo.More(); explo.Next())
640 {
641 const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
642 DegenFirst = DegenFirst && BRep_Tool::Degenerated(anEdge);
643 }
644
645 for (explo.Init(myLast, TopAbs_EDGE); explo.More(); explo.Next())
646 {
647 const TopoDS_Edge& anEdge = TopoDS::Edge(explo.Current());
648 DegenLast = DegenLast && BRep_Tool::Degenerated(anEdge);
649 }
650
651 if (DegenFirst && DegenLast)
652 myShape.Closed(Standard_True);
653 }
654
655 BuildHistory(MkSw);
656 }
657 else {
658 BRep_Builder B;
659 TopoDS_Shell Sh;
660 B.MakeShell(Sh);
661 myShape = Sh; // Nullify
662 if (myStatus == GeomFill_PipeOk) myStatus = GeomFill_PipeNotOk;
663 }
664 return Ok;
665}
666
667//=======================================================================
668//function : MakeSolid
669//purpose :
670//=======================================================================
671 Standard_Boolean BRepFill_PipeShell::MakeSolid()
672{
673 if (myShape.IsNull())
0d969553 674 StdFail_NotDone::Raise("PipeShell is not built");
7fd59977 675 Standard_Boolean B = myShape.Closed();
676 BRep_Builder BS;
677
678 if (!B)
679 {
680 if(!myFirst.IsNull() && !myLast.IsNull()) {
681 B = (myFirst.Closed() && myLast.Closed());
682 }
683 if (B) {
0d969553 684 // It is necessary to block the extremities
7fd59977 685 B = PerformPlan(myFirst);
686 if (B) {
687 B = PerformPlan(myLast);
688 if (B) {
689 if (!myFirst.IsNull() && !IsSameOriented( myFirst, myShape ))
690 myFirst.Reverse();
691 if (!myLast.IsNull() && !IsSameOriented( myLast, myShape ))
692 myLast.Reverse();
693
694 if (!myFirst.IsNull())
695 BS.Add(myShape, TopoDS::Face(myFirst));
696 if (!myLast.IsNull())
697 BS.Add(myShape, TopoDS::Face(myLast));
698
699 myShape.Closed(Standard_True);
700 }
701 }
702 }
703 }
704
705 if (B) {
706 TopoDS_Solid solid;
707 BS.MakeSolid(solid);
708 BS.Add(solid,TopoDS::Shell(myShape));
709 BRepClass3d_SolidClassifier SC(solid);
710 SC.PerformInfinitePoint(Precision::Confusion());
711 if ( SC.State() == TopAbs_IN) {
712 BS.MakeSolid(solid);
713 myShape.Reverse();
714 BS.Add(solid,TopoDS::Shell(myShape));
715 }
716 myShape = solid;
717 myShape.Closed(Standard_True);
718 }
719 return B;
720}
721
722//=======================================================================
723//function : Shape
0d969553 724//purpose : Return the result
7fd59977 725//=======================================================================
726const TopoDS_Shape& BRepFill_PipeShell::Shape() const
727{
728 return myShape;
729}
730
731//=======================================================================
732//function : FirstShape
0d969553 733//purpose : Return the start section
7fd59977 734//=======================================================================
735const TopoDS_Shape& BRepFill_PipeShell::FirstShape() const
736{
737 return myFirst;
738}
739
740//=======================================================================
741//function : LastShape
0d969553 742//purpose : Return the end section
7fd59977 743//=======================================================================
744const TopoDS_Shape& BRepFill_PipeShell::LastShape() const
745{
746 return myLast;
747}
748
749//=======================================================================
750//function : Generated
751//purpose :
752//=======================================================================
753// void BRepFill_PipeShell::Generated(const TopoDS_Shape& ,
754// TopTools_ListOfShape& )
755void BRepFill_PipeShell::Generated(const TopoDS_Shape& theShape,
756 TopTools_ListOfShape& theList)
757{
758 // Standard_NotImplemented::Raise("Generated:Pas Fait");
759 theList.Clear();
760
761 if(myGenMap.IsBound(theShape)) {
762 theList = myGenMap.Find(theShape);
763 }
764}
765
766//=======================================================================
767//function : Prepare
0d969553
Y
768//purpose : - Check that everything is ready
769// - Construct the law of section
770// - Construct the law of location if required
771// - Calculate First & Last
7fd59977 772//=======================================================================
773 void BRepFill_PipeShell::Prepare()
774{
775 TopoDS_Wire theSect;
776 if (!IsReady()) StdFail_NotDone::Raise("PipeShell");
0d969553 777 if (!myLocation.IsNull() && !mySection.IsNull()) return; // It is ready
7fd59977 778
779 //Check set of section for right configuration of punctual sections
780 Standard_Integer i;
781 TopoDS_Iterator iter;;
782 for (i = 2; i <= mySeq.Length()-1; i++)
783 {
784 Standard_Boolean wdeg = Standard_True;
785 for (iter.Initialize(mySeq(i).Wire()); iter.More(); iter.Next())
786 {
787 const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value());
788 wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
789 }
790 if (wdeg)
791 Standard_Failure::Raise("Wrong usage of punctual sections");
792 }
793 if (mySeq.Length() <= 2)
794 {
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())
798 {
799 const TopoDS_Edge& anEdge = TopoDS::Edge(iter.Value());
800 wdeg = wdeg && (BRep_Tool::Degenerated(anEdge));
801 }
802 if (wdeg)
803 Standard_Failure::Raise("Wrong usage of punctual sections");
804 }
805
0d969553 806 // Construction of the law of location
7fd59977 807 if(myLocation.IsNull())
808 {
809 switch(myTrihedron)
810 {
811 case GeomFill_IsCorrectedFrenet :
812 {
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);
818 break;
819 }
820 default :
0d969553 821 { // Not planned!
7fd59977 822 Standard_ConstructionError::Raise("PipeShell");
823 }
824 }
825 }
826
0d969553 827 //Transformation of the law (Transition Management)
7fd59977 828 PerformTransition(myTransition, myLocation, angmin);
829
830
0d969553 831 // Construction of the section law
7fd59977 832 if (mySeq.Length() == 1) {
833 Standard_Real p1;
d7325741
J
834 gp_Trsf aTrsf;
835 Place(mySeq(1), theSect, aTrsf, p1);
7fd59977 836 TopoDS_Wire aLocalShape = theSect;
837 if (mySeq(1).IsLaw())
838 mySection = new BRepFill_ShapeLaw(aLocalShape, myLaw);
839// mySection = new (BRepFill_ShapeLaw) (TopoDS_Wire(theSect), myLaw);
840 else
841 mySection = new BRepFill_ShapeLaw(aLocalShape);
842// mySection = new (BRepFill_ShapeLaw) (TopoDS::Wire(theSect));
843 }
844 else
845 {
846 TColStd_SequenceOfReal Param;
847 TopTools_SequenceOfShape WSeq;
d7325741
J
848 GeomFill_SequenceOfTrsf Transformations;
849 //WSeq.Clear();
850 //Param.Clear();
7fd59977 851 Standard_Integer NbL = myLocation->NbLaw();
d7325741 852 gp_Trsf aTrsf;
7fd59977 853 Standard_Real V1, V2, param;
854 myLocation->CurvilinearBounds(NbL, V1, V2);
855 V1 = 0.;
856 Standard_Integer ideb = 0, ifin = 0;
857// for (Standard_Integer iseq=1;iseq<=mySeq.Length();iseq++) {
858 Standard_Integer iseq;
859 for (iseq=1;iseq<=mySeq.Length();iseq++) {
d7325741 860 Place(mySeq(iseq), theSect, aTrsf, param);
7fd59977 861 Param.Append(param);
862 WSeq.Append(theSect);
863// WSeq.Append(TopoDS::Wire(theSect));
d7325741 864 Transformations.Append(aTrsf);
7fd59977 865 if (param==V1) ideb = iseq;
866 if (param==V2) ifin = iseq;
867 }
868
869
0d969553 870 // looping sections ?
7fd59977 871 if (myLocation->IsClosed()) {
872 if (ideb>0) {
0d969553 873 // place the initial section at the final position
7fd59977 874 Param.Append(V2);
875 WSeq.Append(WSeq(ideb));
876 }
877 else if (ifin>0) {
0d969553 878 // place the final section at the initial position
7fd59977 879 Param.Append(V1);
880 WSeq.Append(WSeq(ifin));
881 }
882 else {
0d969553 883 // it is necessary to find a medium section to impose by V1 and by V2
7fd59977 884 Standard_Real pmin = Param.Value(1), pmax = Param.Value(1);
885 TopoDS_Wire Wmin = TopoDS::Wire(WSeq.Value(1)), Wmax;
886 for (iseq=2;iseq<=WSeq.Length();iseq++) {
887 if (Param.Value(iseq)<pmin) {
888 pmin = Param.Value(iseq);
889 Wmin = TopoDS::Wire(WSeq.Value(iseq));
890 }
891 if (Param.Value(iseq)>pmax) {
892 pmax = Param.Value(iseq);
893 Wmax = TopoDS::Wire(WSeq.Value(iseq));
894 }
895 }
0d969553 896 // medium section between Wmin and Wmax
7fd59977 897 TopoDS_Wire Wres;
898 Standard_Real dmin = Abs(pmin-V1);
899 Standard_Real dmax = Abs(pmax-V2);
900 if (ComputeSection(Wmin,Wmax,dmin,dmax,Wres)) {
0d969553 901 // impose section Wres at the beginning and the end
7fd59977 902 Param.Append(V1);
903 WSeq.Append(Wres);
904 Param.Append(V2);
905 WSeq.Append(Wres);
906
907 }
908
909 }
910 }
911
0d969553 912 // parse sections by increasing parameter
7fd59977 913 Standard_Boolean play_again = Standard_True;
914 while (play_again) {
915 play_again = Standard_False;
916 for (iseq=1;iseq<=WSeq.Length();iseq++) {
917 for (Standard_Integer jseq=iseq+1;jseq<=WSeq.Length();jseq++) {
918 if (Param.Value(iseq)>Param.Value(jseq)) {
919 Param.Exchange(iseq,jseq);
920 WSeq.Exchange(iseq,jseq);
921 play_again = Standard_True;
922 }
923 }
924 }
925 }
926
927#ifdef DRAW
928 if ( Affich) {
929 char* name = new char[100];
930 Standard_Integer NBSECT = 0;
931 for (Standard_Integer i=1;i<=WSeq.Length();i++) {
932 NBSECT++;
933 sprintf(name,"WSeq_%d",NBSECT);
934 DBRep::Set(name,TopoDS::Wire(WSeq.Value(i)));
935 }
936 }
937#endif
938
939
940
0d969553 941 // Calculate work sections
7fd59977 942 TopTools_SequenceOfShape WorkingSections;
943 WorkingSections.Clear();
944 TopTools_DataMapOfShapeListOfShape WorkingMap;
945 WorkingMap.Clear();
946 BRepFill_CompatibleWires Georges(WSeq);
947 Georges.SetPercent(0.1);
948 Georges.Perform(Standard_False);
949 if (Georges.IsDone()) {
950 WorkingSections = Georges.Shape();
951 WorkingMap = Georges.Generated();
952 }
953 else {
954 Standard_ConstructionError::Raise("PipeShell : uncompatible wires");
955 }
d7325741 956 mySection = new (BRepFill_NSections) (WorkingSections,Transformations,Param,V1,V2);
7fd59977 957
958 }// else
959
0d969553 960 // modify the law of location if contact
7fd59977 961 if ( (myTrihedron == GeomFill_IsGuidePlanWithContact)
962 || (myTrihedron == GeomFill_IsGuideACWithContact) ) {
963 Standard_Real fs, f, l, Delta, Length;
964 Handle(GeomFill_LocationGuide) Loc;
965 Handle(GeomFill_SectionLaw) Sec = mySection->ConcatenedLaw();
966 myLocation->CurvilinearBounds(myLocation->NbLaw(), f, Length);
967 Sec->GetDomain(fs,l);
968 Delta = (l-fs)/Length;
969
970 Standard_Real angle, old_angle = 0;
971 for (Standard_Integer ipath=1; ipath<=myLocation->NbLaw(); ipath++) {
972 myLocation->CurvilinearBounds(ipath, f, l);
973 Loc = Handle(GeomFill_LocationGuide)::DownCast(myLocation->Law(ipath));
974 Loc->Set(Sec, Standard_True, fs + f*Delta, fs + l*Delta,
0d969553 975 old_angle, angle); // force the rotation
7fd59977 976 old_angle = angle;
977 }
978 }
979
980 myStatus = myLocation->GetStatus();
981}
982
983//=======================================================================
984//function : Place
0d969553
Y
985//purpose : Implement a Section in the local refernce frame
986// and return its parameter on the trajectory
7fd59977 987//=======================================================================
988void BRepFill_PipeShell::Place(const BRepFill_Section& Sec,
989 TopoDS_Wire& W,
d7325741 990 gp_Trsf& aTrsf,
7fd59977 991 Standard_Real& param)
992{
993 BRepFill_SectionPlacement Place(myLocation,
994 Sec.Wire(),
995 Sec.Vertex(),
996 Sec.WithContact(),
997 Sec.WithCorrection());
998 W = Sec.Wire();
d7325741 999 aTrsf = Place.Transformation();
7fd59977 1000 TopLoc_Location Loc2(Place.Transformation()), Loc1;
1001 Loc1 = W.Location();
1002 W.Location(Loc2.Multiplied(Loc1));
1003 param = Place.AbscissaOnPath();
1004}
1005
1006
1007//=======================================================================
1008//function : ResetLoc
0d969553 1009//purpose : Remove references to the sections in the laws of location
7fd59977 1010//=======================================================================
1011 void BRepFill_PipeShell::ResetLoc()
1012{
1013 if ( (myTrihedron == GeomFill_IsGuidePlanWithContact)
1014 || (myTrihedron == GeomFill_IsGuideACWithContact) ) {
1015 Handle(GeomFill_LocationGuide) Loc;
1016 for (Standard_Integer isec=1; isec<=myLocation->NbLaw(); isec++) {
1017 Loc = Handle(GeomFill_LocationGuide)::DownCast(myLocation->Law(isec));
0d969553 1018 Loc->EraseRotation();// remove the rotation
7fd59977 1019 }
1020 }
1021}
1022
1023//=======================================================================
1024//function : BuildHistory
1025//purpose : Builds history for edges of spine,
1026// for built bottom shape of sweep,
1027// for boundary vertices of bottom shape of sweep,
1028// for boundary profiles
1029//=======================================================================
1030void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep)
1031{
1032 Handle(TopTools_HArray2OfShape) aFaces = theSweep.SubShape();
1033 Handle(TopTools_HArray2OfShape) aVEdges = theSweep.Sections();
1034 Handle(TopTools_HArray2OfShape) aUEdges = theSweep.InterFaces();
1035 Standard_Integer i = 0, j = 0;
1036 Standard_Boolean bPrevModified = Standard_False;
1037
1038 for(i = 1; i <= mySection->NbLaw(); i++) {
1039 if((!aVEdges->Value(i, 1).IsNull()) && (aVEdges->Value(i, 1).ShapeType() == TopAbs_FACE)) {
1040 bPrevModified = Standard_True;
1041 break;
1042 }
1043 }
1044
1045 for(j = myLocation->NbLaw(); j >= 1; j--) {
7fd59977 1046 TopTools_ListOfShape aListOfFace;
1047
1048 if(bPrevModified) {
1049 for(i = 1; i <= mySection->NbLaw(); i++) {
1050 Standard_Integer lessindex = j + 1;
1051 lessindex = (lessindex > myLocation->NbLaw()) ? 1 : lessindex;
1052
1053 if((!aVEdges->Value(i, lessindex).IsNull()) && (aVEdges->Value(i, lessindex).ShapeType() == TopAbs_FACE)) {
1054 aListOfFace.Append(aVEdges->Value(i, lessindex));
1055 const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, 1);
1056
1057 if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) {
1058 UpdateMap(aBottomEdge, aVEdges->Value(i, lessindex), myGenMap);
1059 }
1060 }
1061 }
1062 }
1063 bPrevModified = Standard_False;
1064
1065 for(i = 1; i <= mySection->NbLaw(); i++) {
1066 if((!aVEdges->Value(i, j).IsNull()) && (aVEdges->Value(i, j).ShapeType() == TopAbs_FACE)) {
1067 aListOfFace.Append(aVEdges->Value(i, j));
1068 bPrevModified = Standard_True;
1069
1070 const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, 1);
1071
1072 if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) {
1073 UpdateMap(aBottomEdge, aVEdges->Value(i, j), myGenMap);
1074 }
1075 }
1076
1077 if(aFaces->Value(i, j).ShapeType() == TopAbs_FACE) {
1078 aListOfFace.Append(aFaces->Value(i, j));
1079 const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, 1);
1080
1081 if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) {
1082 UpdateMap(aBottomEdge, aFaces->Value(i, j), myGenMap);
1083 }
1084 }
1085 }
1086
1087 if(!myGenMap.IsBound(myLocation->Edge(j)))
1088 myGenMap.Bind(myLocation->Edge(j), aListOfFace);
1089 else
1090 myGenMap.ChangeFind(myLocation->Edge(j)).Append(aListOfFace);
1091
1092 // build history for free booundaries.begin
1093 if(!mySection->IsUClosed()) {
1094 TopoDS_Compound aFaceComp;
1095 BRep_Builder aB;
1096 aB.MakeCompound(aFaceComp);
1097 TopTools_ListIteratorOfListOfShape anIt(aListOfFace);
1098
1099 for(; anIt.More(); anIt.Next()) {
1100 aB.Add(aFaceComp, anIt.Value());
1101 }
1102 TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
1103 TopExp::MapShapesAndAncestors(aFaceComp, TopAbs_EDGE, TopAbs_FACE, aMapEF);
1104 Standard_Integer eit = 0;
1105
1106 for(eit = aUEdges->LowerRow(); eit <= aUEdges->UpperRow(); eit++) {
1107 const TopoDS_Shape& aShape = aUEdges->Value(eit, j);
1108
1109 if(aMapEF.Contains(aShape)) {
1110 const TopTools_ListOfShape& aList = aMapEF.FindFromKey(aShape);
1111
1112 if(aList.Extent() < 2) {
1113 UpdateMap(myLocation->Edge(j), aShape, myGenMap);
1114
1115 TopoDS_Shape aGenVertex;
1116 TopTools_IndexedDataMapOfShapeListOfShape aMapVE;
1117
1118 for(i = 1; i <= mySection->NbLaw(); i++) {
1119 const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, aVEdges->LowerCol());
1120
1121 if((!aBottomEdge.IsNull()) && (aBottomEdge.ShapeType() == TopAbs_EDGE)) {
1122 TopExp::MapShapesAndAncestors(aBottomEdge, TopAbs_VERTEX, TopAbs_EDGE, aMapVE);
1123 }
1124 }
1125 const TopoDS_Shape& aFreeEdge = aUEdges->Value(eit, aUEdges->LowerCol());
1126 TopExp::MapShapesAndAncestors(aFreeEdge, TopAbs_VERTEX, TopAbs_EDGE, aMapVE);
1127 TopExp_Explorer anExpV(aFreeEdge, TopAbs_VERTEX);
1128
1129 for(; anExpV.More(); anExpV.Next()) {
1130 if(aMapVE.Contains(anExpV.Current())) {
1131 const TopTools_ListOfShape& aListOfV = aMapVE.FindFromKey(anExpV.Current());
1132
1133 if(aListOfV.Extent() >= 2) {
1134 aGenVertex = anExpV.Current();
1135 }
1136 }
1137 }
1138
1139 if(!aGenVertex.IsNull()) {
1140 UpdateMap(aGenVertex, aShape, myGenMap);
1141 }
1142 }
1143 }
1144 }
1145 // end for(eit = aUEdges->LowerRow...
1146 }
1147 // build history for free booundaries.end
1148 }
1149
1150 // build history for boundary section wires. begin
1151
1152 if(!mySeq.IsEmpty()) {
1153 Standard_Integer iseq;
1154 TopoDS_Wire aSect;
d7325741 1155 gp_Trsf aTrsf;
7fd59977 1156 Standard_Real param = 0., aparmin = RealLast(), aparmax = -RealLast();
1157 Standard_Integer ideb = 1, ifin = mySeq.Length();
1158
1159 for (iseq = 1;iseq <= mySeq.Length(); iseq++) {
d7325741 1160 Place(mySeq(iseq), aSect, aTrsf, param);
7fd59977 1161
1162 if(param < aparmin) {
1163 ideb = iseq;
1164 aparmin = param;
1165 }
1166
1167 if(param > aparmax) {
1168 ifin = iseq;
1169 aparmax = param;
1170 }
1171 }
1172
1173 UpdateMap(mySeq(ideb).Wire(), myFirst, myGenMap);
1174 UpdateMap(mySeq(ifin).Wire(), myLast, myGenMap);
1175 }
1176 // build history for boundary section wires. end
1177}
1178
1179// ---------------------------------------------------------------------------------
1180// static function: UpdateMap
1181// purpose:
1182// ---------------------------------------------------------------------------------
1183Standard_Boolean UpdateMap(const TopoDS_Shape& theKey,
1184 const TopoDS_Shape& theValue,
1185 TopTools_DataMapOfShapeListOfShape& theMap) {
1186
1187 if(!theMap.IsBound(theKey)) {
1188 TopTools_ListOfShape thelist;
1189 theMap.Bind(theKey, thelist);
1190 }
1191 TopTools_ListOfShape& aList = theMap.ChangeFind(theKey);
1192 TopTools_ListIteratorOfListOfShape anIt(aList);
1193 Standard_Boolean found = Standard_False;
1194
1195 for(; anIt.More(); anIt.Next()) {
1196 if(theValue.IsSame(anIt.Value())) {
1197 found = Standard_True;
1198 break;
1199 }
1200 }
1201
1202 if(!found)
1203 aList.Append(theValue);
1204 return !found;
1205}
1206
1207// ---------------------------------------------------------------------------------
1208// static function: BuildBoundaries
1209// purpose:
1210// ---------------------------------------------------------------------------------
1211Standard_Boolean BuildBoundaries(const BRepFill_Sweep& theSweep,
1212 const Handle(BRepFill_SectionLaw)& theSection,
1213 TopoDS_Shape& theBottom,
1214 TopoDS_Shape& theTop) {
1215
1216 TopoDS_Wire aBottomWire;
1217 TopoDS_Wire aTopWire;
1218 BRep_Builder aB;
1219 aB.MakeWire(aBottomWire);
1220 aB.MakeWire(aTopWire);
1221 Standard_Boolean bfoundbottom = Standard_False;
1222 Standard_Boolean bfoundtop = Standard_False;
1223 Handle(TopTools_HArray2OfShape) aVEdges = theSweep.Sections();
1224 Standard_Integer i = 0;
1225 Standard_Boolean bAllSame = Standard_True;
1226
1227 for(i = 1; i <= theSection->NbLaw(); i++) {
1228 const TopoDS_Shape& aBottomEdge = aVEdges->Value(i, aVEdges->LowerCol());
1229
1230 if(!aBottomEdge.IsNull() && (aBottomEdge.ShapeType() == TopAbs_EDGE)) {
1231 aB.Add(aBottomWire, aBottomEdge);
1232 bfoundbottom = Standard_True;
1233 }
1234 const TopoDS_Shape& aTopEdge = aVEdges->Value(i, aVEdges->UpperCol());
1235
1236 if(!aTopEdge.IsNull() && (aTopEdge.ShapeType() == TopAbs_EDGE)) {
1237 aB.Add(aTopWire, aTopEdge);
1238 bfoundtop = Standard_True;
1239 }
1240
1241 if(!aBottomEdge.IsNull() && !aTopEdge.IsNull() && !aBottomEdge.IsSame(aTopEdge))
1242 bAllSame = Standard_False;
1243 }
1244
1245 if(theSection->IsUClosed()) {
1246 aBottomWire.Closed(Standard_True);
1247 aTopWire.Closed(Standard_True);
1248 }
1249
1250 if(bfoundbottom) {
1251 theBottom = aBottomWire;
1252 }
1253
1254 if(bfoundtop) {
1255 theTop = aTopWire;
1256 }
1257
1258 if(bAllSame && bfoundbottom && bfoundtop)
1259 theTop = theBottom;
1260
1261 return bfoundbottom || bfoundtop;
1262}