0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[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>
cab49d68 65#include <TopTools_DataMapOfIntegerShape.hxx>
475604b4 66#include <TopTools_ListIteratorOfListOfShape.hxx>
42cf5bc1 67#include <TopTools_SequenceOfShape.hxx>
f52d1b53 68
7fd59977 69#ifdef DRAW
70#include <DBRep.hxx>
71static Standard_Boolean Affich = 0;
72#endif
73
5e9548e7 74// ---------------------------------------------------------------------------------
75// static function: UpdateMap
76// purpose:
77// ---------------------------------------------------------------------------------
78static Standard_Boolean UpdateMap(const TopoDS_Shape& theKey,
79 const TopoDS_Shape& theValue,
80 TopTools_DataMapOfShapeListOfShape& theMap)
81{
82 if(!theMap.IsBound(theKey))
83 {
84 TopTools_ListOfShape thelist;
85 theMap.Bind(theKey, thelist);
86 }
87 TopTools_ListOfShape& aList = theMap.ChangeFind(theKey);
88 TopTools_ListIteratorOfListOfShape anIt(aList);
89 Standard_Boolean found = Standard_False;
90
91 for(; anIt.More(); anIt.Next())
92 {
93 if(theValue.IsSame(anIt.Value()))
94 {
95 found = Standard_True;
96 break;
97 }
98 }
99
100 if(!found)
101 aList.Append(theValue);
102
103 return !found;
104}
105
c8ea5b8e 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));
cab49d68 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(),
7a8c6a36 266 M(3,1), M(3,2), M(3,3), V.Z());
7fd59977 267
268 fila.Multiply(myTrsf);
269 TopLoc_Location LocFirst(fila);
270 myFirst = myProfile;
271 if ( ! LocFirst.IsIdentity()) {
c8ea5b8e 272 //myFirst.Location( LocFirst.Multiplied(myProfile.Location()) );
273 myFirst = BRepBuilderAPI_Transform(myProfile, fila, Standard_True); //copy
7fd59977 274 }
275
f52d1b53 276 ShapeUpgrade_RemoveLocations RemLoc;
32a15d12 277 RemLoc.SetRemoveLevel(TopAbs_COMPOUND);
f52d1b53 278 RemLoc.Remove(myFirst);
279 myFirst = RemLoc.GetResult();
f52d1b53 280
7fd59977 281 myLoc->Law(myLoc->NbLaw())->GetDomain(first, last);
282 myLoc->Law(myLoc->NbLaw())->D0(last,M, V);
0d969553 283// try { // Not good, but there are no other means to test SetValues
7fd59977 284 fila.SetValues(M(1,1), M(1,2), M(1,3), V.X(),
285 M(2,1), M(2,2), M(2,3), V.Y(),
7a8c6a36 286 M(3,1), M(3,2), M(3,3), V.Z());
7fd59977 287 fila.Multiply(myTrsf);
288 TopLoc_Location LocLast(fila);
289 if (! myLoc->IsClosed() || LocFirst != LocLast) {
290 myLast = myProfile;
291 if ( ! LocLast.IsIdentity()) {
c8ea5b8e 292 //myLast.Location(LocLast.Multiplied(myProfile.Location()) );
293 myLast = BRepBuilderAPI_Transform(myProfile, fila, Standard_True); //copy
7fd59977 294 }
295 }
296 else {
297 myLast = myFirst;
298 }
f52d1b53 299
300 RemLoc.Remove(myLast);
301 myLast = RemLoc.GetResult();
f52d1b53 302
7fd59977 303#if DRAW
304 if (Affich) {
305 DBRep::Set("theprof", TheProf);
306 DBRep::Set("thefirst", myFirst);
307 DBRep::Set("thelast" , myLast);
308 }
309#endif
310
cab49d68 311 myShape = MakeShape(TheProf, myProfile, myFirst, myLast);
7fd59977 312}
313
314
315//=======================================================================
316//function : Spine
317//purpose :
318//=======================================================================
319
320const TopoDS_Shape& BRepFill_Pipe::Spine() const
321{
322 return mySpine;
323}
324
325//=======================================================================
326//function : Profile
327//purpose :
328//=======================================================================
329
330const TopoDS_Shape& BRepFill_Pipe::Profile() const
331{
332 return myProfile;
333}
334
335//=======================================================================
336//function : Shape
337//purpose :
338//=======================================================================
339
340const TopoDS_Shape& BRepFill_Pipe::Shape() const
341{
342 return myShape;
343}
344
73920cd4 345//=======================================================================
346//function : ErrorOnSurface
347//purpose :
348//=======================================================================
349
350Standard_Real BRepFill_Pipe::ErrorOnSurface() const
351{
352 return myErrorOnSurf;
353}
354
7fd59977 355
356//=======================================================================
357//function : FirstShape
358//purpose :
359//=======================================================================
360
361const TopoDS_Shape& BRepFill_Pipe::FirstShape() const
362{
363 return myFirst;
364}
365
366
367//=======================================================================
368//function : LastShape
369//purpose :
370//=======================================================================
371
372const TopoDS_Shape& BRepFill_Pipe::LastShape() const
373{
374 return myLast;
375}
376
5e9548e7 377//=======================================================================
378//function : Generated
379//purpose :
380//=======================================================================
381void BRepFill_Pipe::Generated(const TopoDS_Shape& theShape,
382 TopTools_ListOfShape& theList)
383{
384 theList.Clear();
385
cab49d68 386 if(myGenMap.IsBound(theShape)) {
387 theList = myGenMap.Find(theShape);
5e9548e7 388 }
389}
7fd59977 390
391//=======================================================================
392//function : Face
393//purpose :
394//=======================================================================
395
396TopoDS_Face BRepFill_Pipe::Face(const TopoDS_Edge& ESpine,
397 const TopoDS_Edge& EProfile)
398{
399 TopoDS_Face theFace;
400
401 if ( BRep_Tool::Degenerated(EProfile))
402 return theFace;
403
404 Standard_Integer ii, ispin = 0, iprof = 0, count = 0;
405
406 // *************************************************
407 // Search if EProfile is an edge of myProfile
408 // *************************************************
409 iprof = FindEdge(myProfile, EProfile, count);
410
9775fa61 411 if (!iprof) throw Standard_DomainError(
7fd59977 412 "BRepFill_Pipe::Face : Edge not in the Profile");
413
414
415 // *************************************************
416 // Search if ESpine is an edge of mySpine and find
417 // the index of the corresponding Filler
418 // *************************************************
419 for (ii=1; ii<=myLoc->NbLaw() && (!ispin); ii++)
420 if (ESpine.IsSame(myLoc->Edge(ii))) ispin = ii;
421
9775fa61 422 if (!ispin) throw Standard_DomainError(
7fd59977 423 "BRepFill_Pipe::Edge : Edge not in the Spine");
424
425 theFace = TopoDS::Face(myFaces->Value(iprof, ispin));
426 return theFace;
427
428}
429
430//=======================================================================
431//function : Edge
432//purpose :
433//=======================================================================
434TopoDS_Edge BRepFill_Pipe::Edge(const TopoDS_Edge& ESpine,
435 const TopoDS_Vertex& VProfile)
436{
8c2d3314 437 Standard_Integer ii, ispin = 0, iprof = 0, count = 0;
7fd59977 438
439 // *************************************************
440 // Search if VProfile is a Vertex of myProfile
441 // *************************************************
442 iprof = FindVertex(myProfile, VProfile, count);
9775fa61 443 if (!iprof) throw Standard_DomainError(
7fd59977 444 "BRepFill_Pipe::Edge : Vertex not in the Profile");
445
446
447 // *************************************************
448 // Search if ESpine is an edge of mySpine and find
449 // the index of the corresponding Filler
450 // *************************************************
451
452 for (ii=1; ii<=myLoc->NbLaw() && (!ispin); ii++)
453 if (ESpine.IsSame(myLoc->Edge(ii))) ispin = ii;
454
9775fa61 455 if (!ispin) throw Standard_DomainError(
7fd59977 456 "BRepFill_Pipe::Edge : Edge not in the Spine");
457
458
459 // *************************************************
460 // Generate the corresponding Shape
461 // *************************************************
462 TopoDS_Edge theEdge;
463 theEdge = TopoDS::Edge(myEdges->Value(iprof, ispin));
464
465 return theEdge;
466
467}
468
469
470//=======================================================================
471//function : Section
472//purpose :
473//=======================================================================
474
475TopoDS_Shape BRepFill_Pipe::Section(const TopoDS_Vertex& VSpine) const
476{
477 TopoDS_Iterator it, itv;
478
479 Standard_Integer ii, ispin = 0;
480
481 TopoDS_Shape curSect = myProfile;
482
483 // *************************************************
484 // Search if ESpine is an edge of mySpine and find
485 // the index of the corresponding Filler
486 // *************************************************
487
488 // iterate on all the edges of mySpine
489 for (ii=1; ii<=myLoc->NbLaw()+1 && (!ispin); ii++)
490 if (VSpine.IsSame(myLoc->Vertex(ii))) ispin = ii;
491
9775fa61 492 if (!ispin) throw Standard_DomainError(
7fd59977 493 "BRepFill_Pipe::Section : Vertex not in the Spine");
494
495 BRep_Builder B;
496 TopoDS_Compound Comp;
497 B.MakeCompound(Comp);
498 for (ii=1; ii<=mySections->ColLength(); ii++)
499 B.Add(Comp, mySections->Value(ii, ispin));
500
501 return Comp;
502}
503
504//=======================================================================
505//function : PipeLine
0d969553 506//purpose : Construct a wire by sweeping of a point
7fd59977 507//=======================================================================
508
c8ea5b8e 509TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point)
7fd59977 510{
0d969553 511 // Postioning
7fd59977 512 gp_Pnt P;
513 P = Point;
514 P.Transform(myTrsf);
515
cab49d68 516 TopoDS_Vertex VertexSection = BRepLib_MakeVertex(P);
7fd59977 517 Handle(BRepFill_ShapeLaw) Section =
cab49d68 518 new (BRepFill_ShapeLaw) (VertexSection);
7fd59977 519
0d969553 520 // Sweeping
7fd59977 521 BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
a31abc03 522 MkSw.SetForceApproxC1(myForceApproxC1);
8e817497 523 MkSw.Build( myReversedEdges, myTapes, myRails,
c8ea5b8e 524 BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
7fd59977 525 TopoDS_Shape aLocalShape = MkSw.Shape();
73920cd4 526 myErrorOnSurf = MkSw.ErrorOnSurface();
cab49d68 527 BuildHistory(MkSw, VertexSection);
7fd59977 528 return TopoDS::Wire(aLocalShape);
529// return TopoDS::Wire(MkSw.Shape());
530}
531
532//=======================================================================
533//function : MakeShape
534//purpose :
535//=======================================================================
536
537TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S,
cab49d68 538 const TopoDS_Shape& theOriginalS,
7fd59977 539 const TopoDS_Shape& FirstShape,
540 const TopoDS_Shape& LastShape)
541{
542 TopoDS_Shape result;
543 BRep_Builder B;
544 Standard_Boolean explode = Standard_False;
545 TopoDS_Shape TheS, TheFirst, TheLast;
546 Standard_Integer InitialLength = 0;
547 TheS = S;
548 TheFirst = FirstShape;
549 TheLast = LastShape;
550 if (! myFaces.IsNull()) InitialLength = myFaces->ColLength();
551
cab49d68 552 TopLoc_Location BackLoc(myTrsf.Inverted());
553
7fd59977 554 // there are two kinds of generation
555 // 1. generate with S from each Filler (Vertex, Edge)
556 // 2. call MakeShape recursively on the subshapes of S
557 //
558 // explode is True in the second case
559
560 // create the result empty
561
562 switch (S.ShapeType()) {
563
564 case TopAbs_VERTEX :
565 {
566 B.MakeWire(TopoDS::Wire(result));
567 break;
568 }
569
570 case TopAbs_EDGE :
571 {
572 TopoDS_Wire W;
573 B.MakeShell(TopoDS::Shell(result));
574 B.MakeWire(W);
575 B.Add(W, S);
da72a17c 576 W.Closed(BRep_Tool::IsClosed(S));
7fd59977 577 TheS = W;
578 if (!FirstShape.IsNull()) {
579 B.MakeWire(W);
580 B.Add(W, FirstShape);
da72a17c 581 W.Closed(BRep_Tool::IsClosed(FirstShape));
7fd59977 582 TheFirst = W;
583 }
584 if (!LastShape.IsNull()) {
585 B.MakeWire(W);
586 B.Add(W, LastShape);
da72a17c 587 W.Closed(BRep_Tool::IsClosed(LastShape));
7fd59977 588 TheLast = W;
589 }
ab860031 590 result.Closed (BRep_Tool::IsClosed (result));
7fd59977 591 break;
592 }
593
594 case TopAbs_WIRE :
595 B.MakeShell(TopoDS::Shell(result));
596 break;
597
598 case TopAbs_FACE :
599 {
600 B.MakeShell(TopoDS::Shell(result));
601 explode = Standard_True;
602 if ( !mySpine.Closed() && !TheFirst.IsNull()) {
603 B.Add(result, TheFirst.Reversed());
604 }
ab860031 605 result.Closed (BRep_Tool::IsClosed (result));
7fd59977 606 break;
607 }
608
609 case TopAbs_SHELL :
610 {
611 B.MakeCompSolid(TopoDS::CompSolid(result));
612 explode = Standard_True;
613 break;
614 }
615
616 case TopAbs_SOLID :
617 case TopAbs_COMPSOLID :
9775fa61 618 throw Standard_DomainError("BRepFill_Pipe::profile contains solids");
7fd59977 619 break;
620
621 case TopAbs_COMPOUND :
622 {
623 B.MakeCompound(TopoDS::Compound(result));
624 explode = Standard_True;
625 break;
626 }
7fd59977 627 default:
628 break;
7fd59977 629 }
630
631 if (explode) {
632 // add the subshapes
633 TopoDS_Iterator itFirst, itLast;
634 TopoDS_Shape first, last;
635 if (!TheFirst.IsNull()) itFirst.Initialize(TheFirst);
636 if (!TheLast.IsNull()) itLast.Initialize(TheLast);
637
cab49d68 638 TopoDS_Iterator it(S);
639 TopoDS_Iterator itorig(theOriginalS);
640 for (; it.More(); it.Next(),itorig.Next()) {
7fd59977 641 if (!TheFirst.IsNull()) first = itFirst.Value();
642 if (!TheLast.IsNull()) last = itLast.Value();
643 if (TheS.ShapeType() == TopAbs_FACE )
cab49d68 644 MakeShape(it.Value(), itorig.Value(), first, last);
7fd59977 645 else
cab49d68 646 B.Add(result,MakeShape(it.Value(), itorig.Value(), first, last));
7fd59977 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();
cab49d68 662 UpdateMap(theOriginalS, result, myGenMap);
73920cd4 663 myErrorOnSurf = MkSw.ErrorOnSurface();
2cd138b8 664
665 Handle(TopTools_HArray2OfShape) aSections = MkSw.Sections();
666
667 if (aSections.IsNull() == Standard_False) {
668 const Standard_Integer aVLast = aSections->UpperCol();
669
670 myFirst = aSections->Value(1, 1);
671 myLast = aSections->Value(1, aVLast);
672 }
cab49d68 673
674 BuildHistory(MkSw, theOriginalS);
7fd59977 675 }
676
677 if (TheS.ShapeType() == TopAbs_WIRE ) {
678 Handle(BRepFill_ShapeLaw) Section =
679 new (BRepFill_ShapeLaw) (TopoDS::Wire(TheS));
680 BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
681 MkSw.SetBounds(TopoDS::Wire(TheFirst),
682 TopoDS::Wire(TheLast));
a31abc03 683 MkSw.SetForceApproxC1(myForceApproxC1);
8e817497 684 MkSw.Build( myReversedEdges, myTapes, myRails,
c8ea5b8e 685 BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
7fd59977 686 result = MkSw.Shape();
73920cd4 687 myErrorOnSurf = MkSw.ErrorOnSurface();
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 }
cab49d68 745
746 BuildHistory(MkSw, theOriginalS);
7fd59977 747 }
748 }
749
750 if ( TheS.ShapeType() == TopAbs_FACE ) {
751 Standard_Integer ii, jj;
c8ea5b8e 752 //jgv
753 TopExp_Explorer Explo(result, TopAbs_FACE);
754 for (; Explo.More(); Explo.Next())
755 {
756 TopoDS_Shape aFace = Explo.Current();
757 RebuildTopOrBottomFace(aFace.Reversed(), Standard_True); //top face was reversed
758 }
759 /////
7fd59977 760 TopoDS_Face F;
761 for (ii=InitialLength+1; ii<=myFaces->ColLength(); ii++) {
762 for (jj=1; jj<=myFaces->RowLength(); jj++) {
763 F = TopoDS::Face(myFaces->Value(ii, jj));
764 if (!F.IsNull()) B.Add(result, F);
765 }
766 }
767
768 if ( !mySpine.Closed()) {
769 // if Spine is not closed
770 // add the last face of the solid
c8ea5b8e 771
772 //jgv
773 RebuildTopOrBottomFace(TheLast, Standard_False); //bottom face
774 /////
7fd59977 775 B.Add(result, TopoDS::Face(TheLast));
776 }
777
778 TopoDS_Solid solid;
779 BRep_Builder BS;
780 BS.MakeSolid(solid);
781
782 result.Closed(Standard_True);
783 BS.Add(solid,TopoDS::Shell(result));
784
785 BRepClass3d_SolidClassifier SC(solid);
786 SC.PerformInfinitePoint(Precision::Confusion());
787 if ( SC.State() == TopAbs_IN) {
788 BS.MakeSolid(solid);
789 TopoDS_Shape aLocalShape = result.Reversed();
790 BS.Add(solid,TopoDS::Shell(aLocalShape));
791// BS.Add(solid,TopoDS::Shell(result.Reversed()));
792 }
cab49d68 793 UpdateMap(theOriginalS, solid, myGenMap);
7fd59977 794 return solid;
795 }
796 else {
797 return result;
798 }
7fd59977 799}
800
0d969553 801//============================================================================
7fd59977 802//function : FindEdge
0d969553
Y
803//purpose : Find the number of edge corresponding to the edge of the profile.
804//============================================================================
7fd59977 805
806Standard_Integer BRepFill_Pipe::FindEdge(const TopoDS_Shape& S,
807 const TopoDS_Edge& E,
808 Standard_Integer& InitialLength) const
809{
810 Standard_Integer result = 0;
811
812 switch (S.ShapeType()) {
813
814 case TopAbs_EDGE :
815 {
816 InitialLength++;
817 if (S.IsSame(E)) result = InitialLength;
818 break;
819 }
820
821 case TopAbs_WIRE :
822 {
7fd59977 823 Handle(BRepFill_ShapeLaw) Section =
5a8dc41a 824 new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
825 Standard_Integer NbLaw = Section->NbLaw();
826
827 for (Standard_Integer ii = 1; (ii<=NbLaw) && (!result); ii++) {
828 if (E.IsSame(Section->Edge(ii)) ) result = InitialLength + ii;
7fd59977 829 }
5a8dc41a 830 InitialLength += NbLaw;
7fd59977 831 break;
832 }
833
834 case TopAbs_FACE :
835 case TopAbs_SHELL :
836 case TopAbs_COMPOUND :
837 {
838 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
839 result = FindEdge(it.Value(), E, InitialLength );
840 break;
841 }
842
843 case TopAbs_SOLID :
844 case TopAbs_COMPSOLID :
9775fa61 845 throw Standard_DomainError("BRepFill_Pipe::SOLID or COMPSOLID");
7fd59977 846 break;
7fd59977 847 default:
848 break;
7fd59977 849 }
850
851 return result;
852}
853
854//=======================================================================
855//function : FindVertex
0d969553 856//purpose : Find the number of edge corresponding to an edge of the profile.
7fd59977 857//=======================================================================
858
859Standard_Integer BRepFill_Pipe::FindVertex(const TopoDS_Shape& S,
860 const TopoDS_Vertex& V,
861 Standard_Integer& InitialLength) const
862{
863 Standard_Integer result = 0;
864
865 switch (S.ShapeType()) {
866 case TopAbs_VERTEX :
867 {
868 InitialLength++;
869 if (S.IsSame(V)) result = InitialLength;
870 break;
871 }
872
873 case TopAbs_EDGE :
874 {
875 TopoDS_Vertex VF, VL;
876 TopExp::Vertices(TopoDS::Edge(S), VF, VL);
877 if (S.Orientation() == TopAbs_REVERSED) {
878 TopoDS_Vertex aux;
879 aux = VF; VF = VL; VL = aux;
880 }
881 if (VF.IsSame(V)) result = InitialLength+1;
882 else if (VL.IsSame(V)) result = InitialLength+2;
883 InitialLength += 2;
884 break;
885 }
886
887 case TopAbs_WIRE :
888 {
889 Standard_Integer ii = InitialLength+1;
890 Handle(BRepFill_ShapeLaw) Section =
891 new (BRepFill_ShapeLaw) (TopoDS::Wire(S), Standard_False);
892 InitialLength += Section->NbLaw()+1;
893
894 for (; (ii<=InitialLength) && (!result); ii++) {
895 if (V.IsSame(Section->Vertex(ii, 0.)) ) result = ii;
896 }
897 break;
898 }
899
900 case TopAbs_FACE :
901 case TopAbs_SHELL :
902 case TopAbs_COMPOUND :
903 {
904 for (TopoDS_Iterator it(S); it.More() && (!result); it.Next())
905 result = FindVertex(it.Value(), V, InitialLength);
906 break;
907 }
908
909 case TopAbs_SOLID :
910 case TopAbs_COMPSOLID :
9775fa61 911 throw Standard_DomainError("BRepFill_Pipe::SOLID or COMPSOLID");
7fd59977 912 break;
7fd59977 913 default:
914 break;
7fd59977 915 }
916
917 return result;
918}
919
920//=======================================================================
921//function : DefineRealSegmax
922//purpose : Defines the real number of segments
923// required in the case of bspline spine
924//=======================================================================
925
926void BRepFill_Pipe::DefineRealSegmax()
927{
928 Standard_Integer RealSegmax = 0;
929
930 TopoDS_Iterator iter(mySpine);
931 for (; iter.More(); iter.Next())
932 {
933 TopoDS_Edge E = TopoDS::Edge(iter.Value());
934 Standard_Real first, last;
935 Handle(Geom_Curve) C = BRep_Tool::Curve( E, first, last );
936 if (C.IsNull())
937 continue;
938 while (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve) ||
939 C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
940 {
941 if (C->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
c5f3a425 942 C = Handle(Geom_TrimmedCurve)::DownCast (C)->BasisCurve();
7fd59977 943 if (C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve))
c5f3a425 944 C = Handle(Geom_OffsetCurve)::DownCast (C)->BasisCurve();
7fd59977 945 }
946 if (C->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve))
947 {
c5f3a425 948 Handle(Geom_BSplineCurve) BC (Handle(Geom_BSplineCurve)::DownCast (C));
7fd59977 949 Standard_Integer NbKnots = BC->NbKnots();
950 Standard_Integer RealNbKnots = NbKnots;
951 if (first > BC->FirstParameter())
952 {
953 Standard_Integer I1, I2;
954 BC->LocateU( first, Precision::PConfusion(), I1, I2 );
955 RealNbKnots -= I1-1;
956 }
957 if (last < BC->LastParameter())
958 {
959 Standard_Integer I1, I2;
960 BC->LocateU( last, Precision::PConfusion(), I1, I2 );
961 RealNbKnots -= NbKnots-I2;
962 }
963 RealSegmax += RealNbKnots-1;
964 }
965 }
966
967 if (mySegmax < RealSegmax)
968 mySegmax = RealSegmax;
969}
46e68e02 970
971//=======================================================================
c8ea5b8e 972//function : RebuildTopOrBottomFace
973//purpose : Correct orientation of v-iso edges
974// according to new 3d and 2d curves taken from swept surfaces
46e68e02 975//=======================================================================
976
c8ea5b8e 977void BRepFill_Pipe::RebuildTopOrBottomFace(const TopoDS_Shape& aFace,
978 const Standard_Boolean IsTop) const
46e68e02 979{
c8ea5b8e 980 Standard_Integer IndexOfSection =
981 (IsTop)? 1 : mySections->RowLength();
46e68e02 982
c8ea5b8e 983 Standard_Integer ii;
984 BRep_Builder BB;
985 TopoDS_Iterator itf(aFace);
986 for (; itf.More(); itf.Next())
987 {
988 TopoDS_Shape aWire = itf.Value();
989 TopTools_SequenceOfShape InitEdges;
990 TopTools_SequenceOfShape ResEdges;
991 TopoDS_Iterator itw(aWire);
992 for (; itw.More(); itw.Next())
993 {
994 TopoDS_Shape anEdge = itw.Value();
995 for (ii = myCurIndexOfSectionEdge; ii <= mySections->ColLength(); ii++)
996 {
997 TopoDS_Shape aVisoEdge = mySections->Value(ii, IndexOfSection);
998 if (anEdge.IsSame(aVisoEdge))
999 {
1000 InitEdges.Append(anEdge);
1001 ResEdges.Append(aVisoEdge);
46e68e02 1002 break;
1003 }
1004 }
1005 }
c8ea5b8e 1006 aWire.Free(Standard_True);
1007 for (ii = 1; ii <= InitEdges.Length(); ii++)
1008 {
1009 BB.Remove(aWire, InitEdges(ii));
1010 UpdateTolFromTopOrBottomPCurve(TopoDS::Face(aFace), TopoDS::Edge(ResEdges(ii)));
1011 BB.Add(aWire, ResEdges(ii));
46e68e02 1012 }
1013 }
46e68e02 1014}
cab49d68 1015
1016//=======================================================================
1017//function : BuildHistory
1018//purpose : Builds history for edges and vertices
1019// of section and path
1020//=======================================================================
1021void BRepFill_Pipe::BuildHistory(const BRepFill_Sweep& theSweep,
1022 const TopoDS_Shape& theSection)
1023{
1024 //Filling of <myGenMap>
1025 const Handle(TopTools_HArray2OfShape)& anUEdges = theSweep.InterFaces();
1026
1027 Standard_Integer inde;
1028 TopoDS_Iterator itw;
1029
1030 if (theSection.ShapeType() == TopAbs_WIRE)
1031 {
1032 TopoDS_Wire aSection = TopoDS::Wire(theSection);
1033 BRepTools_WireExplorer wexp_sec(aSection);
1034 for (inde = 0; wexp_sec.More(); wexp_sec.Next())
1035 {
1036 inde++;
1037 const TopoDS_Edge& anEdge = TopoDS::Edge(wexp_sec.Current());
1038 if (BRep_Tool::Degenerated(anEdge))
1039 continue;
1040 if (myGenMap.IsBound(anEdge))
1041 continue;
1042
1043 TopoDS_Vertex aVertex [2];
1044 TopExp::Vertices(anEdge, aVertex[0], aVertex[1]);
1045
1046 //For an edge generated shape is a "tape" -
1047 //a shell usually containing this edge and
1048 //passing from beginning of path to its end
1049 TopoDS_Shell aTape = TopoDS::Shell(theSweep.Tape(inde));
1050
1051 //Processing of vertices of <anEdge>
1052 //We should choose right index in <anUEdges>
1053 //for each vertex of edge
1054 Standard_Integer UIndex [2];
1055 UIndex[0] = inde;
1056 UIndex[1] = inde+1;
1057
1058 if (anEdge.Orientation() == TopAbs_REVERSED)
1059 { Standard_Integer Tmp = UIndex[0]; UIndex[0] = UIndex[1]; UIndex[1] = Tmp; }
1060
1061 for (Standard_Integer kk = 0; kk < 2; kk++)
1062 {
1063 if (myGenMap.IsBound(aVertex[kk]))
1064 continue;
1065
1066 //Assemble the list of edges ("rail" along the path)
1067 TopTools_ListOfShape* Elist = myGenMap.Bound(aVertex[kk], TopTools_ListOfShape());
1068 Standard_Integer jj;
1069 for (jj = 1; jj <= anUEdges->UpperCol(); jj++)
1070 {
1071 const TopoDS_Shape& anUedge = anUEdges->Value(UIndex[kk], jj);
1072 if (!anUedge.IsNull())
1073 Elist->Append(anUedge);
1074 }
1075 } //for (Standard_Integer kk = 0; kk < 2; kk++)
1076
1077 TopTools_ListOfShape* Flist = myGenMap.Bound(anEdge, TopTools_ListOfShape());
1078 TopoDS_Iterator itsh(aTape);
1079 for (; itsh.More(); itsh.Next())
1080 Flist->Append(itsh.Value());
1081 } //for (inde = 0; wexp_sec.More(); wexp_sec.Next())
1082 } //if (theSection.ShapeType() == TopAbs_WIRE)
1083
1084 //For subshapes of spine
1085 const Handle(TopTools_HArray2OfShape)& aFaces = theSweep.SubShape();
1086 const Handle(TopTools_HArray2OfShape)& aVEdges = theSweep.Sections();
1087
1088 BRepTools_WireExplorer wexp(mySpine);
1089 inde = 0;
1090 Standard_Boolean ToExit = Standard_False;
1091 for (;;)
1092 {
1093 if (!wexp.More())
1094 ToExit = Standard_True;
1095
1096 inde++;
1097
1098 if (!ToExit)
1099 {
1100 const TopoDS_Edge& anEdgeOfSpine = wexp.Current();
1101 for (Standard_Integer i = 1; i <= aFaces->UpperRow(); i++)
1102 {
1103 const TopoDS_Shape& aFace = aFaces->Value(i, inde);
1104 UpdateMap(anEdgeOfSpine, aFace, myGenMap);
1105 }
1106 }
1107
1108 const TopoDS_Vertex& aVertexOfSpine = wexp.CurrentVertex();
1109 for (Standard_Integer i = 1; i <= aVEdges->UpperRow(); i++)
1110 {
1111 const TopoDS_Shape& aVedge = aVEdges->Value(i, inde);
1112 UpdateMap(aVertexOfSpine, aVedge, myGenMap);
1113 }
1114
1115 if (ToExit)
1116 break;
1117
1118 if (wexp.More())
1119 wexp.Next();
1120 }
1121}