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