0026377: Passing Handle objects as arguments to functions as non-const reference...
[occt.git] / src / BRepFill / BRepFill_Pipe.cxx
CommitLineData
b311480e 1// Created on: 1994-06-07
2// Created by: Bruno DUMORTIER
3// Copyright (c) 1994-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
42cf5bc1 18#include <Adaptor3d_CurveOnSurface.hxx>
7fd59977 19#include <BRep_Builder.hxx>
42cf5bc1 20#include <BRep_Tool.hxx>
21#include <BRepBuilderAPI_Copy.hxx>
22#include <BRepBuilderAPI_Transform.hxx>
7fd59977 23#include <BRepClass3d_SolidClassifier.hxx>
42cf5bc1 24#include <BRepFill_Edge3DLaw.hxx>
25#include <BRepFill_LocationLaw.hxx>
26#include <BRepFill_Pipe.hxx>
7fd59977 27#include <BRepFill_SectionPlacement.hxx>
28#include <BRepFill_ShapeLaw.hxx>
7fd59977 29#include <BRepFill_Sweep.hxx>
42cf5bc1 30#include <BRepLib.hxx>
31#include <BRepLib_MakeVertex.hxx>
32#include <BRepTools_Substitution.hxx>
33#include <Geom2dAdaptor_HCurve.hxx>
34#include <Geom_BSplineCurve.hxx>
35#include <Geom_OffsetCurve.hxx>
36#include <Geom_TrimmedCurve.hxx>
7fd59977 37#include <GeomAbs_Shape.hxx>
42cf5bc1 38#include <GeomAdaptor_HSurface.hxx>
39#include <GeomFill_CorrectedFrenet.hxx>
40#include <GeomFill_CurveAndTrihedron.hxx>
41#include <GeomFill_DiscreteTrihedron.hxx>
42#include <GeomFill_Frenet.hxx>
43#include <gp_Pnt.hxx>
44#include <Precision.hxx>
45#include <ShapeUpgrade_RemoveLocations.hxx>
46#include <Standard_DomainError.hxx>
47#include <Standard_ErrorHandler.hxx>
48#include <Standard_NotImplemented.hxx>
49#include <StdFail_NotDone.hxx>
50#include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
51#include <TColStd_DataMapOfIntegerInteger.hxx>
7fd59977 52#include <TopAbs_ShapeEnum.hxx>
42cf5bc1 53#include <TopExp.hxx>
7fd59977 54#include <TopoDS.hxx>
7fd59977 55#include <TopoDS_Compound.hxx>
42cf5bc1 56#include <TopoDS_Edge.hxx>
57#include <TopoDS_Face.hxx>
7fd59977 58#include <TopoDS_Iterator.hxx>
42cf5bc1 59#include <TopoDS_Shape.hxx>
60#include <TopoDS_Shell.hxx>
61#include <TopoDS_Solid.hxx>
62#include <TopoDS_Vertex.hxx>
63#include <TopoDS_Wire.hxx>
46e68e02 64#include <TopTools_DataMapOfShapeInteger.hxx>
475604b4 65#include <TopTools_ListIteratorOfListOfShape.hxx>
42cf5bc1 66#include <TopTools_SequenceOfShape.hxx>
f52d1b53 67
7fd59977 68#ifdef DRAW
69#include <DBRep.hxx>
70static Standard_Boolean Affich = 0;
71#endif
72
5e9548e7 73// ---------------------------------------------------------------------------------
74// static function: UpdateMap
75// purpose:
76// ---------------------------------------------------------------------------------
77static Standard_Boolean UpdateMap(const TopoDS_Shape& theKey,
78 const TopoDS_Shape& theValue,
79 TopTools_DataMapOfShapeListOfShape& theMap)
80{
81 if(!theMap.IsBound(theKey))
82 {
83 TopTools_ListOfShape thelist;
84 theMap.Bind(theKey, thelist);
85 }
86 TopTools_ListOfShape& aList = theMap.ChangeFind(theKey);
87 TopTools_ListIteratorOfListOfShape anIt(aList);
88 Standard_Boolean found = Standard_False;
89
90 for(; anIt.More(); anIt.Next())
91 {
92 if(theValue.IsSame(anIt.Value()))
93 {
94 found = Standard_True;
95 break;
96 }
97 }
98
99 if(!found)
100 aList.Append(theValue);
101
102 return !found;
103}
104
f52d1b53 105static void ReverseModifiedEdges(TopoDS_Shape& aShape,
106 TopTools_MapOfShape& Emap)
107{
108 TopExp_Explorer Explo(aShape, TopAbs_FACE);
109 BRep_Builder BB;
475604b4 110
f52d1b53 111 for (; Explo.More(); Explo.Next())
112 {
113 TopoDS_Shape aFace = Explo.Current();
114 TopoDS_Iterator itf(aFace);
115 for (; itf.More(); itf.Next())
116 {
117 TopoDS_Shape aWire = itf.Value();
475604b4 118 TopTools_ListOfShape Ledges;
f52d1b53 119 TopoDS_Iterator itw(aWire);
120 for (; itw.More(); itw.Next())
475604b4 121 Ledges.Append(itw.Value());
122
f52d1b53 123 aWire.Free(Standard_True);
475604b4 124 TopTools_ListIteratorOfListOfShape itl(Ledges);
125 for (; itl.More(); itl.Next())
126 BB.Remove(aWire, itl.Value());
127
128 for (itl.Initialize(Ledges); itl.More(); itl.Next())
f52d1b53 129 {
475604b4 130 TopoDS_Shape anEdge = itl.Value();
131 if (Emap.Contains(anEdge))
132 anEdge.Reverse();
133 BB.Add(aWire, anEdge);
f52d1b53 134 }
135 }
136 }
137}
c8ea5b8e 138
139static void UpdateTolFromTopOrBottomPCurve(const TopoDS_Face& aFace,
140 TopoDS_Edge& anEdge)
141{
142 Standard_Real fpar, lpar;
143 Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(anEdge, aFace, fpar, lpar);
144 if (aPCurve.IsNull())
145 return;
146
147 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
148 if (aCurve.IsNull())
149 return;
150
151 Handle(Geom2dAdaptor_HCurve) GAHC2d = new Geom2dAdaptor_HCurve(aPCurve, fpar, lpar);
152 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
153 Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(aSurf);
154 Adaptor3d_CurveOnSurface ConS(GAHC2d, GAHS);
155
156 Standard_Real Tol = BRep_Tool::Tolerance(anEdge);
157 Standard_Real InitTol = Tol;
158 Standard_Real TolTol = Tol*Tol;
159 const Standard_Integer NCONTROL = 22;
160 Standard_Real delta = (lpar - fpar)/NCONTROL;
161 for (Standard_Integer i = 0; i <= NCONTROL; i++)
162 {
163 Standard_Real par = fpar + i*delta;
164 gp_Pnt pnt = aCurve->Value(par);
165 gp_Pnt prj = ConS.Value(par);
166 Standard_Real sqdist = pnt.SquareDistance(prj);
167 if (sqdist > TolTol)
168 TolTol = sqdist;
169 }
170 Tol = 1.00005 * Sqrt(TolTol);
171 if (Tol >= InitTol)
172 {
173 BRep_Builder BB;
174 BB.UpdateEdge(anEdge, Tol);
175 TopoDS_Iterator itv(anEdge);
176 for (; itv.More(); itv.Next())
177 {
178 TopoDS_Vertex aVertex = TopoDS::Vertex(itv.Value());
179 BB.UpdateVertex(aVertex, Tol);
180 }
181 }
182}
183
7fd59977 184//=======================================================================
185//function : BRepFill_Pipe
186//purpose :
187//=======================================================================
188
189BRepFill_Pipe::BRepFill_Pipe()
190{
471ce736 191 myDegmax = 11;
7fd59977 192 mySegmax = 100;
471ce736 193 myContinuity = GeomAbs_C2;
a31abc03 194 myMode = GeomFill_IsCorrectedFrenet;
195 myForceApproxC1 = Standard_False;
c8ea5b8e 196
197 myCurIndexOfSectionEdge = 1;
7fd59977 198}
199
200
201//=======================================================================
202//function : BRepFill_Pipe
203//purpose :
204//=======================================================================
205
206BRepFill_Pipe::BRepFill_Pipe(const TopoDS_Wire& Spine,
207 const TopoDS_Shape& Profile,
471ce736 208 const GeomFill_Trihedron aMode,
209 const Standard_Boolean ForceApproxC1,
7fd59977 210 const Standard_Boolean KPart)
471ce736 211
7fd59977 212{
471ce736 213 myDegmax = 11;
7fd59977 214 mySegmax = 100;
471ce736 215
a31abc03 216 myMode = GeomFill_IsCorrectedFrenet;
a31abc03 217 if (aMode == GeomFill_IsFrenet ||
218 aMode == GeomFill_IsCorrectedFrenet ||
219 aMode == GeomFill_IsDiscreteTrihedron)
220 myMode = aMode;
a31abc03 221
471ce736 222 myContinuity = GeomAbs_C2;
223 if (myMode == GeomFill_IsDiscreteTrihedron)
224 myContinuity = GeomAbs_C0;
225
a31abc03 226 myForceApproxC1 = ForceApproxC1;
c8ea5b8e 227
228 myCurIndexOfSectionEdge = 1;
229
471ce736 230 Perform(Spine, Profile, KPart);
a31abc03 231}
7fd59977 232
233
234//=======================================================================
235//function : Perform
236//purpose :
237//=======================================================================
238
239void BRepFill_Pipe::Perform(const TopoDS_Wire& Spine,
240 const TopoDS_Shape& Profile,
35e08fe8 241 const Standard_Boolean /*KPart*/)
7fd59977 242
243{
244 mySections.Nullify();
245 myFaces.Nullify();
246 myEdges.Nullify();
247
248 mySpine = Spine;
249 myProfile = Profile;
250
251 DefineRealSegmax();
252
253 BRepTools_WireExplorer wexp;
254 TopoDS_Shape TheProf;
255
a31abc03 256 Handle(GeomFill_TrihedronLaw) TLaw;
257 switch (myMode)
258 {
259 case GeomFill_IsFrenet:
260 TLaw = new GeomFill_Frenet();
261 break;
262 case GeomFill_IsCorrectedFrenet:
263 TLaw = new GeomFill_CorrectedFrenet();
264 break;
265 case GeomFill_IsDiscreteTrihedron:
266 TLaw = new GeomFill_DiscreteTrihedron();
267 break;
566f8441 268 default:
269 break;
a31abc03 270 }
7fd59977 271 Handle(GeomFill_CurveAndTrihedron) Loc =
272 new (GeomFill_CurveAndTrihedron) (TLaw);
273 myLoc = new (BRepFill_Edge3DLaw) (mySpine, Loc);
274 if (myLoc->NbLaw() == 0) {
0d969553 275 return; // Degenerated case
7fd59977 276 }
0d969553 277 myLoc->TransformInG0Law(); // Set into continuity
7fd59977 278
279 BRepFill_SectionPlacement Place(myLoc, Profile);
280 myTrsf = Place.Transformation();
281
282 TopLoc_Location Loc2(myTrsf), Loc1;
283 Loc1 = Profile.Location();
284 TopoDS_Shape aux;
285 TheProf = myProfile;
286 TheProf.Location(Loc2.Multiplied(Loc1));
287
0d969553 288 // Construct First && Last Shape
7fd59977 289 Handle(GeomFill_LocationLaw) law;
290
291 gp_Mat M;
292 gp_Vec V;
293 gp_Trsf fila;
294 Standard_Real first, last;
295 myLoc->Law(1)->GetDomain(first, last);
296 myLoc->Law(1)->D0(first, M, V);
297 fila.SetValues(M(1,1), M(1,2), M(1,3), V.X(),
298 M(2,1), M(2,2), M(2,3), V.Y(),
7a8c6a36 299 M(3,1), M(3,2), M(3,3), V.Z());
7fd59977 300
301 fila.Multiply(myTrsf);
302 TopLoc_Location LocFirst(fila);
303 myFirst = myProfile;
304 if ( ! LocFirst.IsIdentity()) {
c8ea5b8e 305 //myFirst.Location( LocFirst.Multiplied(myProfile.Location()) );
306 myFirst = BRepBuilderAPI_Transform(myProfile, fila, Standard_True); //copy
7fd59977 307 }
308
f52d1b53 309 ShapeUpgrade_RemoveLocations RemLoc;
32a15d12 310 RemLoc.SetRemoveLevel(TopAbs_COMPOUND);
f52d1b53 311 RemLoc.Remove(myFirst);
312 myFirst = RemLoc.GetResult();
f52d1b53 313
7fd59977 314 myLoc->Law(myLoc->NbLaw())->GetDomain(first, last);
315 myLoc->Law(myLoc->NbLaw())->D0(last,M, V);
0d969553 316// try { // Not good, but there are no other means to test SetValues
7fd59977 317 fila.SetValues(M(1,1), M(1,2), M(1,3), V.X(),
318 M(2,1), M(2,2), M(2,3), V.Y(),
7a8c6a36 319 M(3,1), M(3,2), M(3,3), V.Z());
7fd59977 320 fila.Multiply(myTrsf);
321 TopLoc_Location LocLast(fila);
322 if (! myLoc->IsClosed() || LocFirst != LocLast) {
323 myLast = myProfile;
324 if ( ! LocLast.IsIdentity()) {
c8ea5b8e 325 //myLast.Location(LocLast.Multiplied(myProfile.Location()) );
326 myLast = BRepBuilderAPI_Transform(myProfile, fila, Standard_True); //copy
7fd59977 327 }
328 }
329 else {
330 myLast = myFirst;
331 }
f52d1b53 332
333 RemLoc.Remove(myLast);
334 myLast = RemLoc.GetResult();
f52d1b53 335
7fd59977 336#if DRAW
337 if (Affich) {
338 DBRep::Set("theprof", TheProf);
339 DBRep::Set("thefirst", myFirst);
340 DBRep::Set("thelast" , myLast);
341 }
342#endif
343
344 myShape = MakeShape(TheProf, myFirst, myLast);
345}
346
347
348//=======================================================================
349//function : Spine
350//purpose :
351//=======================================================================
352
353const TopoDS_Shape& BRepFill_Pipe::Spine() const
354{
355 return mySpine;
356}
357
358//=======================================================================
359//function : Profile
360//purpose :
361//=======================================================================
362
363const TopoDS_Shape& BRepFill_Pipe::Profile() const
364{
365 return myProfile;
366}
367
368//=======================================================================
369//function : Shape
370//purpose :
371//=======================================================================
372
373const TopoDS_Shape& BRepFill_Pipe::Shape() const
374{
375 return myShape;
376}
377
73920cd4 378//=======================================================================
379//function : ErrorOnSurface
380//purpose :
381//=======================================================================
382
383Standard_Real BRepFill_Pipe::ErrorOnSurface() const
384{
385 return myErrorOnSurf;
386}
387
7fd59977 388
389//=======================================================================
390//function : FirstShape
391//purpose :
392//=======================================================================
393
394const TopoDS_Shape& BRepFill_Pipe::FirstShape() const
395{
396 return myFirst;
397}
398
399
400//=======================================================================
401//function : LastShape
402//purpose :
403//=======================================================================
404
405const TopoDS_Shape& BRepFill_Pipe::LastShape() const
406{
407 return myLast;
408}
409
5e9548e7 410//=======================================================================
411//function : Generated
412//purpose :
413//=======================================================================
414void BRepFill_Pipe::Generated(const TopoDS_Shape& theShape,
415 TopTools_ListOfShape& theList)
416{
417 theList.Clear();
418
419 if (theShape.IsSame(myProfile))
420 theList.Append(myShape);
421 else
422 {
423 if (theShape.ShapeType() == TopAbs_FACE ||
424 theShape.ShapeType() == TopAbs_WIRE)
425 {
426 if(myGenMap.IsBound(theShape))
427 theList = myGenMap.Find(theShape);
428 }
429 else if (theShape.ShapeType() == TopAbs_EDGE)
430 {
431 TopoDS_Iterator itw(mySpine);
432 for (; itw.More(); itw.Next())
433 {
434 const TopoDS_Edge& aSpineEdge = TopoDS::Edge(itw.Value());
435 const TopoDS_Shape& aFace = Face(aSpineEdge, TopoDS::Edge(theShape));
436 theList.Append(aFace);
437 }
438 }
439 else if (theShape.ShapeType() == TopAbs_VERTEX)
440 {
441 TopoDS_Iterator itw(mySpine);
442 for (; itw.More(); itw.Next())
443 {
444 const TopoDS_Edge& aSpineEdge = TopoDS::Edge(itw.Value());
445 const TopoDS_Shape& anEdge = Edge(aSpineEdge, TopoDS::Vertex(theShape));
446 theList.Append(anEdge);
447 }
448 }
449 }
450}
7fd59977 451
452//=======================================================================
453//function : Face
454//purpose :
455//=======================================================================
456
457TopoDS_Face BRepFill_Pipe::Face(const TopoDS_Edge& ESpine,
458 const TopoDS_Edge& EProfile)
459{
460 TopoDS_Face theFace;
461
462 if ( BRep_Tool::Degenerated(EProfile))
463 return theFace;
464
465 Standard_Integer ii, ispin = 0, iprof = 0, count = 0;
466
467 // *************************************************
468 // Search if EProfile is an edge of myProfile
469 // *************************************************
470 iprof = FindEdge(myProfile, EProfile, count);
471
472 if (!iprof) Standard_DomainError::Raise(
473 "BRepFill_Pipe::Face : Edge not in the Profile");
474
475
476 // *************************************************
477 // Search if ESpine is an edge of mySpine and find
478 // the index of the corresponding Filler
479 // *************************************************
480 for (ii=1; ii<=myLoc->NbLaw() && (!ispin); ii++)
481 if (ESpine.IsSame(myLoc->Edge(ii))) ispin = ii;
482
483 if (!ispin) Standard_DomainError::Raise(
484 "BRepFill_Pipe::Edge : Edge not in the Spine");
485
486 theFace = TopoDS::Face(myFaces->Value(iprof, ispin));
487 return theFace;
488
489}
490
491//=======================================================================
492//function : Edge
493//purpose :
494//=======================================================================
495TopoDS_Edge BRepFill_Pipe::Edge(const TopoDS_Edge& ESpine,
496 const TopoDS_Vertex& VProfile)
497{
498 Standard_Integer ii, ispin = 0, iprof = 0, count = 0;;
499
500 // *************************************************
501 // Search if VProfile is a Vertex of myProfile
502 // *************************************************
503 iprof = FindVertex(myProfile, VProfile, count);
504 if (!iprof) Standard_DomainError::Raise(
505 "BRepFill_Pipe::Edge : Vertex not in the Profile");
506
507
508 // *************************************************
509 // Search if ESpine is an edge of mySpine and find
510 // the index of the corresponding Filler
511 // *************************************************
512
513 for (ii=1; ii<=myLoc->NbLaw() && (!ispin); ii++)
514 if (ESpine.IsSame(myLoc->Edge(ii))) ispin = ii;
515
516 if (!ispin) Standard_DomainError::Raise(
517 "BRepFill_Pipe::Edge : Edge not in the Spine");
518
519
520 // *************************************************
521 // Generate the corresponding Shape
522 // *************************************************
523 TopoDS_Edge theEdge;
524 theEdge = TopoDS::Edge(myEdges->Value(iprof, ispin));
525
526 return theEdge;
527
528}
529
530
531//=======================================================================
532//function : Section
533//purpose :
534//=======================================================================
535
536TopoDS_Shape BRepFill_Pipe::Section(const TopoDS_Vertex& VSpine) const
537{
538 TopoDS_Iterator it, itv;
539
540 Standard_Integer ii, ispin = 0;
541
542 TopoDS_Shape curSect = myProfile;
543
544 // *************************************************
545 // Search if ESpine is an edge of mySpine and find
546 // the index of the corresponding Filler
547 // *************************************************
548
549 // iterate on all the edges of mySpine
550 for (ii=1; ii<=myLoc->NbLaw()+1 && (!ispin); ii++)
551 if (VSpine.IsSame(myLoc->Vertex(ii))) ispin = ii;
552
553 if (!ispin) Standard_DomainError::Raise(
554 "BRepFill_Pipe::Section : Vertex not in the Spine");
555
556 BRep_Builder B;
557 TopoDS_Compound Comp;
558 B.MakeCompound(Comp);
559 for (ii=1; ii<=mySections->ColLength(); ii++)
560 B.Add(Comp, mySections->Value(ii, ispin));
561
562 return Comp;
563}
564
565//=======================================================================
566//function : PipeLine
0d969553 567//purpose : Construct a wire by sweeping of a point
7fd59977 568//=======================================================================
569
c8ea5b8e 570TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point)
7fd59977 571{
0d969553 572 // Postioning
7fd59977 573 gp_Pnt P;
574 P = Point;
575 P.Transform(myTrsf);
576
577 BRepLib_MakeVertex MkV(P);
578 Handle(BRepFill_ShapeLaw) Section =
579 new (BRepFill_ShapeLaw) (MkV.Vertex());
580
0d969553 581 // Sweeping
7fd59977 582 BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
a31abc03 583 MkSw.SetForceApproxC1(myForceApproxC1);
8e817497 584 MkSw.Build( myReversedEdges, myTapes, myRails,
c8ea5b8e 585 BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
7fd59977 586 TopoDS_Shape aLocalShape = MkSw.Shape();
73920cd4 587 myErrorOnSurf = MkSw.ErrorOnSurface();
7fd59977 588 return TopoDS::Wire(aLocalShape);
589// return TopoDS::Wire(MkSw.Shape());
590}
591
592//=======================================================================
593//function : MakeShape
594//purpose :
595//=======================================================================
596
597TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
598 const TopoDS_Shape& FirstShape,
599 const TopoDS_Shape& LastShape)
600{
601 TopoDS_Shape result;
602 BRep_Builder B;
603 Standard_Boolean explode = Standard_False;
604 TopoDS_Shape TheS, TheFirst, TheLast;
605 Standard_Integer InitialLength = 0;
606 TheS = S;
607 TheFirst = FirstShape;
608 TheLast = LastShape;
609 if (! myFaces.IsNull()) InitialLength = myFaces->ColLength();
610
611 // there are two kinds of generation
612 // 1. generate with S from each Filler (Vertex, Edge)
613 // 2. call MakeShape recursively on the subshapes of S
614 //
615 // explode is True in the second case
616
617 // create the result empty
618
619 switch (S.ShapeType()) {
620
621 case TopAbs_VERTEX :
622 {
623 B.MakeWire(TopoDS::Wire(result));
624 break;
625 }
626
627 case TopAbs_EDGE :
628 {
629 TopoDS_Wire W;
630 B.MakeShell(TopoDS::Shell(result));
631 B.MakeWire(W);
632 B.Add(W, S);
da72a17c 633 W.Closed(BRep_Tool::IsClosed(S));
7fd59977 634 TheS = W;
635 if (!FirstShape.IsNull()) {
636 B.MakeWire(W);
637 B.Add(W, FirstShape);
da72a17c 638 W.Closed(BRep_Tool::IsClosed(FirstShape));
7fd59977 639 TheFirst = W;
640 }
641 if (!LastShape.IsNull()) {
642 B.MakeWire(W);
643 B.Add(W, LastShape);
da72a17c 644 W.Closed(BRep_Tool::IsClosed(LastShape));
7fd59977 645 TheLast = W;
646 }
ab860031 647 result.Closed (BRep_Tool::IsClosed (result));
7fd59977 648 break;
649 }
650
651 case TopAbs_WIRE :
652 B.MakeShell(TopoDS::Shell(result));
653 break;
654
655 case TopAbs_FACE :
656 {
657 B.MakeShell(TopoDS::Shell(result));
658 explode = Standard_True;
659 if ( !mySpine.Closed() && !TheFirst.IsNull()) {
660 B.Add(result, TheFirst.Reversed());
661 }
ab860031 662 result.Closed (BRep_Tool::IsClosed (result));
7fd59977 663 break;
664 }
665
666 case TopAbs_SHELL :
667 {
668 B.MakeCompSolid(TopoDS::CompSolid(result));
669 explode = Standard_True;
670 break;
671 }
672
673 case TopAbs_SOLID :
674 case TopAbs_COMPSOLID :
c8ea5b8e 675 Standard_DomainError::Raise("BRepFill_Pipe::profile contains solids");
7fd59977 676 break;
677
678 case TopAbs_COMPOUND :
679 {
680 B.MakeCompound(TopoDS::Compound(result));
681 explode = Standard_True;
682 break;
683 }
7fd59977 684 default:
685 break;
7fd59977 686 }
687
688 if (explode) {
689 // add the subshapes
690 TopoDS_Iterator itFirst, itLast;
691 TopoDS_Shape first, last;
692 if (!TheFirst.IsNull()) itFirst.Initialize(TheFirst);
693 if (!TheLast.IsNull()) itLast.Initialize(TheLast);
694
695 for (TopoDS_Iterator it(S); it.More(); it.Next()) {
696 if (!TheFirst.IsNull()) first = itFirst.Value();
697 if (!TheLast.IsNull()) last = itLast.Value();
698 if (TheS.ShapeType() == TopAbs_FACE )
699 MakeShape(it.Value(), first, last);
700 else
701 B.Add(result,MakeShape(it.Value(), first, last));
702
703 if (!TheFirst.IsNull()) itFirst.Next();
704 if (!TheLast.IsNull()) itLast.Next();
705 }
706 }
707
708 else {
709 if (TheS.ShapeType() == TopAbs_VERTEX ) {
710 Handle(BRepFill_ShapeLaw) Section =
711 new (BRepFill_ShapeLaw) (TopoDS::Vertex(TheS));
712 BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
a31abc03 713 MkSw.SetForceApproxC1(myForceApproxC1);
8e817497 714 MkSw.Build( myReversedEdges, myTapes, myRails,
c8ea5b8e 715 BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
7fd59977 716 result = MkSw.Shape();
5e9548e7 717 UpdateMap(TheS.Located(myProfile.Location()), result, myGenMap);
73920cd4 718 myErrorOnSurf = MkSw.ErrorOnSurface();
2cd138b8 719
720 Handle(TopTools_HArray2OfShape) aSections = MkSw.Sections();
721
722 if (aSections.IsNull() == Standard_False) {
723 const Standard_Integer aVLast = aSections->UpperCol();
724
725 myFirst = aSections->Value(1, 1);
726 myLast = aSections->Value(1, aVLast);
727 }
7fd59977 728 }
729
730 if (TheS.ShapeType() == TopAbs_WIRE ) {
731 Handle(BRepFill_ShapeLaw) Section =
732 new (BRepFill_ShapeLaw) (TopoDS::Wire(TheS));
733 BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
734 MkSw.SetBounds(TopoDS::Wire(TheFirst),
735 TopoDS::Wire(TheLast));
a31abc03 736 MkSw.SetForceApproxC1(myForceApproxC1);
8e817497 737 MkSw.Build( myReversedEdges, myTapes, myRails,
c8ea5b8e 738 BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
7fd59977 739 result = MkSw.Shape();
5e9548e7 740 UpdateMap(TheS.Located(myProfile.Location()), result, myGenMap);
73920cd4 741 myErrorOnSurf = MkSw.ErrorOnSurface();
f52d1b53 742 //Correct <myFirst> and <myLast>
743 ReverseModifiedEdges(myFirst, myReversedEdges);
744 ReverseModifiedEdges(myLast, myReversedEdges);
7fd59977 745
0d969553 746 // Labeling of elements
7fd59977 747 if (mySections.IsNull()) {
748 myFaces = MkSw.SubShape();
749 mySections = MkSw.Sections();
750 myEdges = MkSw.InterFaces();
751 }
752 else {
753 Handle(TopTools_HArray2OfShape) Aux, Somme;
754 Standard_Integer length;
755 Standard_Integer ii, jj, kk;
756
757 Aux = MkSw.SubShape();
758 length = Aux->ColLength() + myFaces->ColLength();
759 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
760 Aux->RowLength());
761 for (jj=1; jj<=myFaces->RowLength(); jj++) {
762 for (ii=1; ii<=myFaces->ColLength(); ii++)
763 Somme->SetValue(ii, jj, myFaces->Value(ii, jj));
764
765 for (kk=1, ii=myFaces->ColLength()+1;
766 kk <=Aux->ColLength(); kk++, ii++)
767 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
768 }
769 myFaces = Somme;
7fd59977 770
771 Aux = MkSw.Sections();
772 length = Aux->ColLength() + mySections->ColLength();
773 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
774 Aux->RowLength());
775 for (jj=1; jj<=mySections->RowLength(); jj++) {
776 for (ii=1; ii<=mySections->ColLength(); ii++)
777 Somme->SetValue(ii, jj, mySections->Value(ii, jj));
c8ea5b8e 778
779 myCurIndexOfSectionEdge = mySections->ColLength()+1;
780
7fd59977 781 for (kk=1, ii=mySections->ColLength()+1;
782 kk <=Aux->ColLength(); kk++, ii++)
783 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
784 }
785 mySections = Somme;
786
787 Aux = MkSw.InterFaces();
788 length = Aux->ColLength() + myEdges->ColLength();
789 Somme = new (TopTools_HArray2OfShape) (1, length, 1,
790 Aux->RowLength());
791 for (jj=1; jj<=myEdges->RowLength(); jj++) {
792 for (ii=1; ii<=myEdges->ColLength(); ii++)
793 Somme->SetValue(ii, jj, myEdges->Value(ii, jj));
794
795 for (kk=1, ii=myEdges->ColLength()+1;
796 kk <=Aux->ColLength(); kk++, ii++)
797 Somme->SetValue(ii, jj, Aux->Value(kk, jj));
798 }
46e68e02 799
800 myEdges = Somme;
7fd59977 801 }
802 }
803 }
804
805 if ( TheS.ShapeType() == TopAbs_FACE ) {
806 Standard_Integer ii, jj;
c8ea5b8e 807 //jgv
808 TopExp_Explorer Explo(result, TopAbs_FACE);
809 for (; Explo.More(); Explo.Next())
810 {
811 TopoDS_Shape aFace = Explo.Current();
812 RebuildTopOrBottomFace(aFace.Reversed(), Standard_True); //top face was reversed
813 }
814 /////
7fd59977 815 TopoDS_Face F;
816 for (ii=InitialLength+1; ii<=myFaces->ColLength(); ii++) {
817 for (jj=1; jj<=myFaces->RowLength(); jj++) {
818 F = TopoDS::Face(myFaces->Value(ii, jj));
819 if (!F.IsNull()) B.Add(result, F);
820 }
821 }
822
823 if ( !mySpine.Closed()) {
824 // if Spine is not closed
825 // add the last face of the solid
c8ea5b8e 826
827 //jgv
828 RebuildTopOrBottomFace(TheLast, Standard_False); //bottom face
829 /////
7fd59977 830 B.Add(result, TopoDS::Face(TheLast));
831 }
832
833 TopoDS_Solid solid;
834 BRep_Builder BS;
835 BS.MakeSolid(solid);
836
837 result.Closed(Standard_True);
838 BS.Add(solid,TopoDS::Shell(result));
839
840 BRepClass3d_SolidClassifier SC(solid);
841 SC.PerformInfinitePoint(Precision::Confusion());
842 if ( SC.State() == TopAbs_IN) {
843 BS.MakeSolid(solid);
844 TopoDS_Shape aLocalShape = result.Reversed();
845 BS.Add(solid,TopoDS::Shell(aLocalShape));
846// BS.Add(solid,TopoDS::Shell(result.Reversed()));
847 }
5e9548e7 848 UpdateMap(TheS.Located(myProfile.Location()), solid, myGenMap);
7fd59977 849 return solid;
850 }
851 else {
852 return result;
853 }
7fd59977 854}
855
0d969553 856//============================================================================
7fd59977 857//function : FindEdge
0d969553
Y
858//purpose : Find the number of edge corresponding to the edge of the profile.
859//============================================================================
7fd59977 860
861Standard_Integer BRepFill_Pipe::FindEdge(const TopoDS_Shape& S,
862 const TopoDS_Edge& E,
863 Standard_Integer& InitialLength) const
864{
865 Standard_Integer result = 0;
866
867 switch (S.ShapeType()) {
868
869 case TopAbs_EDGE :
870 {
871 InitialLength++;
872 if (S.IsSame(E)) result = InitialLength;
873 break;
874 }
875
876 case TopAbs_WIRE :
877 {
7fd59977 878 Handle(BRepFill_ShapeLaw) Section =
5a8dc41a 879 new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
880 Standard_Integer NbLaw = Section->NbLaw();
881
882 for (Standard_Integer ii = 1; (ii<=NbLaw) && (!result); ii++) {
883 if (E.IsSame(Section->Edge(ii)) ) result = InitialLength + ii;
7fd59977 884 }
5a8dc41a 885 InitialLength += NbLaw;
7fd59977 886 break;
887 }
888
889 case TopAbs_FACE :
890 case TopAbs_SHELL :
891 case TopAbs_COMPOUND :
892 {
893 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
894 result = FindEdge(it.Value(), E, InitialLength );
895 break;
896 }
897
898 case TopAbs_SOLID :
899 case TopAbs_COMPSOLID :
900 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
901 break;
7fd59977 902 default:
903 break;
7fd59977 904 }
905
906 return result;
907}
908
909//=======================================================================
910//function : FindVertex
0d969553 911//purpose : Find the number of edge corresponding to an edge of the profile.
7fd59977 912//=======================================================================
913
914Standard_Integer BRepFill_Pipe::FindVertex(const TopoDS_Shape& S,
915 const TopoDS_Vertex& V,
916 Standard_Integer& InitialLength) const
917{
918 Standard_Integer result = 0;
919
920 switch (S.ShapeType()) {
921 case TopAbs_VERTEX :
922 {
923 InitialLength++;
924 if (S.IsSame(V)) result = InitialLength;
925 break;
926 }
927
928 case TopAbs_EDGE :
929 {
930 TopoDS_Vertex VF, VL;
931 TopExp::Vertices(TopoDS::Edge(S), VF, VL);
932 if (S.Orientation() == TopAbs_REVERSED) {
933 TopoDS_Vertex aux;
934 aux = VF; VF = VL; VL = aux;
935 }
936 if (VF.IsSame(V)) result = InitialLength+1;
937 else if (VL.IsSame(V)) result = InitialLength+2;
938 InitialLength += 2;
939 break;
940 }
941
942 case TopAbs_WIRE :
943 {
944 Standard_Integer ii = InitialLength+1;
945 Handle(BRepFill_ShapeLaw) Section =
946 new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
947 InitialLength += Section->NbLaw()+1;
948
949 for (; (ii<=InitialLength) && (!result); ii++) {
950 if (V.IsSame(Section->Vertex(ii, 0.)) ) result = ii;
951 }
952 break;
953 }
954
955 case TopAbs_FACE :
956 case TopAbs_SHELL :
957 case TopAbs_COMPOUND :
958 {
959 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
960 result = FindVertex(it.Value(), V, InitialLength);
961 break;
962 }
963
964 case TopAbs_SOLID :
965 case TopAbs_COMPSOLID :
966 Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
967 break;
7fd59977 968 default:
969 break;
7fd59977 970 }
971
972 return result;
973}
974
975//=======================================================================
976//function : DefineRealSegmax
977//purpose : Defines the real number of segments
978// required in the case of bspline spine
979//=======================================================================
980
981void BRepFill_Pipe::DefineRealSegmax()
982{
983 Standard_Integer RealSegmax = 0;
984
985 TopoDS_Iterator iter(mySpine);
986 for (; iter.More(); iter.Next())
987 {
988 TopoDS_Edge E = TopoDS::Edge(iter.Value());
989 Standard_Real first, last;
990 Handle(Geom_Curve) C = BRep_Tool::Curve( E, first, last );
991 if (C.IsNull())
992 continue;
993 while (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve) ||
994 C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
995 {
996 if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
c5f3a425 997 C = Handle(Geom_TrimmedCurve)::DownCast (C)->BasisCurve();
7fd59977 998 if (C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
c5f3a425 999 C = Handle(Geom_OffsetCurve)::DownCast (C)->BasisCurve();
7fd59977 1000 }
1001 if (C->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve))
1002 {
c5f3a425 1003 Handle(Geom_BSplineCurve) BC (Handle(Geom_BSplineCurve)::DownCast (C));
7fd59977 1004 Standard_Integer NbKnots = BC->NbKnots();
1005 Standard_Integer RealNbKnots = NbKnots;
1006 if (first > BC->FirstParameter())
1007 {
1008 Standard_Integer I1, I2;
1009 BC->LocateU( first, Precision::PConfusion(), I1, I2 );
1010 RealNbKnots -= I1-1;
1011 }
1012 if (last < BC->LastParameter())
1013 {
1014 Standard_Integer I1, I2;
1015 BC->LocateU( last, Precision::PConfusion(), I1, I2 );
1016 RealNbKnots -= NbKnots-I2;
1017 }
1018 RealSegmax += RealNbKnots-1;
1019 }
1020 }
1021
1022 if (mySegmax < RealSegmax)
1023 mySegmax = RealSegmax;
1024}
46e68e02 1025
1026//=======================================================================
c8ea5b8e 1027//function : RebuildTopOrBottomFace
1028//purpose : Correct orientation of v-iso edges
1029// according to new 3d and 2d curves taken from swept surfaces
46e68e02 1030//=======================================================================
1031
c8ea5b8e 1032void BRepFill_Pipe::RebuildTopOrBottomFace(const TopoDS_Shape& aFace,
1033 const Standard_Boolean IsTop) const
46e68e02 1034{
c8ea5b8e 1035 Standard_Integer IndexOfSection =
1036 (IsTop)? 1 : mySections->RowLength();
46e68e02 1037
c8ea5b8e 1038 Standard_Integer ii;
1039 BRep_Builder BB;
1040 TopoDS_Iterator itf(aFace);
1041 for (; itf.More(); itf.Next())
1042 {
1043 TopoDS_Shape aWire = itf.Value();
1044 TopTools_SequenceOfShape InitEdges;
1045 TopTools_SequenceOfShape ResEdges;
1046 TopoDS_Iterator itw(aWire);
1047 for (; itw.More(); itw.Next())
1048 {
1049 TopoDS_Shape anEdge = itw.Value();
1050 for (ii = myCurIndexOfSectionEdge; ii <= mySections->ColLength(); ii++)
1051 {
1052 TopoDS_Shape aVisoEdge = mySections->Value(ii, IndexOfSection);
1053 if (anEdge.IsSame(aVisoEdge))
1054 {
1055 InitEdges.Append(anEdge);
1056 ResEdges.Append(aVisoEdge);
46e68e02 1057 break;
1058 }
1059 }
1060 }
c8ea5b8e 1061 aWire.Free(Standard_True);
1062 for (ii = 1; ii <= InitEdges.Length(); ii++)
1063 {
1064 BB.Remove(aWire, InitEdges(ii));
1065 UpdateTolFromTopOrBottomPCurve(TopoDS::Face(aFace), TopoDS::Edge(ResEdges(ii)));
1066 BB.Add(aWire, ResEdges(ii));
46e68e02 1067 }
1068 }
46e68e02 1069}