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