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