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