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