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