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