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