1 // Created on: 1998-01-07
2 // Created by: Philippe MANGIN
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
19 #include <BRepFill_Sweep.ixx>
21 #include <BRepFill_SectionLaw.hxx>
22 //#include <BRepFill_TrimCorner.hxx>
23 #include <BRepFill_CurveConstraint.hxx>
25 #include <GeomFill_SectionLaw.hxx>
26 #include <GeomFill_LocationLaw.hxx>
27 #include <GeomFill_Sweep.hxx>
29 // modified by NIZHNY-MKK Wed Oct 22 12:25:45 2003
30 #include <BRepFill_TrimShellCorner.hxx>
32 //#include <GeomPlate_BuildPlateSurface.hxx>
33 //#include <GeomPlate_Surface.hxx>
34 //#include <GeomPlate_PointConstraint.hxx>
36 #include <gp_Pnt2d.hxx>
37 #include <gp_Vec2d.hxx>
38 #include <Bnd_Box.hxx>
40 #include <Geom_Surface.hxx>
41 #include <Geom_SurfaceOfRevolution.hxx>
42 #include <Geom_RectangularTrimmedSurface.hxx>
43 #include <Geom_Plane.hxx>
44 #include <Geom_Curve.hxx>
45 #include <Geom_BezierCurve.hxx>
46 #include <Geom_BSplineCurve.hxx>
47 #include <Geom2d_Line.hxx>
48 #include <Geom2d_BSplineCurve.hxx>
49 #include <Geom2d_TrimmedCurve.hxx>
50 #include <GeomLib.hxx>
51 #include <GeomLib_IsPlanarSurface.hxx>
52 #include <BRepLib_FindSurface.hxx>
53 #include <GeomConvert_ApproxSurface.hxx>
55 #include <BRepAdaptor_HCurve.hxx>
56 #include <BRepAdaptor_HCurve2d.hxx>
57 #include <BRepAdaptor_HSurface.hxx>
58 #include <Adaptor3d_HCurveOnSurface.hxx>
59 #include <GeomAdaptor_HSurface.hxx>
60 #include <GeomAdaptor_HCurve.hxx>
61 #include <Geom2dAdaptor_HCurve.hxx>
62 #include <Approx_CurveOnSurface.hxx>
63 #include <Approx_SameParameter.hxx>
64 #include <GCPnts_AbscissaPoint.hxx>
66 #include <BRep_Builder.hxx>
67 #include <BRep_Tool.hxx>
68 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
69 #include <BRep_TEdge.hxx>
70 #include <BRep_TVertex.hxx>
71 #include <BRep_CurveRepresentation.hxx>
72 #include <BRep_GCurve.hxx>
74 #include <BRepLib.hxx>
75 #include <BRepLib_MakeEdge.hxx>
76 #include <BRepLib_MakeFace.hxx>
77 #include <BRepLib_FaceError.hxx>
80 #include <TopoDS_Edge.hxx>
81 #include <TopoDS_Face.hxx>
82 #include <TopoDS_Compound.hxx>
83 #include <TopoDS_Shell.hxx>
85 #include <TopExp_Explorer.hxx>
86 #include <TopAbs_Orientation.hxx>
88 #include <TColStd_HArray1OfInteger.hxx>
89 #include <TColStd_Array2OfInteger.hxx>
90 #include <TColStd_Array1OfReal.hxx>
91 #include <TColStd_Array2OfReal.hxx>
92 #include <TColGeom_Array2OfSurface.hxx>
93 #include <TColgp_Array1OfPnt.hxx>
94 #include <TColStd_Array1OfBoolean.hxx>
96 #include <TopTools_Array1OfShape.hxx>
97 #include <TopTools_Array2OfShape.hxx>
98 #include <TopTools_HArray2OfShape.hxx>
99 #include <TopTools_HArray1OfShape.hxx>
100 #include <TopTools_ListIteratorOfListOfShape.hxx>
101 #include <TopTools_ListOfShape.hxx>
102 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
103 #include <TopTools_SequenceOfShape.hxx>
104 #include <BRepTools_WireExplorer.hxx>
106 #include <Standard_ConstructionError.hxx>
107 #include <Precision.hxx>
108 #include <BRepBuilderAPI_MakeWire.hxx>
110 #include <BRepTools_Substitution.hxx>
111 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
112 #include <TopoDS_Iterator.hxx>
115 #include <BRepCheck_Edge.hxx>
119 #include <DrawTrSurf.hxx>
121 #include <Geom_BoundedSurface.hxx>
122 static Standard_Boolean Affich = 0;
125 //=======================================================================
126 //function : NumberOfPoles
128 //=======================================================================
129 static Standard_Integer NumberOfPoles(const TopoDS_Wire& W)
131 Standard_Integer NbPoints = 0;
133 TopoDS_Iterator iter(W);
134 for (; iter.More(); iter.Next())
136 BRepAdaptor_Curve c(TopoDS::Edge(iter.Value()));
138 Standard_Real dfUf = c.FirstParameter();
139 Standard_Real dfUl = c.LastParameter();
140 if (IsEqual(dfUf,dfUl))
146 case GeomAbs_BezierCurve:
148 // Put all poles for bezier
149 Handle(Geom_BezierCurve) GC = c.Bezier();
150 Standard_Integer iNbPol = GC->NbPoles();
155 case GeomAbs_BSplineCurve:
157 // Put all poles for bspline
158 Handle(Geom_BSplineCurve) GC = c.BSpline();
159 Standard_Integer iNbPol = GC->NbPoles();
170 case GeomAbs_Ellipse:
171 case GeomAbs_Hyperbola:
172 case GeomAbs_Parabola:
178 NbPoints += 15 + c.NbIntervals(GeomAbs_C3);
179 } // switch (c.GetType()) ...
180 } // for (; iter.More(); iter.Next())
185 //=======================================================================
186 //function : HasPCurves
188 //=======================================================================
189 static Standard_Boolean HasPCurves(const TopoDS_Edge& E)
191 Standard_Boolean haspcurves = Standard_False;
193 BRep_ListIteratorOfListOfCurveRepresentation itcr
194 ((*((Handle(BRep_TEdge)*)&E.TShape()))->Curves());
195 for (; itcr.More(); itcr.Next())
197 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
198 if (cr->IsCurveOnSurface())
200 haspcurves = Standard_True;
207 //=======================================================================
208 //function : Translate
209 //purpose : Copy a column from one table to another.
210 //=======================================================================
211 static void Translate(const Handle(TopTools_HArray2OfShape)& ArrayIn,
212 const Standard_Integer In,
213 Handle(TopTools_HArray2OfShape)& ArrayOut,
214 const Standard_Integer Out)
216 Standard_Integer ii, Nb;
217 Nb = ArrayOut->ColLength();
218 for (ii=1; ii<=Nb; ii++) {
219 ArrayOut->SetValue(ii, Out, ArrayIn->Value(ii, In));
224 //=======================================================================
226 //purpose : Bounding box of a section.
227 //=======================================================================
228 static void Box(Handle(GeomFill_SectionLaw)& Sec,
229 const Standard_Real U,
233 Standard_Integer NbPoles, bid;
235 Sec->SectionShape(NbPoles, bid, bid);
236 TColgp_Array1OfPnt Poles(1, NbPoles);
237 TColStd_Array1OfReal W(1, NbPoles);
238 Sec->D0(U, Poles, W);
239 for (Standard_Integer ii=1; ii<=NbPoles; ii++) {
244 //=======================================================================
246 //purpose : Check if E is an edge of sewing on S
247 // and make the representation HadHoc
248 //=======================================================================
249 static Handle(Geom2d_Curve) Couture(const TopoDS_Edge& E,
250 const Handle(Geom_Surface)& S,
251 const TopLoc_Location& L)
253 TopLoc_Location l = L.Predivided(E.Location());
254 Standard_Boolean Eisreversed = (E.Orientation() == TopAbs_REVERSED);
256 // find the representation
257 BRep_ListIteratorOfListOfCurveRepresentation itcr
258 ((*((Handle(BRep_TEdge)*)&E.TShape()))->ChangeCurves());
260 while (itcr.More()) {
261 Handle(BRep_CurveRepresentation)& cr = itcr.Value();
262 if (cr->IsCurveOnSurface(S,l)) {
263 Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
264 if (GC->IsCurveOnClosedSurface() && Eisreversed)
265 return GC->PCurve2();
271 Handle(Geom2d_Curve) pc;
276 //=======================================================================
277 //function : CheckSameParameter
278 //purpose : Check a posteriori that sameparameter has worked correctly
279 //=======================================================================
281 static Standard_Boolean CheckSameParameter
282 (const Handle(Adaptor3d_HCurve)& C3d,
283 const Handle(Geom2d_Curve)& Pcurv,
284 const Handle(Adaptor3d_HSurface)& S,
285 const Standard_Real tol3d,
286 Standard_Real& tolreached)
289 Standard_Real f = C3d->FirstParameter();
290 Standard_Real l = C3d->LastParameter();
291 Standard_Integer nbp = 45;
292 Standard_Real step = 1./(nbp -1);
293 for(Standard_Integer i = 0; i < nbp; i++){
296 t = (1-t) * f + t * l;
297 Pcurv->Value(t).Coord(u,v);
298 gp_Pnt pS = S->Value(u,v);
299 gp_Pnt pC = C3d->Value(t);
300 Standard_Real d2 = pS.SquareDistance(pC);
301 tolreached = Max(tolreached,d2);
303 tolreached = sqrt(tolreached);
304 if(tolreached > tol3d){
306 return Standard_False;
309 tolreached = Max(tolreached,Precision::Confusion());
310 return Standard_True;
313 //=======================================================================
314 //function : SameParameter
315 //purpose : Encapsulation of Sameparameter
316 // Boolean informs if the pcurve was computed or not...
317 // The tolerance is always OK.
318 //=======================================================================
320 static Standard_Boolean SameParameter(TopoDS_Edge& E,
321 Handle(Geom2d_Curve)& Pcurv,
322 const Handle(Geom_Surface)& Surf,
323 const Standard_Real tol3d,
324 Standard_Real& tolreached)
326 //Handle(BRepAdaptor_HCurve) C3d = new (BRepAdaptor_HCurve)(E);
328 Handle(Geom_Curve) C3d = BRep_Tool::Curve( E, f, l );
329 GeomAdaptor_Curve GAC3d( C3d, f, l );
330 Handle(GeomAdaptor_HCurve) HC3d = new GeomAdaptor_HCurve( GAC3d );
332 Handle(GeomAdaptor_HSurface) S = new (GeomAdaptor_HSurface)(Surf);
333 Standard_Real ResTol;
335 if(CheckSameParameter( HC3d, Pcurv, S, tol3d, tolreached ))
336 return Standard_True;
340 Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( Pcurv );
341 Approx_CurveOnSurface AppCurve(HC2d, S, HC2d->FirstParameter(), HC2d->LastParameter(),
342 Precision::Confusion(), GeomAbs_C1, 10, 10, Standard_True);
343 if (AppCurve.IsDone() && AppCurve.HasResult())
345 C3d = AppCurve.Curve3d();
346 tolreached = AppCurve.MaxError3d();
348 B.UpdateEdge( E, C3d, tolreached );
349 return Standard_True;
353 const Handle(Adaptor3d_HCurve)& aHCurve = HC3d; // to avoid ambiguity
354 Approx_SameParameter sp (aHCurve, Pcurv, S, tol3d );
355 if(sp.IsDone() && !sp.IsSameParameter()) Pcurv = sp.Curve2d();
356 else if(!sp.IsDone() && !sp.IsSameParameter()){
358 cout<<"echec SameParameter"<<endl;
360 return Standard_False;
363 ResTol = sp.TolReached();
364 if(ResTol > tolreached ){
366 cout<<"SameParameter : Tolerance not reached!"<<endl;
367 cout<<"tol visee : "<<tol3d<<" tol obtained : "<<ResTol<<endl;
369 return Standard_False;
372 tolreached = 1.1*ResTol;
373 if(sp.IsDone() && !sp.IsSameParameter()) Pcurv = sp.Curve2d();
375 return Standard_True;
378 //=======================================================================
379 //Objet : Orientate an edge of natural restriction
381 //=======================================================================
382 static void Oriente(const Handle(Geom_Surface)& S,
386 gp_Vec2d D, URef(1, 0), VRef(0, 1);
387 Standard_Boolean isuiso, isfirst, isopposite;
388 Standard_Real UFirst, ULast, VFirst, VLast, f, l;
389 S->Bounds(UFirst, ULast, VFirst, VLast);
390 Handle(Geom2d_Curve) C;
393 C = BRep_Tool::CurveOnSurface(E, S, bid, f, l);
394 C->D1((f+l)/2, P, D);
396 isuiso = D.IsParallel(VRef, 0.1);
399 isfirst = (Abs (P.X()-UFirst) < Precision::Confusion());
400 isopposite = D.IsOpposite(VRef, 0.1);
401 E.Orientation(TopAbs_REVERSED);
404 isfirst = (Abs (P.Y()-VFirst) < Precision::Confusion());
405 isopposite = D.IsOpposite(URef, 0.1);
406 E.Orientation(TopAbs_FORWARD);
409 if (!isfirst) E.Reverse();
410 if (isopposite) E.Reverse();
413 static void UpdateEdgeOnPlane(const TopoDS_Face& F, const TopoDS_Edge& E,
414 const BRep_Builder& BB)
417 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f,l);
418 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
420 Standard_Real Tol = BRep_Tool::Tolerance(E);
421 BB.UpdateEdge(E, C2d, S, Loc, Tol);
422 BRepCheck_Edge Check(E);
423 Tol = Max(Tol,Check.Tolerance());
424 BB.UpdateEdge(E, Tol);
427 V = TopExp::FirstVertex(E);
428 if(BRep_Tool::Tolerance(V) < Tol) BB.UpdateVertex(V, Tol);
429 V = TopExp::LastVertex(E);
430 if(BRep_Tool::Tolerance(V) < Tol) BB.UpdateVertex(V, Tol);
433 //=======================================================================
434 //Function : BuildFace
435 //Objet : Construct a Face via a surface and 4 Edges (natural borders)
436 // : Only one Hypothesis : isos u and v are switched :
437 // Edge1/3 are iso u (recp v)
438 // Edge2/4 are iso v (recp u)
439 //=======================================================================
440 static void BuildFace(const Handle(Geom_Surface)& S,
441 const TopoDS_Edge& E1,
442 const TopoDS_Edge& E2,
443 const TopoDS_Edge& E3,
444 const TopoDS_Edge& E4,
445 TopTools_DataMapOfShapeShape& EEmap,
446 const Standard_Boolean ExchUV,
447 const Standard_Boolean UReverse,
451 // Class BRep_Tool without fields and without Constructor :
453 TopoDS_Edge e1, e2, E;
456 BRepBuilderAPI_MakeWire B;
457 TopoDS_Iterator Iter;
460 //Is the surface planar ?
461 Standard_Real Tol1, Tol2, Tol3, Tol4;
462 Tol1 = BRep_Tool::Tolerance( E1 );
463 Tol2 = BRep_Tool::Tolerance( E2 );
464 Tol3 = BRep_Tool::Tolerance( E3 );
465 Tol4 = BRep_Tool::Tolerance( E4 );
466 // Tol = Min( BT.Tolerance(E1), BT.Tolerance(E2));
467 Tol = Min( Tol1, Tol2 );
468 // Tol = Min(Tol, Min(BT.Tolerance(E3),BT.Tolerance(E4)));
469 Tol = Min( Tol, Min( Tol3, Tol4 ) );
470 Standard_Boolean IsPlan = Standard_False;
471 Handle(Geom_Plane) thePlane;
473 if (!E1.IsSame(E3) && !E2.IsSame(E4)) //exclude cases with seam edges: they are not planar
475 GeomLib_IsPlanarSurface IsP(S, Tol);
478 IsPlan = Standard_True;
479 thePlane = new Geom_Plane( IsP.Plan() );
483 Handle(BRep_TEdge)& TE1 = *((Handle(BRep_TEdge)*)&E1.TShape());
484 Handle(BRep_TEdge)& TE2 = *((Handle(BRep_TEdge)*)&E2.TShape());
485 Handle(BRep_TEdge)& TE3 = *((Handle(BRep_TEdge)*)&E3.TShape());
486 Handle(BRep_TEdge)& TE4 = *((Handle(BRep_TEdge)*)&E4.TShape());
487 TE1->Tolerance( Precision::Confusion() );
488 TE2->Tolerance( Precision::Confusion() );
489 TE3->Tolerance( Precision::Confusion() );
490 TE4->Tolerance( Precision::Confusion() );
492 TopoDS_Wire theWire = BRepLib_MakeWire( E1, E2, E3, E4 );
493 Standard_Integer NbPoints = NumberOfPoles( theWire );
494 if (NbPoints <= 100) //limitation for CPU
496 BRepLib_FindSurface FS( theWire, -1, Standard_True );
499 IsPlan = Standard_True;
500 thePlane = Handle(Geom_Plane)::DownCast(FS.Surface());
503 BB.UpdateEdge( E1, Tol1 );
504 BB.UpdateEdge( E2, Tol2 );
505 BB.UpdateEdge( E3, Tol3 );
506 BB.UpdateEdge( E4, Tol4 );
510 // Construction of the wire
514 // if (!IsPlan || !BT.Degenerated(e1))
515 if (!IsPlan || !BRep_Tool::Degenerated(e1))
520 // if (!IsPlan || !BT.Degenerated(e2))
521 if (!IsPlan || !BRep_Tool::Degenerated(e2))
524 if (!BRep_Tool::Degenerated(e2))
527 TopoDS_Shape NewEdge;
528 //take the last edge added to WW
529 for (Iter.Initialize( WW ); Iter.More(); Iter.Next())
530 NewEdge = Iter.Value();
531 if (! e2.IsSame(NewEdge))
532 EEmap.Bind( e2, NewEdge );
544 // if (!IsPlan || !BT.Degenerated(E))
545 if (!IsPlan || !BRep_Tool::Degenerated(E))
548 if (!BRep_Tool::Degenerated(E))
551 TopoDS_Shape NewEdge;
552 //take the last edge added to WW
553 for (Iter.Initialize( WW ); Iter.More(); Iter.Next())
554 NewEdge = Iter.Value();
555 if (! E.IsSame(NewEdge))
556 EEmap.Bind( E, NewEdge );
568 // if (!IsPlan || !BT.Degenerated(E))
569 if (!IsPlan || !BRep_Tool::Degenerated(E))
572 if (!BRep_Tool::Degenerated(E))
575 TopoDS_Shape NewEdge;
576 //take the last edge added to WW
577 for (Iter.Initialize( WW ); Iter.More(); Iter.Next())
578 NewEdge = Iter.Value();
579 if (! E.IsSame(NewEdge))
580 EEmap.Bind( E, NewEdge );
587 DBRep::Set("wire-on-face", WW);
590 // Construction of the face.
591 if (IsPlan) { // Suspend representation 2d
592 // and construct face Plane
594 //BRepLib_MakeFace MkF(IsP.Plan(), WW);
596 gp_Vec DU, DV, NS, NP;
597 Standard_Real Ufirst, Ulast, Vfirst, Vlast;
598 S->Bounds( Ufirst, Ulast, Vfirst, Vlast );
599 S->D1( (Ufirst+Ulast)/2., (Vfirst+Vlast)/2., aPnt, DU, DV );
601 NP = thePlane->Pln().Axis().Direction();
603 thePlane->UReverse();
604 BRepLib_MakeFace MkF( thePlane, WW );
605 if (MkF.Error() != BRepLib_FaceDone) {
607 BRepLib_FaceError Err = MkF.Error();
608 cout << "Planar Face Error :" << Err << endl;
612 Handle(Geom2d_Curve) NullC2d;
614 BB.UpdateEdge( E1, NullC2d, S, Loc, Tol1 );
615 BB.UpdateEdge( E2, NullC2d, S, Loc, Tol2 );
616 BB.UpdateEdge( E3, NullC2d, S, Loc, Tol3 );
617 BB.UpdateEdge( E4, NullC2d, S, Loc, Tol4 );
620 UpdateEdgeOnPlane(F,E1,BB);
621 UpdateEdgeOnPlane(F,E2,BB);
622 UpdateEdgeOnPlane(F,E3,BB);
623 UpdateEdgeOnPlane(F,E4,BB);
626 Handle(Geom2d_Curve) NC;
628 // B.UpdateEdge(E1, NC, S, Loc, BT.Tolerance(E1));
629 BB.UpdateEdge(E1, NC, S, Loc, BRep_Tool::Tolerance(E1));
630 // B.UpdateEdge(E2, NC, S, Loc, BT.Tolerance(E2));
631 BB.UpdateEdge(E2, NC, S, Loc, BRep_Tool::Tolerance(E2));
632 // B.UpdateEdge(E3, NC, S, Loc, BT.Tolerance(E3));
633 BB.UpdateEdge(E3, NC, S, Loc, BRep_Tool::Tolerance(E3));
634 // B.UpdateEdge(E4, NC, S, Loc, BT.Tolerance(E4));
635 BB.UpdateEdge(E4, NC, S, Loc, BRep_Tool::Tolerance(E4));
640 if (!IsPlan) {// Cas Standard : Ajout
641 BB.MakeFace(F, S, Precision::Confusion());
646 if (ExchUV) F.Reverse();
647 if (UReverse) F.Reverse();
651 //=======================================================================
652 //Fonction : BuildEdge
653 //Objet : Construct non-closed Edge
654 //=======================================================================
655 static TopoDS_Edge BuildEdge(Handle(Geom_Curve)& C3d,
656 Handle(Geom2d_Curve)& C2d,
657 Handle(Geom_Surface)& S,
658 const TopoDS_Vertex& VF,
659 const TopoDS_Vertex& VL,
660 const Standard_Real f,
661 const Standard_Real l,
662 const Standard_Real Tol3d)
665 Standard_Real Tol1, Tol2, Tol, d;
666 // Class BRep_Tool without fields and without Constructor :
672 P1 = BRep_Tool::Pnt(VF);
673 // Tol1 = BT.Tolerance(VF);
674 Tol1 = BRep_Tool::Tolerance(VF);
676 P2 = BRep_Tool::Pnt(VL);
677 // Tol2 = BT.Tolerance(VF);
678 Tol2 = BRep_Tool::Tolerance(VF);
679 Tol = Max(Tol1, Tol2);
682 (P1.Distance(P2) < Tol ) ) {
686 S->D0(P2d.X(), P2d.Y(), P);
688 if (d > Tol) Tol = d;
690 S->D0(P2d.X(), P2d.Y(), P);
692 if (d > Tol) Tol = d;
694 B.UpdateVertex(VF, Tol);
695 B.UpdateVertex(VL, Tol);
698 B.UpdateEdge(E,C2d,S,TopLoc_Location(), Tol);
702 B.Degenerated(E, Standard_True);
710 B.UpdateVertex(VF, d);
713 P1 = BRep_Tool::Pnt(VL);
717 B.UpdateVertex(VL, d);
719 BRepLib_MakeEdge MkE (C3d, VF, VL, f, l);
720 if (!MkE.IsDone()) { // Error of construction !!
723 sprintf(name,"firstvertex_error");
724 DBRep::Set(name, VF);
725 sprintf(name,"lastvertex_error");
726 DBRep::Set(name, VL);
727 sprintf(name,"curve3d_error");
729 DrawTrSurf::Set(Temp, C3d);
730 // DrawTrSurf::Set(name, C3d);
731 Standard_ConstructionError::Raise("BRepFill_Sweep::BuildEdge");
737 B.UpdateEdge(E, C2d, S, Loc, Tol3d);
743 //=======================================================================
745 //Objet : Construct the faces of filling
746 //=======================================================================
747 static Standard_Boolean Filling(const TopoDS_Shape& EF,
748 const TopoDS_Shape& F1,
749 const TopoDS_Shape& EL,
750 const TopoDS_Shape& F2,
751 TopTools_DataMapOfShapeShape& EEmap,
752 const Standard_Real Tol,
754 const gp_Vec& TangentOnPart1,
760 // Class BRep_Tool without fields and without Constructor :
762 // Standard_Integer NbInt =0;
763 // Standard_Real Tol3d = Tol;
764 Standard_Boolean WithE3, WithE4;
766 // Return constraints
767 TopoDS_Vertex V1, V2, Vf, Vl;
768 TopoDS_Edge E1, E2, E3, E4;
769 E1 = TopoDS::Edge(EF);
770 E2 = TopoDS::Edge(EL);
772 TopExp::Vertices(E1, Vf, Vl);
773 Vf.Orientation(TopAbs_FORWARD);
774 Vl.Orientation(TopAbs_FORWARD);
776 TopExp::Vertices(E2, V1, V2);
777 V1.Orientation(TopAbs_REVERSED);
778 V2.Orientation(TopAbs_REVERSED);
783 WithE3 = WithE4 = Standard_False;
785 if ((!Aux1.IsNull()) && (!Vf.IsSame(V1))) {
787 // E3 = TopoDS::Edge(Aux1);
788 WithE3 = Standard_True;
796 else if (!Aux2.IsNull() && (!Vl.IsSame(V2))) {
798 // E4 = TopoDS::Edge(Aux2);
799 WithE4 = Standard_True;
804 DBRep::Set("Fill_Edge1", E1);
805 DBRep::Set("Fill_Edge2", E2);
807 DBRep::Set("Fill_Edge3", E3);
809 DBRep::Set("Fill_Edge4", E4);
813 // Construction of a surface of revolution
814 Handle(Geom_Curve) Prof1, Prof2;
815 //Standard_Integer ii, jj;//, Nb;
816 Standard_Real f1, f2, l1, l2,/*d1, d2,*/ Angle;//, Eps = 1.e-9;
817 // Prof1 = BT.Curve(E1, f1, l1);
818 Prof1 = BRep_Tool::Curve(E1, f1, l1);
819 // Prof2 = BT.Curve(E2, f2, l2);
820 Prof2 = BRep_Tool::Curve(E2, f2, l2);
824 Tf.SetTransformation(Axe);
826 // Choose the angle of opening
827 P1 = Prof1->Value((f1+l1)/2);
828 P2 = Prof2->Value((f2+l2)/2);
831 p1.SetCoord(P1.Z(), P1.X());
832 p2.SetCoord(P2.Z(), P2.X());
833 gp_Vec2d v1(gp::Origin2d(), p1);
834 gp_Vec2d v2(gp::Origin2d(), p2);
835 if (v1.Magnitude() <= gp::Resolution() ||
836 v2.Magnitude() <= gp::Resolution())
837 return Standard_False;
838 Angle = v1.Angle(v2);
840 gp_Ax1 axe(Axe.Location(), Axe.YDirection());
847 Handle(Geom_SurfaceOfRevolution) Rev =
848 new (Geom_SurfaceOfRevolution) (Prof1, axe);
850 Handle(Geom_Surface) Surf =
851 new (Geom_RectangularTrimmedSurface) (Rev, 0, Angle, f1, l1);
853 // Control the direction of the rotation
854 Standard_Boolean ToReverseResult = Standard_False;
856 d1u = Surf->DN(0, (f1+l1)/2, 1, 0);
857 if (d1u.Angle(TangentOnPart1) > M_PI/2) { //Invert everything
858 ToReverseResult = Standard_True;
861 Angle = 2*M_PI - Angle;
862 Rev = new (Geom_SurfaceOfRevolution) (Prof1, axe);
863 Surf = new (Geom_RectangularTrimmedSurface)
864 (Rev, 0, Angle, f1, l1);
870 char* Temp = "Surf_Init" ;
871 DrawTrSurf::Set(Temp, Surf);
875 Handle(Geom2d_Curve) C1, C2, C3, C4;
877 // Deform the surface of revolution.
878 GeomPlate_BuildPlateSurface BPS;
880 Handle(BRepAdaptor_HSurface) AS;
881 Handle(BRepAdaptor_HCurve2d) AC2d;
882 Handle(Adaptor3d_HCurveOnSurface) HConS;
884 Handle(Geom2d_Line) L;
887 L = new (Geom2d_Line) (P2d, gp::DY2d());
888 C1 = new (Geom2d_TrimmedCurve) (L, f1, l1);
890 P2d.SetCoord(Angle,0.);
891 L = new (Geom2d_Line) (P2d, gp::DY2d());
892 C2 = new (Geom2d_TrimmedCurve) (L, f1, l1);
894 // It is required to control the direction and the range.
896 Surf->D0(P2d.X(), P2d.Y(), P1);
898 Surf->D0(P2d.X(), P2d.Y(), P2);
900 P = BRep_Tool::Pnt(V1);
901 if (P.Distance(P2)+Tol < P.Distance(P1)) {
902 // E2 is parsed in the direction opposite to E1
909 GeomLib::SameRange(Precision::PConfusion(), C2,
910 C2->FirstParameter(),
916 P1 = BRep_Tool::Pnt(Vf);
918 P2 = BRep_Tool::Pnt(V1);
919 // pointu_f = Vf.IsSame(V1) || (P1.Distance(P2) < BT.Tolerance(Vf));
921 P1 = BRep_Tool::Pnt(Vl);
923 P2 = BRep_Tool::Pnt(V2);
924 // pointu_l = Vl.IsSame(V2) || (P1.Distance(P2) < BT.Tolerance(Vl));
927 L = new (Geom2d_Line) (P2d, gp::DX2d());
928 C3 = new (Geom2d_TrimmedCurve) (L, 0, Angle);
932 L = new (Geom2d_Line) (P2d, gp::DX2d());
933 C4 = new (Geom2d_TrimmedCurve) (L, 0, Angle);
935 // Determine the constraints and
936 // their parametric localisation.
938 AS = new BRepAdaptor_HSurface(TopoDS::Face(F1));
939 AC2d = new BRepAdaptor_HCurve2d();
940 AC2d->ChangeCurve2d().Initialize(E1,TopoDS::Face(F1));
941 HConS = new (Adaptor3d_HCurveOnSurface)();
942 HConS->ChangeCurve().Load(AC2d);
943 HConS->ChangeCurve().Load(AS);
945 Handle(BRepFill_CurveConstraint) Cont
946 = new BRepFill_CurveConstraint(HConS, 1, 15);
947 Cont->SetCurve2dOnSurf(C1);
950 NbInt = HConS->NbIntervals(GeomAbs_CN);
954 AS = new BRepAdaptor_HSurface(TopoDS::Face(F2));
955 AC2d = new BRepAdaptor_HCurve2d();
956 AC2d->ChangeCurve2d().Initialize(E2,TopoDS::Face(F2));
957 HConS = new (Adaptor3d_HCurveOnSurface);
959 HConS->ChangeCurve().Load(AC2d);
960 HConS->ChangeCurve().Load(AS);
962 Handle(BRepFill_CurveConstraint) Cont
963 = new BRepFill_CurveConstraint(HConS, 1, 15);
964 Cont->SetCurve2dOnSurf(C2);
969 Handle(BRepAdaptor_HCurve) AC = new (BRepAdaptor_HCurve) (E3);
970 Handle(BRepFill_CurveConstraint) Cont
971 = new BRepFill_CurveConstraint(AC, 0);
972 Cont->SetCurve2dOnSurf(C3);
976 Standard_Real delta = Angle / 11;
978 P = BRep_Tool::Pnt(Vf);
979 Handle(GeomPlate_PointConstraint) PC;
980 for (ii=1; ii<=10; ii++) {
981 C3->D0(ii*delta, P2d);
982 PC = new (GeomPlate_PointConstraint) (P, 0);
983 PC->SetPnt2dOnSurf(P2d);
990 Handle(BRepAdaptor_HCurve) AC = new (BRepAdaptor_HCurve) (E4);
991 Handle(BRepFill_CurveConstraint) Cont
992 = new BRepFill_CurveConstraint(AC, 0);
993 Cont->SetCurve2dOnSurf(C4);
997 Standard_Real delta = Angle / 11;
999 P = BRep_Tool::Pnt(Vl);
1000 Handle(GeomPlate_PointConstraint) PC;
1001 for (ii=1; ii<=10; ii++) {
1002 C4->D0(ii*delta, P2d);
1003 PC = new (GeomPlate_PointConstraint) (P, 0);
1004 PC->SetPnt2dOnSurf(P2d);
1009 BPS.LoadInitSurface(Surf);
1012 // Controle s'il y a une deformation effective
1013 Handle(GeomPlate_Surface) plate;
1014 plate = BPS.Surface();
1015 plate->SetBounds(0, Angle, f1, l1);
1016 Standard_Boolean Ok=Standard_True;
1020 for (ii=0; ii<=5 && Ok; ii++) {
1022 for (jj=0; jj<=5 && Ok; jj++) {
1024 plate->D0(u, v, P1);
1026 Ok = (P2.IsEqual(P1, Tol));
1032 // Approx de la plate surface
1033 // Bords naturelles => pas besoin de criteres.
1034 GeomConvert_ApproxSurface App(BPS.Surface(),
1036 GeomAbs_C1, GeomAbs_C1,
1038 if (!App.HasResult()) {
1040 cout << "Filling_Approx : Pas de resultat" << endl;
1042 return Standard_False;
1045 cout << "Filling_Approx Error 3d = " <<
1046 App.MaxError() << endl;
1048 Surf = App.Surface();
1049 Tol3d = App.MaxError();
1054 TopLoc_Location Loc;
1055 Handle(Geom_Curve) C3d;
1056 B.UpdateEdge(E1, C1, Surf, Loc, /*Tol3d*/Precision::Confusion());
1057 B.UpdateEdge(E2, C2, Surf, Loc, /*Tol3d*/Precision::Confusion());
1059 if (E3.IsSame(E4)) {
1062 C3d = Surf->VIso(f1);
1063 E3 = BuildEdge(C3d, C3, Surf, Vf, V1, 0, Angle, /*Tol3d*/Precision::Confusion());
1067 BRepAdaptor_Curve aCurve(E3);
1068 Standard_Real AngleOld = aCurve.LastParameter();
1069 if (Angle > AngleOld)
1071 B.Range( E3, 0, Angle );
1072 TopoDS_Vertex V (TopExp::LastVertex(E3));
1073 Handle(BRep_TVertex)& TVlast = *((Handle(BRep_TVertex)*) &V.TShape());
1074 TVlast->Tolerance( Precision::Confusion() );
1078 B.UpdateEdge(E3, C3, C4, Surf, Loc, /*Tol3d*/Precision::Confusion());
1085 C3d = Surf->VIso(f1);
1086 E3 = BuildEdge(C3d, C3, Surf, Vf, V1, 0, Angle, /*Tol3d*/Precision::Confusion());
1090 BRepAdaptor_Curve aCurve(E3);
1091 Standard_Real AngleOld = aCurve.LastParameter();
1092 if (Angle > AngleOld)
1094 B.Range( E3, 0, Angle );
1095 TopoDS_Vertex V(TopExp::LastVertex(E3));
1096 Handle(BRep_TVertex)& TVlast = *((Handle(BRep_TVertex)*) &V.TShape());
1097 TVlast->Tolerance( Precision::Confusion() );
1100 B.UpdateEdge(E3, C3, Surf, Loc, /*Tol3d*/Precision::Confusion());
1105 C3d = Surf->VIso(l1);
1106 E4 = BuildEdge(C3d, C4, Surf, Vl, V2, 0, Angle, /*Tol3d*/Precision::Confusion());
1110 BRepAdaptor_Curve aCurve(E4);
1111 Standard_Real AngleOld = aCurve.LastParameter();
1112 if (Angle > AngleOld)
1114 B.Range( E4, 0, Angle );
1115 TopoDS_Vertex V (TopExp::LastVertex(E4));
1116 Handle(BRep_TVertex)& TVlast = *((Handle(BRep_TVertex)*)&V.TShape());
1117 TVlast->Tolerance( Precision::Confusion() );
1120 B.UpdateEdge(E4, C4, Surf, Loc, /*Tol3d*/Precision::Confusion());
1125 BuildFace(Surf,E1, E3, E2, E4, EEmap,
1126 Standard_False, Standard_False,
1129 // Set the continuities.
1130 B.Continuity(E1, TopoDS::Face(F1), Result, GeomAbs_G1);
1131 B.Continuity(E2, TopoDS::Face(F2), Result, GeomAbs_G1);
1133 // Render the calculated borders.
1134 // if (!BT.Degenerated(E3))
1135 if (!BRep_Tool::Degenerated(E3))
1138 B.MakeEdge(Aux1); //Nullify
1140 // if (!BT.Degenerated(E4))
1141 if (!BRep_Tool::Degenerated(E4))
1146 // Set the orientation
1147 gp_Vec D1U, D1V, N1, N2;
1148 C1->D0( (f1+l1)/2, P2d);
1149 Surf->D1(P2d.X(), P2d.Y(), P, D1U, D1V);
1152 // C1 = BT.CurveOnSurface(E1, TopoDS::Face(F1), f2, l2);
1153 C1 = BRep_Tool::CurveOnSurface(E1, TopoDS::Face(F1), f2, l2);
1154 C1->D0( (f1+l1)/2, P2d);
1155 Handle(BRepAdaptor_HSurface) AS = new BRepAdaptor_HSurface(TopoDS::Face(F1));
1156 AS->D1(P2d.X(), P2d.Y(), P, D1U, D1V);
1159 if ( (F1.Orientation() == TopAbs_REVERSED) ^ (N1.Angle(N2)>M_PI/2) )
1160 Result.Orientation(TopAbs_REVERSED);
1161 else Result.Orientation(TopAbs_FORWARD);
1163 if (ToReverseResult)
1167 if (Affich) DBRep::Set("BoucheTrou", Result);
1170 return Standard_True;
1173 //=======================================================================
1174 //function : Substitute
1176 //=======================================================================
1177 static void Substitute(BRepTools_Substitution& aSubstitute,
1178 const TopoDS_Edge& Old,
1179 const TopoDS_Edge& New)
1181 TopTools_ListOfShape listShape;
1183 TopoDS_Vertex OldV1, OldV2, NewV1, NewV2;
1184 TopExp::Vertices( Old, OldV1, OldV2 );
1185 TopExp::Vertices( New, NewV1, NewV2 );
1187 if (!aSubstitute.IsCopied( OldV1 ))
1189 listShape.Append( NewV1.Oriented(TopAbs_FORWARD) );
1190 aSubstitute.Substitute( OldV1, listShape );
1193 if (!aSubstitute.IsCopied( OldV2 ))
1195 listShape.Append( NewV2.Oriented(TopAbs_FORWARD) );
1196 aSubstitute.Substitute( OldV2, listShape );
1199 if (!aSubstitute.IsCopied( Old ))
1201 listShape.Append( New.Oriented(TopAbs_FORWARD) );
1202 aSubstitute.Substitute( Old, listShape );
1206 //=======================================================================
1207 //Function : SetCommonEdgeInFace
1208 //Purpose : Replace an edge of the face by the corresponding edge from
1210 //=======================================================================
1212 static void SetCommonEdgeInFace(BRepTools_Substitution& aSubstitute,
1213 const TopoDS_Shape& Face,
1214 const TopoDS_Shape& Edge)
1219 Standard_Boolean done = Standard_False;
1220 // Class BRep_Tool without fields and without Constructor :
1223 TopExp_Explorer Exp(Face, TopAbs_EDGE);
1224 Handle(Geom_Curve) Cref, C;
1225 TopLoc_Location Lref, L;
1226 // Cref = BT.Curve(TopoDS::Edge(Edge), Lref, f, l);
1227 const TopoDS_Edge& NewEdge = TopoDS::Edge(Edge);
1228 Cref = BRep_Tool::Curve( NewEdge, Lref, f, l );
1230 for ( ; Exp.More() && !done; Exp.Next()) {
1231 // C = BT.Curve(TopoDS::Edge(Exp.Current()), L, f, l);
1232 const TopoDS_Edge& OldEdge = TopoDS::Edge(Exp.Current());
1233 C = BRep_Tool::Curve(OldEdge, L, f, l);
1234 if ((Cref==C) && (Lref == L)) {
1235 done = Standard_True;
1236 Substitute( aSubstitute, OldEdge, NewEdge );
1240 if (!done) cout << "Substitution of Edge failed" << endl;
1245 //=======================================================================
1246 //Fonction : KeepEdge
1247 //Objet : Find edges of the face supported by the same Curve.
1248 //=======================================================================
1249 static void KeepEdge(const TopoDS_Shape& Face,
1250 const TopoDS_Shape& Edge,
1251 TopTools_ListOfShape& List)
1254 // Class BRep_Tool without fields and without Constructor :
1257 TopExp_Explorer Exp(Face, TopAbs_EDGE);
1258 Handle(Geom_Curve) Cref, C;
1259 TopLoc_Location Lref, L;
1260 // Cref = BT.Curve(TopoDS::Edge(Edge), Lref, f, l);
1261 Cref = BRep_Tool::Curve(TopoDS::Edge(Edge), Lref, f, l);
1263 for ( ; Exp.More(); Exp.Next()) {
1264 // C = BT.Curve(TopoDS::Edge(Exp.Current()), L, f, l);
1265 C = BRep_Tool::Curve(TopoDS::Edge(Exp.Current()), L, f, l);
1266 if ((Cref==C) && (Lref == L)) {
1267 List.Append(Exp.Current());
1272 //=======================================================================
1274 //Objet : Construct a vertex via an iso
1275 //=======================================================================
1276 static void BuildVertex(const Handle(Geom_Curve)& Iso,
1277 const Standard_Boolean isfirst,
1278 const Standard_Real First,
1279 const Standard_Real Last,
1280 TopoDS_Shape& Vertex)
1285 if (isfirst) val = First;
1287 B.MakeVertex(TopoDS::Vertex(Vertex),
1289 Precision::Confusion());
1292 //=======================================================================
1294 //Objet : Construct an empty edge
1295 //=======================================================================
1296 static TopoDS_Edge NullEdge(TopoDS_Shape& Vertex)
1301 Vertex.Orientation(TopAbs_FORWARD);
1303 B.Add(E, Vertex.Reversed());
1304 B.Degenerated(E, Standard_True);
1309 //=======================================================================
1311 //Objet : Construct an edge via an iso
1312 //=======================================================================
1313 static TopoDS_Edge BuildEdge(const Handle(Geom_Surface)& S,
1314 const Standard_Boolean isUiso,
1315 const Standard_Real ValIso,
1316 const TopoDS_Shape& VFirst,
1317 const TopoDS_Shape& VLast,
1318 const Standard_Real Tol)
1322 Handle(Geom_Curve) Iso;
1323 Standard_Boolean sing = Standard_False;
1325 Iso = S->UIso(ValIso);
1328 Iso = S->VIso(ValIso);
1331 if (VFirst.IsSame(VLast)) { // Singular case ?
1333 // Class BRep_Tool without fields and without Constructor :
1335 const TopoDS_Vertex& V = TopoDS::Vertex(VFirst);
1336 // Standard_Real tol = BT.Tolerance(V);
1337 Standard_Real tol = BRep_Tool::Tolerance(V);
1338 if (Tol > tol) tol = Tol;
1339 Iso->D0((Iso->FirstParameter()+Iso->LastParameter())/2, P);
1340 // if (P.Distance(BT.Pnt(V)) < tol) {
1341 if (P.Distance(BRep_Tool::Pnt(V)) < tol) {
1342 GeomAdaptor_Curve AC(Iso);
1343 sing = GCPnts_AbscissaPoint::Length(AC, tol/4) < tol;
1348 if (sing) { // Singular case
1353 // B.UpdateEdge(E, Iso, Precision::Confusion());
1354 B.Degenerated(E, Standard_True);
1358 // Construction Via 3d
1360 // Iso = S->UIso(ValIso);
1362 Standard_Real p1, p2, p11, p12, p21, p22;
1363 Standard_Boolean fwd = Standard_False;
1364 p1 = Iso->FirstParameter();
1365 p2 = Iso->LastParameter();
1366 P1 = Iso->Value(p1);
1367 P2 = Iso->Value(p2);
1369 Standard_Real t1 = BRep_Tool::Tolerance(TopoDS::Vertex(VFirst));
1370 Standard_Real t2 = BRep_Tool::Tolerance(TopoDS::Vertex(VLast));
1374 p11 = P1.Distance(BRep_Tool::Pnt(TopoDS::Vertex(VFirst)));
1375 p22 = P2.Distance(BRep_Tool::Pnt(TopoDS::Vertex(VLast)));
1376 p12 = P1.Distance(BRep_Tool::Pnt(TopoDS::Vertex(VLast)));
1377 p21 = P2.Distance(BRep_Tool::Pnt(TopoDS::Vertex(VFirst)));
1379 if(p11 < p12 && p22 < p21) fwd = Standard_True;
1381 if(fwd) { //OCC500(apo)
1382 if (p11 >= t1) BB.UpdateVertex(TopoDS::Vertex(VFirst), 1.01*p11);
1383 if (p22 >= t2) BB.UpdateVertex(TopoDS::Vertex(VLast), 1.01*p22);
1386 // Iso = S->VIso(ValIso);
1387 if (p12 >= t2) BB.UpdateVertex(TopoDS::Vertex(VLast), 1.01*p12);
1388 if (p21 >= t1) BB.UpdateVertex(TopoDS::Vertex(VFirst), 1.01*p21);
1391 BRepLib_MakeEdge MkE;
1394 // TopoDS::Vertex(VFirst),
1395 // TopoDS::Vertex(VLast),
1396 // Iso->FirstParameter(),
1397 // Iso->LastParameter());
1400 TopoDS::Vertex(VFirst),
1401 TopoDS::Vertex(VLast),
1402 Iso->FirstParameter(),
1403 Iso->LastParameter());
1406 TopoDS::Vertex(VLast),
1407 TopoDS::Vertex(VFirst),
1408 Iso->FirstParameter(),
1409 Iso->LastParameter());
1411 // if (!MkE.IsDone()) { // Il faut peut etre permuter les Vertex
1413 // TopoDS::Vertex(VLast),
1414 // TopoDS::Vertex(VFirst),
1415 // Iso->FirstParameter(),
1416 // Iso->LastParameter());
1419 if (!MkE.IsDone()) { // Erreur de construction !!
1422 sprintf(name,"firstvertex_error");
1423 DBRep::Set(name, VFirst);
1424 sprintf(name,"lastvertex_error");
1425 DBRep::Set(name, VLast);
1426 sprintf(name,"curve3d_error");
1428 DrawTrSurf::Set(Temp,Iso);
1429 // DrawTrSurf::Set(name,Iso);
1431 Standard_ConstructionError::Raise("BRepFill_Sweep::BuildEdge");
1438 Handle(Geom2d_Line) L;
1439 TopLoc_Location Loc;
1440 Standard_Real Umin, Umax, Vmin, Vmax;
1441 S->Bounds(Umin, Umax, Vmin, Vmax);
1443 //gp_Pnt2d P(ValIso, 0);
1444 gp_Pnt2d P( ValIso, Vmin - Iso->FirstParameter() );
1446 L = new (Geom2d_Line) (P, V);
1449 //gp_Pnt2d P(0., ValIso);
1450 gp_Pnt2d P( Umin -Iso->FirstParameter() , ValIso );
1452 L = new (Geom2d_Line) (P, V);
1455 B.UpdateEdge(E, L, S, Loc, Precision::Confusion());
1456 if (sing) B.Range(E, S, Loc,
1457 Iso->FirstParameter(),
1458 Iso->LastParameter());
1460 Standard_Real MaxTol = 1.e-4;
1461 Standard_Real theTol;
1462 GeomAdaptor_Curve GAiso(Iso);
1463 Handle(GeomAdaptor_HCurve) GAHiso = new GeomAdaptor_HCurve(GAiso);
1464 GeomAdaptor_Surface GAsurf(S);
1465 Handle(GeomAdaptor_HSurface) GAHsurf = new GeomAdaptor_HSurface(GAsurf);
1466 CheckSameParameter( GAHiso, L, GAHsurf, MaxTol, theTol);
1467 B.UpdateEdge(E, theTol);
1472 //=======================================================================
1474 //Objet : Complete an edge via an iso
1475 //=======================================================================
1476 static void UpdateEdge(TopoDS_Edge& E,
1477 const Handle(Geom_Surface)& S,
1478 const Standard_Boolean isUiso,
1479 const Standard_Real ValIso)
1482 Handle(Geom2d_Line) L;
1483 Handle(Geom2d_Curve) PCurve, CL;
1484 TopLoc_Location Loc;
1485 Standard_Real UFirst, ULast, VFirst, VLast, F2d, L2d;
1486 S->Bounds( UFirst, ULast, VFirst, VLast);
1488 Standard_Boolean sing = Standard_False;
1489 Handle(Geom_Curve) Iso;
1491 Iso = S->UIso(ValIso);
1494 Iso = S->VIso(ValIso);
1497 TopoDS_Vertex Vf, Vl;
1498 TopExp::Vertices(E, Vf, Vl);
1499 if (Vf.IsSame(Vl)) { // Singular case ?
1501 Standard_Real tol = BRep_Tool::Tolerance(Vf);
1502 Iso->D0((Iso->FirstParameter()+Iso->LastParameter())/2, Pmid);
1503 if (Pmid.Distance(BRep_Tool::Pnt(Vf)) < tol) {
1504 GeomAdaptor_Curve AC(Iso);
1505 sing = GCPnts_AbscissaPoint::Length(AC, tol/4) < tol;
1510 gp_Pnt2d P(ValIso, 0);
1512 L = new (Geom2d_Line) (P, V);
1517 gp_Pnt2d P(0., ValIso);
1519 L = new (Geom2d_Line) (P, V);
1523 CL = new (Geom2d_TrimmedCurve) (L, F2d, L2d);
1525 // Control direction & Range
1526 Standard_Real R, First, Last, Tol=1.e-4;
1527 Standard_Boolean reverse = Standard_False;;
1530 // Class BRep_Tool without fields and without Constructor :
1534 // BT.Range(E, First, Last);
1535 BRep_Tool::Range(E, First, Last);
1537 if (!Vf.IsSame(Vl)) {
1538 // Test distances between "FirstPoint" and "Vertex"
1539 P2d = CL->Value(F2d);
1540 POnS = S->Value(P2d.X(), P2d.Y());
1541 // reverse = POnS.Distance(BT.Pnt(Vl)) < POnS.Distance(BT.Pnt(Vf));
1542 reverse = POnS.Distance(BRep_Tool::Pnt(Vl)) < POnS.Distance(BRep_Tool::Pnt(Vf));
1545 // Test angle between "First Tangente"
1547 gp_Vec V3d, du, dv, dC3d;
1548 BRepAdaptor_Curve C3d(E);
1550 C3d.D1(First, POnS, dC3d);
1551 CL->D1(F2d, P2d, V2d);
1552 S->D1(P2d.X(), P2d.Y(), POnS, du, dv);
1553 V3d.SetLinearForm(V2d.X(), du, V2d.Y(), dv);
1554 reverse = ( dC3d.Angle(V3d) > Tol);
1556 if (reverse ) { // Return curve 2d
1557 CL = new (Geom2d_TrimmedCurve)(L, F2d, L2d);
1559 F2d = CL->FirstParameter();
1560 L2d = CL->LastParameter();
1565 Handle(Geom_Curve) NullCurve;
1566 B.UpdateEdge(E, NullCurve, 0.);
1567 B.Degenerated(E, Standard_True);
1568 B.Range(E, F2d, L2d);
1573 if (First != F2d || Last != L2d) {
1574 Handle(Geom2d_Curve) C2d;
1575 GeomLib::SameRange(Precision::PConfusion(), CL,
1576 F2d, L2d, First, Last,
1578 CL = new (Geom2d_TrimmedCurve)(C2d, First, Last);
1581 // Update des Vertex
1585 P2d = CL->Value(First);
1586 POnS = S->Value(P2d.X(), P2d.Y());
1587 V = TopExp::FirstVertex(E);
1588 // R = POnS.Distance(BT.Pnt(V));
1589 R = POnS.Distance(BRep_Tool::Pnt(V));
1590 B.UpdateVertex(V, R);
1592 P2d = CL->Value(Last);
1593 POnS = S->Value(P2d.X(), P2d.Y());
1594 V = TopExp::LastVertex(E);
1595 // R = POnS.Distance(BT.Pnt(V));
1596 R = POnS.Distance(BRep_Tool::Pnt(V));
1597 B.UpdateVertex(V, R);
1600 if (!sing && SameParameter(E, CL, S, Tol, R)) {
1604 PCurve = Couture(E, S, Loc);
1605 if (PCurve.IsNull())
1606 B.UpdateEdge(E, CL, S, Loc, Precision::Confusion());
1607 else { // Sewing edge
1610 if (e.Orientation() == TopAbs_REVERSED)
1611 B.UpdateEdge(E, CL, PCurve, S, Loc, Precision::Confusion());
1613 B.UpdateEdge(E, PCurve, CL, S, Loc, Precision::Confusion());
1616 // Attention to case not SameRange on its shapes (PRO13551)
1617 // if (!BT.SameRange(E)) B.Range(E, S, Loc, First, Last);
1618 if (!BRep_Tool::SameRange(E)) B.Range(E, S, Loc, First, Last);
1621 //=======================================================================
1622 // Object : Check if a surface is degenerated
1623 //=======================================================================
1624 static Standard_Boolean IsDegen(const Handle(Geom_Surface)& S,
1625 const Standard_Real Tol)
1627 Standard_Integer Nb = 5;
1628 Standard_Boolean B = Standard_True;
1629 Standard_Real Umax, Umin, Vmax, Vmin, t, dt, l;
1630 Standard_Integer ii;
1631 Handle(Geom_Curve) Iso;
1633 GCPnts_AbscissaPoint GC;
1635 S->Bounds(Umin, Umax, Vmin, Vmax);
1637 // Check the length of Iso-U
1638 t = (Umin + Umax)/2;
1640 S->D0(t, (Vmin+Vmax)/2, P2);
1642 B = ((P1.Distance(P2) + P2.Distance(P3)) < Tol);
1644 for (ii=1, dt = (Umax-Umin)/(Nb+1); B && (ii<=Nb); ii++) {
1647 GeomAdaptor_Curve AC(Iso);
1648 l = GC.Length(AC, Tol/4);
1652 if (B) return Standard_True;
1654 // Check the length of Iso-V
1655 t = (Vmin + Vmax)/2;
1657 S->D0((Umin+Umax)/2, t, P2);
1659 B = ((P1.Distance(P2) + P2.Distance(P3)) < Tol);
1662 for (ii=1, dt = (Vmax-Vmin)/(Nb+1); B && (ii<=Nb); ii++) {
1665 GeomAdaptor_Curve AC(Iso);
1666 l = GC.Length(AC, Tol/4);
1673 //=======================================================================
1674 //function : Constructeur
1676 //======================================================================
1677 BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section,
1678 const Handle(BRepFill_LocationLaw)& Location,
1679 const Standard_Boolean WithKPart) :
1680 isDone(Standard_False),
1688 SetTolerance(1.e-4);
1689 SetAngularControl();
1692 myApproxStyle = GeomFill_Location;
1693 myContinuity = GeomAbs_C2;
1696 myForceApproxC1 = Standard_False;
1699 //=======================================================================
1700 //function : SetBounds
1701 //purpose : Define start and end shapes
1702 //======================================================================
1703 void BRepFill_Sweep::SetBounds(const TopoDS_Wire& First,
1704 const TopoDS_Wire& Last)
1709 // It is necessary to check the SameRange on its (PRO13551)
1711 Standard_Boolean issame = Standard_True;
1714 BRepTools_WireExplorer wexp;
1715 if (!FirstShape.IsNull()) {
1716 for (wexp.Init(FirstShape); wexp.More(); wexp.Next()) {
1717 if (!BRepLib::CheckSameRange(wexp.Current())) {
1718 B.SameRange(wexp.Current(), Standard_False);
1719 B.SameParameter(wexp.Current(), Standard_False);
1721 issame = Standard_False;
1727 if (!LastShape.IsNull()) {
1728 for (wexp.Init(LastShape); wexp.More(); wexp.Next()) {
1729 if (!BRepLib::CheckSameRange(wexp.Current())) {
1730 B.SameRange(wexp.Current(), Standard_False);
1731 B.SameParameter(wexp.Current(), Standard_False);
1733 issame = Standard_False;
1741 cout<<"Sweep Warning : Edge not SameRange in the limits"<<endl;
1745 //=======================================================================
1746 //function : SetTolerance
1748 //======================================================================
1749 void BRepFill_Sweep::SetTolerance(const Standard_Real Tol3d,
1750 const Standard_Real BoundTol,
1751 const Standard_Real Tol2d,
1752 const Standard_Real TolAngular)
1755 myBoundTol = BoundTol;
1757 myTolAngular = TolAngular;
1759 //=======================================================================
1760 //function : SetAngularControl
1762 //======================================================================
1763 void BRepFill_Sweep::SetAngularControl(const Standard_Real MinAngle,
1764 const Standard_Real MaxAngle)
1766 myAngMin = Max (MinAngle, Precision::Angular());
1767 myAngMax = Min (MaxAngle, 6.28);
1770 //=======================================================================
1771 //function : SetForceApproxC1
1772 //purpose : Set the flag that indicates attempt to approximate
1773 // a C1-continuous surface if a swept surface proved
1775 //=======================================================================
1776 void BRepFill_Sweep::SetForceApproxC1(const Standard_Boolean ForceApproxC1)
1778 myForceApproxC1 = ForceApproxC1;
1781 ///=======================================================================
1782 //function : CorrectApproxParameters
1784 //=======================================================================
1785 Standard_Boolean BRepFill_Sweep::CorrectApproxParameters()
1787 TopoDS_Wire thePath = myLoc->Wire();
1788 GeomAbs_Shape NewCont = myContinuity;
1789 Standard_Integer NewSegmax = mySegmax;
1791 TopoDS_Iterator iter(thePath);
1792 for (; iter.More(); iter.Next())
1794 TopoDS_Edge anEdge = TopoDS::Edge(iter.Value());
1795 BRepAdaptor_Curve aBAcurve(anEdge);
1796 GeomAbs_Shape aContinuity = aBAcurve.Continuity();
1797 Standard_Integer aNbInterv = aBAcurve.NbIntervals(GeomAbs_CN);
1798 if (aContinuity < NewCont)
1799 NewCont = aContinuity;
1800 if (aNbInterv > NewSegmax)
1801 NewSegmax = aNbInterv;
1804 Standard_Boolean Corrected = Standard_False;
1805 if (NewCont != myContinuity || NewSegmax != mySegmax)
1806 Corrected = Standard_True;
1807 myContinuity = NewCont;
1808 mySegmax = NewSegmax;
1812 //=======================================================================
1813 //function : BuildWire
1814 //purpose : Construit a wire by sweeping
1815 //======================================================================
1816 Standard_Boolean BRepFill_Sweep::
1817 BuildWire(const BRepFill_TransitionStyle /*Transition*/)
1819 Standard_Integer ipath, isec = 1;
1823 // Class BRep_Tool without fields and without Constructor :
1825 Standard_Integer NbPath = myLoc->NbLaw();
1826 Standard_Boolean vclose;
1827 vclose = (myLoc->IsClosed() && (myLoc->IsG1(0, myTol3d)>= 0));
1829 Handle(Geom_Surface) S;
1830 Handle(Geom_Curve) Iso;
1831 Standard_Real val, bid, First, Last, Tol;
1837 // (1) Construction of all curves
1839 // (1.1) Construction of Tables
1840 myFaces = new (TopTools_HArray2OfShape) (1, 1, 1, NbPath);
1841 myUEdges = new (TopTools_HArray2OfShape) (1, 2, 1, NbPath);
1842 myVEdges = new (TopTools_HArray2OfShape) (1, 1, 1, NbPath+1);
1844 // (1.2) Calculate curves / vertex / edge
1845 for (ipath=1; ipath <=NbPath; ipath++) {
1846 // Curve by iso value
1847 GeomFill_Sweep Sweep(myLoc->Law(ipath), KPart);
1848 Sweep.SetTolerance(myTol3d, myBoundTol, myTol2d, myTolAngular);
1849 Sweep.SetForceApproxC1(myForceApproxC1);
1850 Sweep.Build(mySec->Law(isec), myApproxStyle, myContinuity, myDegmax, mySegmax);
1851 if (!Sweep.IsDone())
1852 return Standard_False;
1853 S = Sweep.Surface();
1854 if (Sweep.ExchangeUV()) {
1855 if (Sweep.UReversed()) S->Bounds(First, Last, bid, val);
1856 else S->Bounds(First, Last, val, bid);
1860 if (Sweep.UReversed()) S->Bounds(bid, val, First, Last);
1861 else S->Bounds(val, bid, First, Last);
1864 // Vertex by position
1866 BuildVertex(Iso, Standard_False, First, Last,
1867 myVEdges->ChangeValue(1, ipath+1));
1870 TopoDS_Vertex& V = TopoDS::Vertex(myVEdges->ChangeValue(1, 1));
1871 myVEdges->SetValue(1, ipath+1, V);
1873 // Tol = P1.Distance(BT.Pnt(V));
1874 Tol = P1.Distance(BRep_Tool::Pnt(V));
1875 B.UpdateVertex(V, Tol);
1878 if (!LastShape.IsNull()) myVEdges->SetValue(1, NbPath, FirstShape);
1879 else BuildVertex(Iso, Standard_False, First, Last,
1880 myVEdges->ChangeValue(1, NbPath+1));
1886 TopoDS_Vertex& V = TopoDS::Vertex(myVEdges->ChangeValue(1, ipath));
1887 // Tol = P1.Distance(BT.Pnt(V));
1888 Tol = P1.Distance(BRep_Tool::Pnt(V));
1889 B.UpdateVertex(V, Tol);
1892 if (!FirstShape.IsNull()) myVEdges->SetValue(1,1, FirstShape);
1893 else BuildVertex(Iso, Standard_True, First, Last,
1894 myVEdges->ChangeValue(1, 1));
1897 // Construction of the edge
1898 BRepLib_MakeEdge MkE;
1900 TopoDS::Vertex(myVEdges->Value(1, ipath)),
1901 TopoDS::Vertex(myVEdges->Value(1, ipath+1)),
1902 Iso->FirstParameter(),
1903 Iso->LastParameter());
1904 if (!MkE.IsDone()) { // Error of construction !!
1907 sprintf(name,"firstvertex_error");
1908 DBRep::Set(name, myVEdges->Value(1, ipath));
1909 sprintf(name,"lastvertex_error");
1910 DBRep::Set(name, myVEdges->Value(1, ipath+1));
1911 sprintf(name,"curve3d_error");
1913 DrawTrSurf::Set(Temp,Iso);
1914 // DrawTrSurf::Set(name,Iso);
1915 Standard_ConstructionError::Raise("BRepFill_Sweep::BuildEdge");
1917 return Standard_False;
1922 sprintf(name,"Surf_%d", ipath);
1924 DrawTrSurf::Set(Temp, S);
1925 // DrawTrSurf::Set(name, S);
1926 sprintf(name,"Edge_%d", ipath);
1927 DBRep::Set(name, E);
1930 B.UpdateEdge(E, Sweep.ErrorOnSurface());
1932 myFaces->SetValue(1, ipath, E);
1935 return Standard_True;
1938 //=======================================================================
1939 //function : BuildShell
1940 //purpose : Construct a Shell by sweeping
1941 //======================================================================
1942 Standard_Boolean BRepFill_Sweep::
1943 BuildShell(const BRepFill_TransitionStyle /*Transition*/,
1944 const Standard_Integer IFirst,
1945 const Standard_Integer ILast,
1946 TopTools_MapOfShape& ReversedEdges,
1947 BRepFill_DataMapOfShapeHArray2OfShape& Tapes,
1948 BRepFill_DataMapOfShapeHArray2OfShape& Rails,
1949 const Standard_Real ExtendFirst,
1950 const Standard_Real ExtendLast)
1952 Standard_Integer ipath, isec, IPath;
1957 Standard_Integer NbPath = ILast - IFirst;
1958 Standard_Integer NbLaw = mySec->NbLaw();
1959 Standard_Boolean uclose, vclose, constSection, hasdegen = Standard_False;
1960 constSection = mySec->IsConstant();
1961 uclose = mySec->IsUClosed();
1962 vclose = (mySec->IsVClosed() && myLoc->IsClosed()) &&
1963 (NbPath == myLoc->NbLaw()) && (myLoc->IsG1(0, myTol3d)>= 0);
1966 // (1) Construction of all surfaces
1968 // (1.1) Construction of Tables
1970 TColStd_Array2OfInteger ExchUV(1, NbLaw, 1, NbPath);
1971 TColStd_Array2OfInteger UReverse(1, NbLaw, 1, NbPath);
1972 TColStd_Array2OfInteger Degenerated(1, NbLaw, 1, NbPath);
1973 Degenerated.Init(0);
1974 // No VReverse for the moment...
1975 TColStd_Array2OfReal TabErr(1, NbLaw , 1, NbPath);
1976 TColGeom_Array2OfSurface TabS(1, NbLaw , 1, NbPath);
1978 TopTools_Array2OfShape UEdge(1, NbLaw+1, 1, NbPath);
1979 TopTools_Array2OfShape VEdge(1, NbLaw , 1, NbPath+1);
1980 TopTools_Array2OfShape Vertex(1,NbLaw+1, 1, NbPath+1);
1982 TopoDS_Vertex VNULL;
1986 TopTools_Array1OfShape SecVertex(1, NbLaw+1);
1987 TColStd_Array1OfReal VError(1, NbLaw+1);
1988 TColStd_Array1OfReal Vi(1, NbPath+1);
1990 //Initialization of management of parametric intervals
1991 //(Case of evolutionary sections)
1992 Standard_Real Length, SecDom, SecDeb;
1993 myLoc->CurvilinearBounds(myLoc->NbLaw(), SecDom, Length);
1994 mySec->Law(1)->GetDomain(SecDeb, SecDom);
1997 Standard_Real Lf, Ll;
1998 myLoc->CurvilinearBounds(IFirst-1, Lf, Ll);
1999 Vi(1) = SecDeb + (Ll/Length)*SecDom;
2004 // Error a priori on vertices
2006 for (isec=1; isec<=NbLaw+1; isec++) {
2007 VError(isec) = mySec->VertexTol(isec-1, 0.);
2008 SecVertex(isec) = mySec->Vertex(isec, 0.);
2013 // (1.2) Calculate surfaces
2014 for (ipath=1, IPath=IFirst; ipath <=NbPath; ipath++, IPath++) {
2016 GeomFill_Sweep Sweep(myLoc->Law(IPath), KPart);
2017 Sweep.SetTolerance(myTol3d, myBoundTol, myTol2d, myTolAngular);
2018 Sweep.SetForceApproxC1(myForceApproxC1);
2020 // Case of evolutionary section, definition of parametric correspondence
2021 if (!constSection) {
2022 Standard_Real lf, ll, Lf, Ll;
2023 myLoc->Law(IPath)->GetDomain(lf, ll);
2024 myLoc->CurvilinearBounds(IPath, Lf, Ll);
2025 Vi(ipath+1) = SecDeb + (Ll/Length)*SecDom;
2026 Sweep.SetDomain(lf, ll, Vi(ipath), Vi(ipath+1));
2028 else //section is constant
2030 Standard_Real lf, ll, Lf, Ll;
2031 myLoc->Law(IPath)->GetDomain(lf, ll);
2032 myLoc->CurvilinearBounds(IPath, Lf, Ll);
2033 Vi(ipath+1) = SecDeb + (Ll/Length)*SecDom;
2036 for(isec=1; isec<=NbLaw; isec++) {
2037 Sweep.Build(mySec->Law(isec), myApproxStyle, myContinuity, myDegmax, mySegmax);
2038 if (!Sweep.IsDone())
2039 return Standard_False;
2040 TabS(isec,ipath) = Sweep.Surface();
2041 TabErr(isec,ipath) = Sweep.ErrorOnSurface();
2042 ExchUV(isec, ipath) = Sweep.ExchangeUV();
2043 UReverse(isec, ipath) = Sweep.UReversed();
2044 if (Sweep.ErrorOnSurface()>Error) Error = Sweep.ErrorOnSurface();
2046 if ((ipath==1)&&(ExtendFirst>0)) {
2047 Handle(Geom_BoundedSurface) BndS;
2048 BndS = Handle(Geom_BoundedSurface)::DownCast(TabS(isec,ipath));
2049 GeomLib::ExtendSurfByLength(BndS, ExtendFirst, 1,
2050 Sweep.ExchangeUV(), Standard_False);
2051 TabS(isec,ipath) = BndS;
2053 if ((ipath==NbPath)&&(ExtendLast>0)){
2054 Handle(Geom_BoundedSurface) BndS;
2055 BndS = Handle(Geom_BoundedSurface)::DownCast(TabS(isec,ipath));
2056 GeomLib::ExtendSurfByLength(BndS, ExtendLast, 1,
2057 Sweep.ExchangeUV(), Standard_True);
2058 TabS(isec,ipath) = BndS;
2063 sprintf(name,"Surf_%d_%d", isec, IPath);
2065 DrawTrSurf::Set(Temp, TabS(isec,ipath));
2071 // (2) Construction of Edges
2072 Standard_Real UFirst, ULast, VFirst, VLast;
2073 Standard_Boolean exuv, singu, singv;
2074 Handle(Geom_Surface) S;
2076 // (2.0) return preexisting Edges and vertices
2078 TColStd_Array1OfBoolean IsBuilt(1, NbLaw);
2079 IsBuilt.Init(Standard_False);
2080 TopTools_Array1OfShape StartEdges(1, NbLaw);
2081 if (! FirstShape.IsNull() && (IFirst==1)) {
2082 mySec->Init(FirstShape);
2083 for (isec=1; isec<=NbLaw; isec++) {
2084 E = mySec->CurrentEdge();
2085 TopoDS_Vertex Vfirst, Vlast;
2086 TopExp::Vertices(E, Vfirst, Vlast);
2088 if (E.Orientation() == TopAbs_REVERSED)
2089 Vertex(isec+1, 1) = Vfirst; //TopExp::FirstVertex(E);
2091 Vertex(isec+1, 1) = Vlast; //TopExp::LastVertex(E);
2092 UpdateVertex(IFirst-1, isec+1,
2093 TabErr(isec, 1), Vi(1), Vertex(isec+1, 1));
2095 StartEdges(isec) = E;
2096 if (Tapes.IsBound(E))
2098 IsBuilt(isec) = Standard_True;
2100 //Initialize VEdge, UEdge, Vertex and myFaces
2102 for (j = 1; j <= NbPath+1; j++)
2104 VEdge(isec, j) = Tapes(E)->Value(1, j);
2105 VEdge(isec, j).Reverse(); //direction of round is reversed
2107 Standard_Integer ifirst = isec+1, ilast = isec; //direction of round is reversed
2108 for (j = 1; j <= NbPath; j++)
2109 UEdge(ifirst, j) = Tapes(E)->Value(2, j);
2110 for (j = 1; j <= NbPath; j++)
2111 UEdge(ilast, j) = Tapes(E)->Value(3, j);
2112 for (j = 1; j <= NbPath+1; j++)
2113 Vertex(ifirst, j) = Tapes(E)->Value(4, j);
2114 for (j = 1; j <= NbPath+1; j++)
2115 Vertex(ilast, j) = Tapes(E)->Value(5, j);
2116 for (j = 1; j <= NbPath; j++)
2117 myFaces->SetValue(isec, j, Tapes(E)->Value(6, j));
2119 if (uclose && isec == 1)
2121 for (j = 1; j <= NbPath; j++)
2122 UEdge(NbLaw+1, j) = UEdge(1, j);
2123 for (j = 1; j <= NbPath+1; j++)
2124 Vertex(NbLaw+1, j) = Vertex(1, j);
2126 if (uclose && isec == NbLaw)
2128 for (j = 1; j <= NbPath; j++)
2129 UEdge(1, j) = UEdge(NbLaw+1, j);
2130 for (j = 1; j <= NbPath+1; j++)
2131 Vertex(1, j) = Vertex(NbLaw+1, j);
2136 Handle(TopTools_HArray2OfShape) EmptyArray = new TopTools_HArray2OfShape(1, 6, 1, NbPath+1);
2137 Tapes.Bind(E, EmptyArray);
2139 if (Rails.IsBound(Vfirst))
2141 Standard_Integer ind = (E.Orientation() == TopAbs_REVERSED)? isec+1 : isec;
2142 for (j = 1; j <= NbPath; j++)
2143 UEdge(ind, j) = Rails(Vfirst)->Value(1, j);
2144 for (j = 1; j <= NbPath+1; j++)
2145 Vertex(ind, j) = Rails(Vfirst)->Value(2, j);
2147 if (Rails.IsBound(Vlast))
2149 Standard_Integer ind = (E.Orientation() == TopAbs_FORWARD)? isec+1 : isec;
2150 for (j = 1; j <= NbPath; j++)
2151 UEdge(ind, j) = Rails(Vlast)->Value(1, j);
2152 for (j = 1; j <= NbPath+1; j++)
2153 Vertex(ind, j) = Rails(Vlast)->Value(2, j);
2158 if (VEdge(1, 1).Orientation() == TopAbs_REVERSED)
2159 Vertex(1, 1) = TopExp::LastVertex(TopoDS::Edge(VEdge(1, 1)));
2161 Vertex(1, 1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(1, 1)));
2162 UpdateVertex(IFirst-1, 1,
2163 TabErr(1, 1), Vi(1), Vertex(1, 1));
2166 Standard_Real u, v, aux;
2167 Standard_Boolean ureverse;
2168 for (isec=1; isec<=NbLaw+1; isec++) {
2172 ureverse = UReverse(NbLaw, 1);
2173 exuv = ExchUV(NbLaw, 1);
2177 ureverse = UReverse(isec, 1);
2178 exuv = ExchUV(isec, 1);
2180 S->Bounds(UFirst, ULast, VFirst, VLast);
2182 // Choice of parameters
2185 aux = VFirst; VFirst = VLast; VLast = aux;
2188 aux = UFirst; UFirst = ULast; ULast = aux;
2191 if (isec!= NbLaw+1) {
2206 // construction of vertices
2207 if (Vertex(isec, 1).IsNull())
2208 B.MakeVertex(TopoDS::Vertex(Vertex(isec, 1)),
2210 mySec->VertexTol(isec-1,Vi(1)));
2213 TopLoc_Location Identity;
2214 Vertex(isec, 1).Location(Identity);
2215 B.UpdateVertex(TopoDS::Vertex(Vertex(isec, 1)),
2217 mySec->VertexTol(isec-1,Vi(1)));
2219 } //end of for (isec=1; isec<=NbLaw+1; isec++)
2221 if (! LastShape.IsNull() && (ILast==myLoc->NbLaw()+1) ) {
2222 mySec->Init(LastShape);
2223 for (isec=1; isec<=NbLaw; isec++) {
2224 E = mySec->CurrentEdge();
2225 if (VEdge(isec, NbPath+1).IsNull())
2226 VEdge(isec, NbPath+1) = E;
2228 if (Vertex(isec+1, NbPath+1).IsNull())
2230 if (VEdge(isec, NbPath+1).Orientation() == TopAbs_REVERSED)
2231 Vertex(isec+1, NbPath+1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(isec, NbPath+1)));
2233 Vertex(isec+1, NbPath+1) = TopExp::LastVertex(TopoDS::Edge(VEdge(isec, NbPath+1)));
2235 UpdateVertex(ILast-1, isec+1, TabErr(isec, NbPath),
2236 Vi(NbPath+1), Vertex(isec+1, NbPath+1));
2239 if (Vertex(1, NbPath+1).IsNull())
2241 if (VEdge(1, NbPath+1).Orientation() == TopAbs_REVERSED)
2242 Vertex(1, NbPath+1) = TopExp::LastVertex(TopoDS::Edge(VEdge(1, NbPath+1)));
2244 Vertex(1, NbPath+1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(1, NbPath+1)));
2246 UpdateVertex(ILast-1, 1,
2247 TabErr(1, NbPath), Vi(NbPath+1), Vertex(1, NbPath+1 ));
2250 for (isec=1; isec<=NbLaw+1; isec++) {
2253 S = TabS(NbLaw, NbPath);
2254 ureverse = UReverse(NbLaw, NbPath);
2255 exuv = ExchUV(NbLaw, NbPath);
2258 S = TabS(isec, NbPath);
2259 ureverse = UReverse(isec, NbPath);
2260 exuv = ExchUV(isec, NbPath);
2262 S->Bounds(UFirst, ULast, VFirst, VLast);
2264 // Choice of parametres
2267 aux = VFirst; VFirst = VLast; VLast = aux;
2270 aux = UFirst; UFirst = ULast; ULast = aux;
2273 if (isec == NbLaw+1) {
2288 // construction of vertex
2289 if (Vertex(isec, NbPath+1).IsNull())
2290 B.MakeVertex(TopoDS::Vertex(Vertex(isec, NbPath+1)),
2292 mySec->VertexTol(isec-1, Vi(NbPath+1)));
2295 TopLoc_Location Identity;
2296 Vertex(isec, NbPath+1).Location(Identity);
2297 B.UpdateVertex(TopoDS::Vertex(Vertex(isec, NbPath+1)),
2299 mySec->VertexTol(isec-1, Vi(NbPath+1)));
2301 } //end of for (isec=1; isec<=NbLaw+1; isec++)
2304 // ---------- Creation of Vertex and edge ------------
2305 ReversedEdges.Clear();
2306 for (ipath=1, IPath=IFirst; ipath<=NbPath;
2308 for (isec=1; isec <=NbLaw; isec++) {
2312 S = TabS(isec, ipath);
2313 exuv = ExchUV(isec, ipath);
2314 S->Bounds(UFirst, ULast, VFirst, VLast);
2315 if (UReverse(isec, ipath)) {
2318 aux = VFirst; VFirst = VLast; VLast = aux;
2321 aux = UFirst; UFirst = ULast; ULast = aux;
2325 // (2.1) Construction of new vertices
2327 if (ipath == 1 && Vertex(1, 1).IsNull()) {
2330 myLoc->PerformVertex(IPath-1,
2331 TopoDS::Vertex(SecVertex(1)),
2333 TopoDS::Vertex(Vertex(1, 1)));
2335 myLoc->PerformVertex(IPath-1,
2336 mySec->Vertex(1,Vi(1)),
2337 mySec->VertexTol(0,Vi(1)),
2338 TopoDS::Vertex(Vertex(1, 1)));
2340 // the first and the next column
2341 if (vclose &&(ipath == NbPath) ) {
2342 Vertex(1, ipath+1) = Vertex(1, 1);
2344 else if (Vertex(1, ipath+1).IsNull()) {
2346 myLoc->PerformVertex(IPath,
2347 TopoDS::Vertex(SecVertex(1)),
2348 TabErr(1,ipath)+VError(1),
2349 TopoDS::Vertex(Vertex(1, ipath+1)) );
2351 myLoc->PerformVertex(IPath,
2352 mySec->Vertex(1,Vi(ipath+1)),
2354 mySec->VertexTol(0,Vi(ipath+1)),
2355 TopoDS::Vertex(Vertex(1, ipath+1)));
2357 if (MergeVertex(Vertex(1,ipath), Vertex(1,ipath+1))) {
2358 UEdge(1, ipath) = NullEdge(Vertex(1,ipath));
2364 if (uclose && (isec == NbLaw)) {
2365 Vertex(isec+1, 1) = Vertex(1, 1);
2367 else if (Vertex(isec+1, 1).IsNull()) {
2369 myLoc->PerformVertex(IPath-1,
2370 TopoDS::Vertex(SecVertex(isec+1)),
2371 TabErr(isec,1)+VError(isec+1),
2372 TopoDS::Vertex(Vertex(isec+1, 1)) );
2374 myLoc->PerformVertex(IPath-1,
2375 mySec->Vertex(isec+1,Vi(1)),
2377 mySec->VertexTol(isec,Vi(1)),
2378 TopoDS::Vertex(Vertex(isec+1, 1)) );
2380 if (MergeVertex(Vertex(isec,1), Vertex(isec+1,1))) {
2381 VEdge(isec, 1) = NullEdge(Vertex(isec, 1));
2386 if (uclose && (isec == NbLaw)) {
2387 Vertex(isec+1, ipath+1) = Vertex(1, ipath+1);
2389 else if (vclose && (ipath == NbPath)) {
2390 Vertex(isec+1, ipath+1) = Vertex(isec+1, 1);
2392 else if (Vertex(isec+1, ipath+1).IsNull()) {
2394 myLoc->PerformVertex(IPath,
2395 TopoDS::Vertex(SecVertex(isec+1)),
2396 TabErr(isec, ipath)+ VError(isec+1),
2397 TopoDS::Vertex(Vertex(isec+1, ipath+1)) );
2399 myLoc->PerformVertex(IPath,
2400 mySec->Vertex(isec+1,Vi(ipath+1)),
2401 TabErr(isec, ipath) +
2402 mySec->VertexTol(isec, Vi(ipath+1)),
2403 TopoDS::Vertex(Vertex(isec+1, ipath+1)) );
2407 singv = MergeVertex(Vertex(isec,ipath+1), Vertex(isec+1,ipath+1));
2408 singu = MergeVertex(Vertex(isec+1,ipath), Vertex(isec+1,ipath+1));
2412 if (singu || singv) {
2413 Degenerated(isec, ipath) = IsDegen(TabS(isec,ipath),
2414 Max(myTol3d, TabErr(isec,ipath)));
2416 if (Degenerated(isec, ipath)) {
2418 cout << "Sweep : Degenerated case" << endl;
2420 hasdegen = Standard_True;
2421 // Particular construction of edges
2422 if (UEdge(isec+1, ipath).IsNull()) {
2425 UEdge(isec+1, ipath) = NullEdge(Vertex(isec+1,ipath));
2427 else { // Copy the previous edge
2428 UEdge(isec+1, ipath) = UEdge(isec, ipath);
2431 if (VEdge(isec, ipath+1).IsNull()) {
2434 VEdge(isec, ipath+1) = NullEdge(Vertex(isec,ipath+1));
2436 else { // Copy the previous edge
2437 VEdge(isec, ipath+1) = VEdge(isec, ipath);
2441 else { // Construction of edges by isos
2444 UV = UFirst; UFirst = VFirst; VFirst = UV;
2445 UV = ULast ; ULast = VLast ; VLast = UV;
2449 if (isec == 1 && UEdge(1, ipath).IsNull()) {
2450 if (!Vertex(1,ipath).IsSame(Vertex(1,ipath+1))) {
2451 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(Vertex(1,ipath)));
2452 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(Vertex(1,ipath+1)));
2453 if (P1.Distance(P2) <= myTol3d)
2454 Vertex(1,ipath+1) = Vertex(1,ipath);
2456 UEdge(1, ipath) = BuildEdge(S, !exuv, UFirst,
2463 if (UEdge(isec, ipath).IsNull()) //sweep failed
2464 return Standard_False;
2465 UpdateEdge(TopoDS::Edge(UEdge(isec, ipath)),
2469 if (uclose && (isec==NbLaw)) {
2470 if (UEdge(1, ipath).IsNull()) //degenerated case
2472 UEdge(isec+1, ipath) = BuildEdge(S, !exuv, ULast,
2473 Vertex(isec+1, ipath),
2474 Vertex(isec+1, ipath+1),
2478 UpdateEdge(TopoDS::Edge(UEdge(1, ipath)),
2480 UEdge(isec+1, ipath) = UEdge(1, ipath);
2484 if (UEdge(isec+1, ipath).IsNull())
2485 UEdge(isec+1, ipath) = BuildEdge(S, !exuv, ULast,
2486 Vertex(isec+1, ipath),
2487 Vertex(isec+1, ipath+1),
2490 UpdateEdge(TopoDS::Edge(UEdge(isec+1, ipath)), S, !exuv, ULast);
2496 TopoDS_Edge aNewFirstEdge = BuildEdge(S, exuv, VFirst,
2500 if (VEdge(isec, ipath).IsNull())
2501 VEdge(isec, ipath) = aNewFirstEdge;
2502 else //rebuild first edge
2504 RebuildTopOrBottomEdge(aNewFirstEdge,
2505 TopoDS::Edge(VEdge(isec, ipath)),
2507 if (ReversedEdges.Contains(VEdge(isec, ipath)))
2508 StartEdges(isec).Reverse();
2512 else UpdateEdge(TopoDS::Edge(VEdge(isec, ipath)),
2515 if (vclose && (ipath == NbPath)) {
2516 if (VEdge(isec, 1).IsNull()) //degenerated case
2518 VEdge(isec, ipath+1) = BuildEdge(S, exuv, VLast,
2519 Vertex(isec , ipath+1),
2520 Vertex(isec+1, ipath+1),
2524 UpdateEdge(TopoDS::Edge(VEdge(isec, 1)),
2526 VEdge(isec, ipath+1) = VEdge(isec, 1);
2529 else if (VEdge(isec, ipath+1).IsNull())
2530 VEdge(isec, ipath+1) = BuildEdge(S, exuv, VLast,
2531 Vertex(isec , ipath+1),
2532 Vertex(isec+1, ipath+1),
2536 if (ipath != NbPath || vclose)
2537 UpdateEdge(TopoDS::Edge(VEdge(isec, ipath+1)),
2539 else //ipath == NbPath && !vclose => rebuild last edge
2541 TopoDS_Edge aNewLastEdge = BuildEdge(S, exuv, VLast,
2542 Vertex(isec , ipath+1),
2543 Vertex(isec+1, ipath+1),
2545 RebuildTopOrBottomEdge(aNewLastEdge,
2546 TopoDS::Edge(VEdge(isec, ipath+1)),
2551 }// End of construction of edges
2554 // (3) Construction of Faces
2559 for (ipath=1, IPath=IFirst; ipath<=NbPath; ipath++, IPath++) {
2560 for (isec=1; isec <=NbLaw+1; isec++){
2561 sprintf(name,"uedge_%d_%d", isec, IPath);
2562 DBRep::Set(name,UEdge(isec, ipath));
2566 for (ipath=1, IPath=IFirst; ipath<=NbPath+1; ipath++, IPath++) {
2567 for (isec=1; isec <=NbLaw; isec++){
2568 sprintf(name,"vedge_%d_%d", isec, IPath);
2569 DBRep::Set(name,VEdge(isec, ipath));
2572 for (isec=1; isec <=NbLaw+1; isec++){
2573 sprintf(name,"vertex_%d_%d", isec, IPath);
2574 DBRep::Set(name,Vertex(isec, ipath));
2580 for (ipath=1, IPath=IFirst; ipath<=NbPath; ipath++, IPath++) {
2581 for (isec=1; isec <=NbLaw; isec++) {
2582 if (Degenerated(isec, ipath)) {
2583 if (UEdge(isec, ipath).IsSame(UEdge(isec+1, ipath)))
2584 myFaces->SetValue(isec, IPath, UEdge(isec, ipath));
2586 myFaces->SetValue(isec, IPath, VEdge(isec, ipath));
2588 else if (myFaces->Value(isec, IPath).IsNull()) {
2589 BuildFace(TabS(isec,ipath),
2590 TopoDS::Edge(UEdge(isec, ipath)),
2591 TopoDS::Edge(VEdge(isec, ipath)),
2592 TopoDS::Edge(UEdge(isec+1, ipath)),
2593 TopoDS::Edge(VEdge(isec, ipath+1)),
2595 ExchUV(isec, ipath),
2596 UReverse(isec, ipath),
2598 myFaces->SetValue(isec, IPath, face);
2603 // (3.1) Reverse the faces that have been built ealier
2604 for (ipath = 1; ipath <= NbPath; ipath++)
2605 for (isec = 1; isec <= NbLaw; isec++)
2607 myFaces->ChangeValue(isec, ipath).Reverse();
2610 // (4) History and Continuity
2613 //(4.1) // Degenerated case => Sledgehammer
2614 TopoDS_Compound Comp;
2615 B.MakeCompound(Comp);
2616 for (isec=1; isec <= NbLaw+1; isec++)
2617 for (ipath=1, IPath=IFirst; ipath<= NbPath+1; ipath++, IPath++) {
2618 if (ipath <= NbPath) myUEdges->SetValue(isec, IPath, UEdge(isec, ipath));
2619 if (isec <= NbLaw) myVEdges->SetValue(isec, IPath, VEdge(isec, ipath));
2620 if ((ipath <= NbPath) && (isec <= NbLaw) &&
2621 (myFaces->Value(isec, IPath).ShapeType() == TopAbs_FACE))
2622 B.Add(Comp, myFaces->Value(isec, IPath));
2624 BRepLib::EncodeRegularity(Comp, myTolAngular);
2627 //(4.2) // General case => Tweezers
2628 Standard_Boolean isG1;
2632 for (isec=1; isec <= NbLaw+1; isec++) {
2634 (mySec->Continuity(isec-1, myTolAngular) >= GeomAbs_G1);
2635 else isG1 = Standard_False;
2636 for (ipath=1, IPath=IFirst; ipath<= NbPath; ipath++, IPath++) {
2637 myUEdges->SetValue(isec, IPath, UEdge(isec, ipath));
2639 if (isec == NbLaw+1) FF = TopoDS::Face(myFaces->Value(1, IPath));
2640 else FF = TopoDS::Face(myFaces->Value(isec, IPath));
2641 B.Continuity(TopoDS::Edge(myUEdges->Value(isec, IPath)),
2642 TopoDS::Face(myFaces->Value(isec-1, IPath)),
2648 Standard_Integer nbpath = NbPath;
2649 if (vclose) nbpath++; //Another test G1
2650 for (ipath=1, IPath=IFirst; ipath<= NbPath+1; ipath++, IPath++) {
2651 if ((ipath > 1) && (ipath <=nbpath))
2652 isG1 = (myLoc->IsG1(IPath-1, myTol3d, myTolAngular) >= 0);
2653 else isG1 = Standard_False;
2654 for (isec=1; isec <= NbLaw; isec++) {
2655 myVEdges->SetValue(isec, IPath, VEdge(isec, ipath));
2657 if (ipath==NbPath+1) FF = TopoDS::Face(myFaces->Value(isec, 1));
2658 else FF = TopoDS::Face(myFaces->Value(isec, IPath));
2659 E = TopoDS::Edge(myVEdges->Value(isec, IPath));
2660 BRepLib::EncodeRegularity(E, FF,
2661 TopoDS::Face(myFaces->Value(isec, IPath-1)),
2668 // (5) Update Tapes and Rails
2670 if (IFirst == 1 && !Tapes.IsEmpty()) //works only in case of single shell
2672 for (isec = 1; isec <= NbLaw; isec++)
2674 for (j = 1; j <= NbPath+1; j++)
2675 Tapes(StartEdges(isec))->SetValue(1, j, myVEdges->Value(isec, j));
2676 for (j = 1; j <= NbPath; j++)
2677 Tapes(StartEdges(isec))->SetValue(2, j, myUEdges->Value(isec, j));
2678 for (j = 1; j <= NbPath; j++)
2679 Tapes(StartEdges(isec))->SetValue(3, j, myUEdges->Value(isec+1, j));
2680 for (j = 1; j <= NbPath+1; j++)
2681 Tapes(StartEdges(isec))->SetValue(4, j, Vertex(isec, j));
2682 for (j = 1; j <= NbPath+1; j++)
2683 Tapes(StartEdges(isec))->SetValue(5, j, Vertex(isec+1, j));
2684 for (j = 1; j <= NbPath; j++)
2685 Tapes(StartEdges(isec))->SetValue(6, j, myFaces->Value(isec, j));
2686 TopoDS_Vertex Vfirst, Vlast;
2687 TopExp::Vertices(TopoDS::Edge(StartEdges(isec)), Vfirst, Vlast, Standard_True); //with orientation
2688 if (!Rails.IsBound(Vfirst))
2690 Handle(TopTools_HArray2OfShape) anArray = new TopTools_HArray2OfShape(1, 2, 1, NbPath+1);
2691 for (j = 1; j <= NbPath; j++)
2692 anArray->SetValue(1, j, myUEdges->Value(isec, j));
2693 for (j = 1; j <= NbPath+1; j++)
2694 anArray->SetValue(2, j, Vertex(isec, j));
2695 Rails.Bind(Vfirst, anArray);
2697 if (!Rails.IsBound(Vlast))
2699 Handle(TopTools_HArray2OfShape) anArray = new TopTools_HArray2OfShape(1, 2, 1, NbPath+1);
2700 for (j = 1; j <= NbPath; j++)
2701 anArray->SetValue(1, j, myUEdges->Value(isec+1, j));
2702 for (j = 1; j <= NbPath+1; j++)
2703 anArray->SetValue(2, j, Vertex(isec+1, j));
2704 Rails.Bind(Vlast, anArray);
2709 return Standard_True;
2712 //=======================================================================
2714 //purpose : Construt the result of sweeping
2715 //======================================================================
2716 void BRepFill_Sweep::Build(TopTools_MapOfShape& ReversedEdges,
2717 BRepFill_DataMapOfShapeHArray2OfShape& Tapes,
2718 BRepFill_DataMapOfShapeHArray2OfShape& Rails,
2719 const BRepFill_TransitionStyle Transition,
2720 const GeomAbs_Shape Continuity,
2721 const GeomFill_ApproxStyle Approx,
2722 const Standard_Integer Degmax,
2723 const Standard_Integer Segmax)
2725 myContinuity = Continuity;
2726 myApproxStyle = Approx;
2730 CorrectApproxParameters();
2733 if (mySec->IsVertex()) isDone = BuildWire(Transition);
2736 Standard_Integer NbTrous = myLoc->NbHoles(myTol3d),
2737 NbPath = myLoc->NbLaw(),
2738 NbLaw = mySec->NbLaw(), ii, jj, NbPart=1;
2739 Standard_Integer ipath, isec;
2741 myUEdges = new (TopTools_HArray2OfShape) (1, NbLaw+1, 1, NbPath);
2742 myVEdges = new (TopTools_HArray2OfShape) (1, NbLaw, 1, NbPath+1);
2743 myFaces = new (TopTools_HArray2OfShape) (1, NbLaw, 1, NbPath);
2744 Handle (TopTools_HArray2OfShape) Bounds =
2745 new (TopTools_HArray2OfShape) (1, NbLaw, 1, 2);
2747 Handle(TColStd_HArray1OfInteger) Trous;
2749 if (NbTrous>0) { // How many sub-parts ?
2750 Trous = new (TColStd_HArray1OfInteger) (1, NbTrous);
2751 myLoc->Holes(Trous->ChangeArray1());
2753 if (Trous->Value(NbTrous) == NbPath+1) NbPart--;
2755 if (NbPart == 1) { // This is done at once
2756 Standard_Real Extend = 0.0;
2757 if (NbTrous==1) Extend = EvalExtrapol(1, Transition);
2758 isDone = BuildShell(Transition,
2764 else { // This is done piece by piece
2765 Standard_Integer IFirst = 1, ILast;
2766 for (ii=1, isDone=Standard_True;
2767 ii<=NbPart && isDone; ii++) {
2768 if (ii > NbTrous) ILast = NbPath+1;
2769 else ILast = Trous->Value(ii);
2770 isDone = BuildShell(Transition,
2774 EvalExtrapol(IFirst, Transition),
2775 EvalExtrapol(ILast, Transition));
2777 Translate(myVEdges, IFirst, Bounds, 2);
2778 PerformCorner(IFirst,
2779 Transition, Bounds);
2782 Translate(myVEdges, IFirst, Bounds, 1);
2785 // Management of looping ends
2786 if ( (NbTrous>0) && (myLoc->IsClosed()) &&
2787 (Trous->Value(NbTrous) == NbPath+1) ) {
2788 Translate(myVEdges, NbPath+1, Bounds, 1);
2789 Translate(myVEdges, 1, Bounds, 2);
2790 PerformCorner(1, Transition, Bounds);
2793 // Construction of the shell
2796 for (ipath=1; ipath<=NbPath; ipath++)
2797 for (isec=1; isec <=NbLaw; isec++) {
2798 const TopoDS_Shape& face = myFaces->Value(isec, ipath);
2799 if (!face.IsNull() &&
2800 (face.ShapeType() == TopAbs_FACE) ) B.Add(shell, face);
2803 TopTools_ListIteratorOfListOfShape It(myAuxShape);
2804 for (; It.More(); It.Next()) {
2805 const TopoDS_Shape& face = It.Value();
2806 if (!face.IsNull() &&
2807 (face.ShapeType() == TopAbs_FACE) ) B.Add(shell, face);
2809 //Set common Uedges to faces
2810 BRepTools_Substitution aSubstitute;
2812 for (ii = 1; ii <= NbLaw; ii++)
2813 for (jj = 1; jj <= NbPath; jj++)
2815 SetCommonEdgeInFace(aSubstitute,
2816 myFaces->Value(ii, jj),
2817 myUEdges->Value(ii, jj));
2818 SetCommonEdgeInFace(aSubstitute,
2819 myFaces->Value(ii, jj),
2820 myUEdges->Value(ii+1, jj));
2822 if (mySec->IsUClosed())
2823 for (jj = 1; jj <= NbPath; jj++)
2824 SetCommonEdgeInFace(aSubstitute,
2825 myFaces->Value( 1, jj ),
2826 myUEdges->Value( NbLaw+1, jj));
2828 TopTools_DataMapIteratorOfDataMapOfShapeShape mapit( myVEdgesModified );
2829 for (; mapit.More(); mapit.Next())
2831 const TopoDS_Edge& OldEdge = TopoDS::Edge(mapit.Key());
2832 const TopoDS_Edge& NewEdge = TopoDS::Edge(mapit.Value());
2833 Substitute( aSubstitute, OldEdge, NewEdge );
2835 aSubstitute.Build( shell );
2836 if (aSubstitute.IsCopied( shell )) {
2837 const TopTools_ListOfShape& listSh = aSubstitute.Copy( shell );
2838 shell = TopoDS::Shell( listSh.First() );
2841 for (ii = myFaces->LowerRow(); ii <= myFaces->UpperRow(); ii++) {
2842 for (jj = myFaces->LowerCol(); jj <= myFaces->UpperCol(); jj++) {
2843 const TopoDS_Shape& aLocalShape = myFaces->Value(ii, jj);
2845 if(!aLocalShape.IsNull() && aSubstitute.IsCopied(aLocalShape)) {
2846 const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape);
2848 if(!aList.IsEmpty())
2849 myFaces->ChangeValue(ii, jj) = aList.First();
2854 for (ii = myVEdges->LowerRow(); ii <= myVEdges->UpperRow(); ii++) {
2855 for (jj = myVEdges->LowerCol(); jj <= myVEdges->UpperCol(); jj++) {
2856 const TopoDS_Shape& aLocalShape = myVEdges->Value(ii, jj);
2858 if(!aLocalShape.IsNull() && aSubstitute.IsCopied(aLocalShape)) {
2859 const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape);
2861 if(!aList.IsEmpty())
2862 myVEdges->ChangeValue(ii, jj) = aList.First();
2867 for (ii = myUEdges->LowerRow(); ii <= myUEdges->UpperRow(); ii++) {
2868 for (jj = myUEdges->LowerCol(); jj <= myUEdges->UpperCol(); jj++) {
2869 const TopoDS_Shape& aLocalShape = myUEdges->Value(ii, jj);
2871 if(!aLocalShape.IsNull() && aSubstitute.IsCopied(aLocalShape)) {
2872 const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape);
2874 if(!aList.IsEmpty())
2875 myUEdges->ChangeValue(ii, jj) = aList.First();
2881 if (myLoc->IsClosed() && mySec->IsUClosed()) {
2883 Standard_Boolean closed = Standard_True;
2884 Standard_Integer iedge;
2885 TopTools_IndexedDataMapOfShapeListOfShape EFmap;
2886 TopExp::MapShapesAndAncestors(shell, TopAbs_EDGE,
2887 TopAbs_FACE, EFmap);
2889 for (iedge = 1; iedge <=EFmap.Extent() && closed; iedge++) {
2890 const TopoDS_Edge& theEdge = TopoDS::Edge(EFmap.FindKey(iedge));
2891 if (BRep_Tool::Degenerated(theEdge)) continue;
2892 closed = ( EFmap(iedge).Extent() > 1);
2894 shell.Closed(closed);
2901 //=======================================================================
2904 //=======================================================================
2905 Standard_Boolean BRepFill_Sweep::IsDone() const
2910 //=======================================================================
2913 //=======================================================================
2914 TopoDS_Shape BRepFill_Sweep::Shape() const
2919 //=======================================================================
2920 //function : ErrorOnSurface
2922 //=======================================================================
2923 Standard_Real BRepFill_Sweep::ErrorOnSurface() const
2928 //=======================================================================
2929 //function : SubShape
2930 //purpose : Faces obtained by sweeping
2931 //=======================================================================
2932 Handle(TopTools_HArray2OfShape) BRepFill_Sweep::SubShape() const
2937 //=======================================================================
2938 //function : InterFaces
2939 //purpose : Edges obtained by sweeping
2940 //=======================================================================
2941 Handle(TopTools_HArray2OfShape) BRepFill_Sweep::InterFaces() const
2946 //=======================================================================
2947 //function : Sections
2948 //purpose : Edges or Face (or compound of 2) Transition between 2 sweepings
2949 //=======================================================================
2950 Handle(TopTools_HArray2OfShape) BRepFill_Sweep::Sections() const
2955 //=======================================================================
2956 //function : PerformCorner
2957 //purpose : Trim and/or loop a corner
2958 //======================================================================
2959 void BRepFill_Sweep::PerformCorner(const Standard_Integer Index,
2960 const BRepFill_TransitionStyle Transition,
2961 const Handle(TopTools_HArray2OfShape)& Bounds)
2964 if (Transition == BRepFill_Modified) return; // Do nothing.
2966 BRepFill_TransitionStyle TheTransition = Transition;
2967 Standard_Boolean isTangent=Standard_False;
2969 Standard_Integer I1, I2, ii; //, jj;
2971 gp_Vec T1, T2, Tang, Sortant;
2973 //Handle(TopTools_HArray1OfShape) TheShape =
2974 //new TopTools_HArray1OfShape( 1, mySec->NbLaw() );
2975 // TopTools_ListIteratorOfListOfShape Iterator;
2982 I1 = myLoc->NbLaw();
2986 // Construct an axis supported by the bissectrice
2987 myLoc->Law(I1)->GetDomain(F, L);
2988 myLoc->Law(I1)->GetCurve()->D1(L, P1, T1);
2991 myLoc->Law(I2)->GetDomain(F, L);
2992 myLoc->Law(I2)->GetCurve()->D1(F, P2, T2);
2995 if (T1.Angle(T2) < myAngMin) {
2996 isTangent = Standard_True;
2999 myLoc->Law(I1)->GetDomain(F, L);
3000 myLoc->Law(I1)->D0(L, M, V);
3002 myLoc->Law(I2)->GetDomain(F, L);
3003 myLoc->Law(I2)->D0(L, M, V);
3006 if (t1.Angle(t2) < myAngMin) {
3008 cout << "BRepFill_Sweep::PerformCorner : This is not a corner !" << endl;
3015 if ((TheTransition == BRepFill_Right)
3016 && (T1.Angle(T2) > myAngMax) ) {
3017 TheTransition = BRepFill_Round;
3020 Tang = T1 + T2; //Average direction
3021 gp_Dir NormalOfBisPlane = Tang;
3024 Sortant -= Tang.Dot(Tang)*Tang;
3027 Sortant = T2-T1; //Direction input
3028 Sortant *= -1; // " " output
3029 Tang -= (Tang.Dot(T2))*T2;
3032 P1.BaryCenter(0.5, P2, 0.5);
3036 gp_Ax2 Axe (P1, N, Dx);
3037 gp_Ax2 AxeOfBisPlane( P1, NormalOfBisPlane );
3039 // Construct 2 intersecting Shells
3040 Handle (TopTools_HArray2OfShape) UEdges =
3041 new TopTools_HArray2OfShape( 1, mySec->NbLaw()+1, 1, myLoc->NbLaw() );
3042 UEdges->ChangeArray2() = myUEdges->Array2();
3044 // modified by NIZHNY-MKK Wed Oct 29 18:31:47 2003.BEGIN
3045 Handle (TopTools_HArray2OfShape) aFaces =
3046 new TopTools_HArray2OfShape(myFaces->LowerRow(), myFaces->UpperRow(), 1, 2);
3047 Translate(myFaces, I1, aFaces, 1);
3048 Translate(myFaces, I2, aFaces, 2);
3050 Handle (TopTools_HArray2OfShape) aUEdges =
3051 new TopTools_HArray2OfShape(myUEdges->LowerRow(), myUEdges->UpperRow(), 1, 2);
3052 Translate(myUEdges, I1, aUEdges, 1);
3053 Translate(myUEdges, I2, aUEdges, 2);
3055 gp_Vec aNormal = T2 + T1;
3056 TopoDS_Face aPlaneF;
3058 if(aNormal.Magnitude() > gp::Resolution()) {
3059 gp_Pln pl(P1, gp_Dir(aNormal));
3060 BRepLib_MakeFace aFMaker(pl);
3062 if(aFMaker.Error() == BRepLib_FaceDone) {
3063 aPlaneF = aFMaker.Face();
3065 aBB.UpdateFace(aPlaneF, Precision::Confusion() * 10.);
3069 BRepFill_TrimShellCorner aTrim(aFaces, AxeOfBisPlane, aPlaneF);
3070 aTrim.AddBounds(Bounds);
3071 aTrim.AddUEdges(aUEdges);
3074 if (aTrim.IsDone()) {
3075 TopTools_ListOfShape listmodif;
3076 Standard_Integer iit = 0;
3078 for(iit = 0; iit < 2; iit++) {
3079 Standard_Integer II = (iit == 0) ? I1 : I2;
3081 for (ii = 1; ii <= mySec->NbLaw(); ii++) {
3082 aTrim.Modified(myFaces->Value(ii, II), listmodif);
3084 if(!listmodif.IsEmpty()) {
3085 myFaces->SetValue(ii, II, listmodif.First());
3089 for (ii = myUEdges->LowerRow(); ii <= myUEdges->UpperRow(); ii++) {
3090 aTrim.Modified(myUEdges->Value(ii, II), listmodif);
3092 if(!listmodif.IsEmpty()) {
3093 myUEdges->SetValue(ii, II, listmodif.First());
3098 else if ((TheTransition == BRepFill_Right) ||
3099 aTrim.HasSection() ) {
3101 cout << "Fail of TrimCorner" << endl;
3103 return; // Nothing is touched
3106 if (mySec->IsUClosed())
3108 myUEdges->SetValue( 1, I1, myUEdges->Value(mySec->NbLaw()+1, I1) );
3109 myUEdges->SetValue( 1, I2, myUEdges->Value(mySec->NbLaw()+1, I2) );
3112 if (TheTransition == BRepFill_Round) {
3114 TopTools_ListOfShape list1, list2;
3115 TopoDS_Edge Bord1, Bord2, BordFirst;
3116 BordFirst.Nullify();
3119 Standard_Boolean HasFilling = Standard_False;
3121 for (ii=1; ii<=mySec->NbLaw(); ii++) {
3122 KeepEdge(myFaces->Value(ii, I1), Bounds->Value(ii, 1), list1);
3123 KeepEdge(myFaces->Value(ii, I2), Bounds->Value(ii, 2), list2);
3124 if (list1.Extent() == list2.Extent()) {
3125 TopTools_ListIteratorOfListOfShape It1(list1);
3126 TopTools_ListIteratorOfListOfShape It2(list2);
3128 for (; It1.More(); It1.Next(), It2.Next()) {
3129 if (HasFilling) { // Transversal choice of constraints
3130 TopoDS_Vertex VF, VL, VC;
3131 TopoDS_Edge E = TopoDS::Edge(It1.Value());
3135 TopExp::Vertices(E, VF, VL);
3136 if (!Bord1.IsNull() &&
3137 TopExp::CommonVertex(E, Bord1, VC)) {
3138 if (VC.IsSame(VF)) E1 = Bord1;
3141 if (!Bord2.IsNull() &&
3142 TopExp::CommonVertex(E, Bord2, VC)) {
3143 if (VC.IsSame(VF)) E1 = Bord2;
3146 if (!BordFirst.IsNull() &&
3147 TopExp::CommonVertex(E, BordFirst, VC)) {
3148 if (VC.IsSame(VF)) E1 = BordFirst;
3149 else E2 = BordFirst;
3156 B = Filling(It1.Value(), myFaces->Value(ii, I1),
3157 It2.Value(), myFaces->Value(ii, I2),
3158 myVEdgesModified, myTol3d, Axe, T1, Bord1, Bord2, FF);
3161 myAuxShape.Append(FF);
3162 myVEdges->ChangeValue(ii, I2) = FF;
3163 HasFilling = Standard_True;
3165 if (ii==1) BordFirst = Bord1;
3169 else cout << "PerformCorner : Unsymmetry of free border" << endl;
3177 Standard_Integer jj;
3179 DBRep::Set("TrimmedShell", TheShape);
3180 for (jj=1; jj <=myFaces->ColLength(); jj++){
3181 sprintf(name,"Tfaces_%d_%d", jj, I1);
3182 DBRep::Set(name, myFaces->Value(jj, I1));
3183 sprintf(name,"Tfaces_%d_%d", jj, I2);
3184 DBRep::Set(name, myFaces->Value(jj, I2));
3191 //=======================================================================
3192 //function : EvalExtrapol
3194 //======================================================================
3195 Standard_Real BRepFill_Sweep::
3196 EvalExtrapol(const Standard_Integer Index,
3197 const BRepFill_TransitionStyle Transition) const
3199 Standard_Real Extrap = 0.0;
3200 if (Transition == BRepFill_Right) {
3201 Standard_Integer I1, I2;
3202 if ((Index == 1) || (Index ==myLoc->NbLaw()+1) ) {
3203 if (!myLoc->IsClosed() || !mySec->IsVClosed()) return Extrap;
3204 I1 = myLoc->NbLaw();
3212 gp_Vec V1, V2, T1, T2;
3214 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax, R, f, l;
3216 myLoc->Law(I1)->GetDomain(f, l);
3217 myLoc->Law(I1)->D0(l, M1, V1);
3218 T1.SetXYZ(M1.Column(3));
3219 myLoc->Law(I2)->GetDomain(f, l);
3220 myLoc->Law(I2)->D0(f, M2, V2);
3221 T2.SetXYZ(M2.Column(3));
3223 Standard_Real alpha = T1.Angle(T2);
3224 if ((alpha > myAngMax) || (alpha < myAngMin)) {
3225 //Angle too great => No "straight" connection
3226 //Angle too small => No connection
3227 return Extrap; // = 0.0
3230 Handle(GeomFill_SectionLaw) Sec;
3231 Sec = mySec->ConcatenedLaw();
3233 //Calculating parameter U
3234 Standard_Real U, Length, SecFirst, SecLen, Lf, Ll;
3235 myLoc->CurvilinearBounds( myLoc->NbLaw(), Lf, Length );
3236 mySec->Law(1)->GetDomain( SecFirst, SecLen );
3238 myLoc->CurvilinearBounds( I1, Lf, Ll );
3239 U = SecFirst + (Ll/Length)*SecLen;
3242 //Box(Sec, 0., box);
3244 box.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
3246 R = Max(Max(Abs(Xmin), Abs(Xmax)),Max(Abs(Ymin), Abs(Ymax)));
3248 // modified by NIZHNY-MKK Fri Oct 31 18:57:51 2003
3249 // Standard_Real coef = 1.2;
3250 Standard_Real coef = 2.;
3252 Extrap = Max(Abs(Zmin), Abs(Zmax)) + 100*myTol3d;
3253 Extrap += R*Tan(alpha/2);
3258 //=======================================================================
3259 //function : MergeVertex
3260 //purpose : Make V2 = V1 if V2 is too close to V1
3261 //======================================================================
3262 Standard_Boolean BRepFill_Sweep::MergeVertex(const TopoDS_Shape& V1,
3263 TopoDS_Shape& V2) const
3265 // Class BRep_Tool without fields and without Constructor :
3267 const TopoDS_Vertex& v1 = TopoDS::Vertex(V1);
3268 const TopoDS_Vertex& v2 = TopoDS::Vertex(V2);
3270 // tol = Max(BT.Tolerance(v1), BT.Tolerance(v2));
3271 tol = Max(BRep_Tool::Tolerance(v1), BRep_Tool::Tolerance(v2));
3272 if (tol < myTol3d) tol = myTol3d;
3273 // if (BT.Pnt(v1).Distance(BT.Pnt(v2)) <= tol ){
3274 if (BRep_Tool::Pnt(v1).Distance(BRep_Tool::Pnt(v2)) <= tol ){
3276 return Standard_True;
3278 return Standard_False;
3282 //=======================================================================
3283 //function : UpdateVertex
3284 //purpose : Update the Tolerance of Vertices depending on Laws.
3285 //======================================================================
3286 void BRepFill_Sweep::UpdateVertex(const Standard_Integer ipath,
3287 const Standard_Integer isec,
3288 const Standard_Real ErrApp,
3289 const Standard_Real Param,
3290 TopoDS_Shape& V) const
3292 TopoDS_Vertex vv, TheV;
3293 TheV = TopoDS::Vertex(V);
3294 myLoc->PerformVertex(ipath,
3295 mySec->Vertex(isec, Param),
3296 ErrApp+mySec->VertexTol(isec-1, Param),
3298 // Class BRep_Tool without fields and without Constructor :
3302 P1 = BRep_Tool::Pnt(vv);
3303 // P2 = BT.Pnt(TheV);
3304 P2 = BRep_Tool::Pnt(TheV);
3306 // Standard_Real Tol = BT.Tolerance(vv);
3307 Standard_Real Tol = BRep_Tool::Tolerance(vv);
3308 Tol += P1.Distance(P2);
3310 // if (Tol > BT.Tolerance(TheV)) {
3311 if (Tol > BRep_Tool::Tolerance(TheV)) {
3313 B.UpdateVertex(TheV, Tol);
3317 //=======================================================================
3318 //function : RebuildTopOrBottomEdge
3319 //purpose : Rebuild v-iso edge of top or bottom section
3320 // inserting new 3d and 2d curves taken from swept surfaces
3321 //======================================================================
3322 void BRepFill_Sweep::RebuildTopOrBottomEdge(const TopoDS_Edge& aNewEdge,
3323 TopoDS_Edge& anEdge,
3324 TopTools_MapOfShape& ReversedEdges) const
3326 Standard_Real fpar, lpar;
3327 Handle(Geom_Curve) aNewCurve = BRep_Tool::Curve(aNewEdge, fpar, lpar);
3328 TopLoc_Location Identity;
3330 Standard_Boolean ToReverse = Standard_False;
3331 Standard_Boolean IsDegen = BRep_Tool::Degenerated(aNewEdge);
3333 BRep_Tool::Range(aNewEdge, fpar, lpar);
3336 TopoDS_Vertex V1, V2, NewV1, NewV2;
3337 TopExp::Vertices(anEdge, V1, V2);
3340 TopExp::Vertices(aNewEdge, NewV1, NewV2);
3341 V1.Location(Identity);
3342 if (!V1.IsSame(NewV1))
3344 if (V1.IsSame(NewV2))
3345 ToReverse = Standard_True;
3348 gp_Pnt Pnt1 = BRep_Tool::Pnt(V1);
3349 gp_Pnt NewPnt1 = BRep_Tool::Pnt(NewV1);
3350 Standard_Real TolSum = BRep_Tool::Tolerance(V1) + BRep_Tool::Tolerance(NewV1);
3351 if (!Pnt1.IsEqual(NewPnt1, TolSum))
3352 ToReverse = Standard_True;
3358 Standard_Real OldFirst, OldLast;
3359 Handle(Geom_Curve) OldCurve = BRep_Tool::Curve(anEdge, OldFirst, OldLast);
3360 gp_Vec OldD1, NewD1;
3362 OldCurve->D1(0.5*(OldFirst + OldLast), MidPnt, OldD1);
3363 aNewCurve->D1(0.5*(fpar + lpar), MidPnt, NewD1);
3364 if (OldD1 * NewD1 < 0.)
3365 ToReverse = Standard_True;
3369 anEdge.Location(Identity);
3370 const Handle(BRep_TEdge)& TEdge = *((Handle(BRep_TEdge)*) &anEdge.TShape());
3371 TEdge->Tolerance(BRep_Tool::Tolerance(aNewEdge));
3373 BB.Range(anEdge, fpar, lpar);
3374 BB.UpdateEdge(anEdge, aNewCurve, Precision::Confusion());
3375 const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &aNewEdge.TShape());
3376 const BRep_ListOfCurveRepresentation& lcr = TE->Curves();
3377 BRep_ListIteratorOfListOfCurveRepresentation itrep(lcr);
3378 for (; itrep.More(); itrep.Next())
3380 const Handle(BRep_CurveRepresentation)& CurveRep = itrep.Value();
3381 if (CurveRep->IsCurveOnSurface())
3383 Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (CurveRep));
3384 Handle(Geom2d_Curve) aPCurve = GC->PCurve();
3385 Handle(Geom_Surface) aSurf = GC->Surface();
3386 TopLoc_Location aLoc = aNewEdge.Location() * GC->Location();
3387 BB.UpdateEdge(anEdge, aPCurve, aSurf, aLoc, Precision::Confusion());
3391 anEdge.Free(Standard_True);
3392 TopoDS_Vertex V1, V2;
3393 TopExp::Vertices(anEdge, V1, V2);
3395 TopoDS_Shape anEdgeFORWARD = anEdge.Oriented(TopAbs_FORWARD);
3397 BB.Remove(anEdgeFORWARD, V1);
3398 BB.Remove(anEdgeFORWARD, V2);
3400 V1.Location(Identity);
3401 V2.Location(Identity);
3404 V2.Orientation(TopAbs_FORWARD);
3405 V1.Orientation(TopAbs_REVERSED);
3407 BB.Add(anEdgeFORWARD, V1);
3408 BB.Add(anEdgeFORWARD, V2);
3413 ReversedEdges.Add(anEdge);
3416 BB.Degenerated(anEdge, IsDegen);