1 // File: BRepOffset_Tool.cxx
2 // Created: Mon Oct 23 14:25:07 1995
3 // Author: Yves FRICAUD
8 #include <BRepOffset_Tool.ixx>
10 #include <BRepAlgo_Tool.hxx>
12 #include <BRepAdaptor_Curve.hxx>
13 #include <BRepAdaptor_Surface.hxx>
14 #include <BRepAdaptor_HCurve.hxx>
15 #include <BRepAdaptor_HSurface.hxx>
17 #include <BRepBndLib.hxx>
19 #include <Bnd_Box2d.hxx>
20 #include <BndLib_Add3dCurve.hxx>
21 #include <BRep_Tool.hxx>
22 #include <BRepLib.hxx>
23 #include <BRepLib_MakeEdge.hxx>
24 #include <BRepLib_MakeVertex.hxx>
25 #include <BRepLib_MakePolygon.hxx>
26 #include <BRepLib_MakeFace.hxx>
27 #include <BRepLib_MakeWire.hxx>
28 #include <BRepTools.hxx>
29 #include <BRepTools_WireExplorer.hxx>
31 #include <BRepTools_Modifier.hxx>
32 #include <BRepTools_TrsfModification.hxx>
33 #include <BRepTopAdaptor_FClass2d.hxx>
34 #include <BRepAdaptor_Curve.hxx>
35 #include <BRepAdaptor_Curve2d.hxx>
37 #include <IntRes2d_IntersectionPoint.hxx>
38 #include <IntRes2d_IntersectionSegment.hxx>
39 #include <Extrema_ExtPC.hxx>
42 #include <TopExp_Explorer.hxx>
44 #include <Standard_ConstructionError.hxx>
46 #include <TopOpeBRepBuild_Builder.hxx>
47 #include <TopOpeBRepDS_HDataStructure.hxx>
48 #include <TopOpeBRepDS_CurveExplorer.hxx>
49 #include <TopOpeBRep_DSFiller.hxx>
50 #include <TopOpeBRepTool_GeomTool.hxx>
51 #include <TopOpeBRep_ShapeIntersector.hxx>
52 #include <TopOpeBRep_FacesFiller.hxx>
53 #include <TopOpeBRep_GeomTool.hxx>
55 #include <TopoDS_Iterator.hxx>
56 #include <TopTools_ListIteratorOfListOfShape.hxx>
57 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
59 #include <Geom_Surface.hxx>
60 #include <Geom_RectangularTrimmedSurface.hxx>
61 #include <Geom_OffsetSurface.hxx>
62 #include <Geom_BezierSurface.hxx>
63 #include <Geom_BSplineSurface.hxx>
64 #include <Geom_ConicalSurface.hxx>
65 #include <Geom_Curve.hxx>
66 #include <Geom_Line.hxx>
67 #include <Geom_Conic.hxx>
68 #include <Geom_TrimmedCurve.hxx>
69 #include <GCPnts_QuasiUniformDeflection.hxx>
71 #include <GeomLib.hxx>
72 #include <GeomAPI.hxx>
73 #include <GeomAPI_ProjectPointOnCurve.hxx>
74 #include <Geom2d_TrimmedCurve.hxx>
75 #include <Geom2d_Line.hxx>
76 #include <Geom2d_Curve.hxx>
77 #include <Geom2d_Circle.hxx>
78 #include <Geom2d_Ellipse.hxx>
79 #include <Geom2d_Parabola.hxx>
80 #include <Geom2d_Hyperbola.hxx>
81 #include <Geom2d_BezierCurve.hxx>
82 #include <Geom2d_BSplineCurve.hxx>
84 #include <Geom2dAdaptor_Curve.hxx>
85 #include <Geom2dInt_GInter.hxx>
87 #include <GeomAdaptor_Surface.hxx>
88 #include <GeomProjLib.hxx>
89 #include <GeomInt_IntSS.hxx>
90 #include <ProjLib_ProjectedCurve.hxx>
91 #include <ProjLib_HProjectedCurve.hxx>
101 #include <Precision.hxx>
102 #include <Standard_ConstructionError.hxx>
104 #include <BRep_TEdge.hxx>
105 #include <Extrema_ExtPC2d.hxx>
107 #include <Geom_SurfaceOfLinearExtrusion.hxx>
108 #include <Geom_SurfaceOfRevolution.hxx>
109 #include <GCPnts_AbscissaPoint.hxx>
111 //tma: for new boolean operation
112 #include <TopTools_SequenceOfShape.hxx>
113 #include <BOPTools_DSFiller.hxx>
114 #include <Geom_BSplineCurve.hxx>
115 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
116 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
117 #include <GeomConvert_ApproxCurve.hxx>
118 #include <Geom2dConvert_ApproxCurve.hxx>
119 //#include <BRepAlgoAPI_Section.hxx>
120 #include <BooleanOperations_ShapesDataStructure.hxx>
121 #include <BOPTools_InterferencePool.hxx>
122 #include <BOPTools_SSInterference.hxx>
123 #include <BOPTools_SequenceOfCurves.hxx>
124 #include <BOPTools_Curve.hxx>
125 #include <BOPTools_ListOfPaveBlock.hxx>
126 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
127 #include <BOPTools_PaveBlock.hxx>
128 #include <BRepAlgoAPI_Section.hxx>
129 #include <BOPTools_SSIntersectionAttribute.hxx>
130 #include <BOPTools_PaveFiller.hxx>
131 #include <BOPTools_Tools2D.hxx>
132 #include <BOPTools_ListIteratorOfListOfPave.hxx>
133 #include <TopoDS_Compound.hxx>
134 #include <GCPnts_UniformAbscissa.hxx>
135 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
136 #include <BRep_CurveRepresentation.hxx>
138 #include <BRepOffset_ListOfInterval.hxx>
139 #include <BRepOffset_Interval.hxx>
140 #include <TColgp_Array1OfPnt2d.hxx>
141 #include <ShapeCustom_Curve2d.hxx>
142 #include <GeomAPI_ExtremaCurveCurve.hxx>
150 Standard_Boolean AffichInter = Standard_False;
151 static Standard_Boolean AffichExtent = Standard_False;
152 static Standard_Integer NbNewEdges = 1;
153 static Standard_Integer NbFaces = 1;
154 static Standard_Integer NbFOB = 1;
155 static Standard_Integer NbFTE = 1;
156 static Standard_Integer NbExtE = 1;
158 //char* name = new char[100];
162 //=======================================================================
163 //function : EdgeVertices
165 //=======================================================================
167 void BRepOffset_Tool::EdgeVertices (const TopoDS_Edge& E,
171 if (E.Orientation() == TopAbs_REVERSED) {
172 TopExp::Vertices(E,V2,V1);
175 TopExp::Vertices(E,V1,V2);
179 //=======================================================================
180 //function : OriEdgeInFace
182 //=======================================================================
184 TopAbs_Orientation BRepOffset_Tool::OriEdgeInFace (const TopoDS_Edge& E,
185 const TopoDS_Face& F )
189 Exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
191 for (; Exp.More() ;Exp.Next()) {
192 if (Exp.Current().IsSame(E)) {
193 return Exp.Current().Orientation();
196 Standard_ConstructionError::Raise("BRepOffset_Tool::OriEdgeInFace");
197 return E.Orientation();
201 //=======================================================================
202 //function : FindPeriod
204 //=======================================================================
206 static void FindPeriod (const TopoDS_Face& F,
215 for (exp.Init(F,TopAbs_EDGE); exp.More(); exp.Next()) {
216 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
219 const Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,pf,pl);
220 if (C.IsNull()) return;
221 Geom2dAdaptor_Curve PC(C,pf,pl);
222 Standard_Real i, nbp = 20;
223 if (PC.GetType() == GeomAbs_Line) nbp = 2;
224 Standard_Real step = (pl - pf) / nbp;
228 for (i = 2; i < nbp; i++) {
235 B.Get(umin,vmin,umax,vmax);
239 //=======================================================================
240 //function : PutInBounds
241 //purpose : Recadre la courbe 2d dans les bounds de la face
242 //=======================================================================
244 static void PutInBounds (const TopoDS_Face& F,
245 const TopoDS_Edge& E,
246 Handle(Geom2d_Curve)& C2d)
248 Standard_Real umin,umax,vmin,vmax;
250 BRep_Tool::Range(E,f,l);
252 TopLoc_Location L; // Recup S avec la location pour eviter la copie.
253 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
255 if (S->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
256 S = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface();
261 if (!S->IsUPeriodic() && !S->IsVPeriodic()) return;
263 FindPeriod (F,umin,umax,vmin,vmax);
265 if (S->IsUPeriodic()) {
266 Standard_Real period = S->UPeriod();
267 Standard_Real eps = period*1.e-6;
268 gp_Pnt2d Pf = C2d->Value(f);
269 gp_Pnt2d Pl = C2d->Value(l);
270 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
271 Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
272 Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
273 Standard_Real du = 0.;
274 if (minC< umin - eps) {
275 du = (int((umin - minC)/period) + 1)*period;
277 if (minC > umax + eps) {
278 du = -(int((minC - umax)/period) + 1)*period;
283 minC += du; maxC += du;
285 // Ajuste au mieux la courbe dans le domaine.
286 if (maxC > umax +100*eps) {
287 Standard_Real d1 = maxC - umax;
288 Standard_Real d2 = umin - minC + period;
289 if (d2 < d1) du =-period;
299 if (S->IsVPeriodic()) {
300 Standard_Real period = S->VPeriod();
301 Standard_Real eps = period*1.e-6;
302 gp_Pnt2d Pf = C2d->Value(f);
303 gp_Pnt2d Pl = C2d->Value(l);
304 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
305 Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
306 Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
307 Standard_Real dv = 0.;
308 if (minC< vmin - eps) {
309 dv = (int((vmin - minC)/period) + 1)*period;
311 if (minC > vmax + eps) {
312 dv = -(int((minC - vmax)/period) + 1)*period;
317 minC += dv; maxC += dv;
319 // Ajuste au mieux la courbe dans le domaine.
320 if (maxC > vmax +100*eps) {
321 Standard_Real d1 = maxC - vmax;
322 Standard_Real d2 = vmin - minC + period;
323 if (d2 < d1) dv =-period;
332 //=======================================================================
335 //=======================================================================
337 Standard_Real BRepOffset_Tool::Gabarit(const Handle(Geom_Curve)& aCurve)
339 GeomAdaptor_Curve GC( aCurve );
341 BndLib_Add3dCurve::Add( GC, Precision::Confusion(), aBox );
342 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dist;
343 aBox.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
344 dist = Max( (aXmax-aXmin), (aYmax-aYmin) );
345 dist = Max( dist, (aZmax-aZmin) );
349 //=======================================================================
350 //function : BuildPCurves
352 //=======================================================================
354 static void BuildPCurves (const TopoDS_Edge& E,
355 const TopoDS_Face& F)
358 Handle (Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E,F,ff,ll);
359 if (!C2d.IsNull()) return;
361 //Standard_Real Tolerance = Max(Precision::Confusion(),BRep_Tool::Tolerance(E));
362 Standard_Real Tolerance = Precision::Confusion();
364 BRepAdaptor_Surface AS(F,0);
365 BRepAdaptor_Curve AC(E);
367 //Try to find pcurve on a bound of BSpline or Bezier surface
368 Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( F );
369 Handle( Standard_Type ) typS = theSurf->DynamicType();
370 if (typS == STANDARD_TYPE(Geom_OffsetSurface))
371 typS = (*((Handle(Geom_OffsetSurface)*)&theSurf))->BasisSurface()->DynamicType();
372 if (typS == STANDARD_TYPE(Geom_BezierSurface) || typS == STANDARD_TYPE(Geom_BSplineSurface))
374 gp_Pnt fpoint = AC.Value( AC.FirstParameter() );
375 gp_Pnt lpoint = AC.Value( AC.LastParameter() );
376 TopoDS_Face theFace = BRepLib_MakeFace( theSurf, Precision::Confusion() );
377 Standard_Real U1 = 0., U2 = 0., TolProj = 1.e-4; //1.e-5;
379 TopExp_Explorer Explo;
380 Explo.Init( theFace, TopAbs_EDGE );
381 for (; Explo.More(); Explo.Next())
383 TopoDS_Edge anEdge = TopoDS::Edge( Explo.Current() );
384 BRepAdaptor_Curve aCurve( anEdge );
385 Extrema_ExtPC fextr( fpoint, aCurve );
386 if (!fextr.IsDone() || fextr.NbExt() < 1)
388 Standard_Real dist2, dist2min = RealLast();
390 for (i = 1; i <= fextr.NbExt(); i++)
392 dist2 = fextr.SquareDistance(i);
393 if (dist2 < dist2min)
396 U1 = fextr.Point(i).Parameter();
399 if (dist2min > TolProj * TolProj)
401 Extrema_ExtPC lextr( lpoint, aCurve );
402 if (!lextr.IsDone() || lextr.NbExt() <1)
404 dist2min = RealLast();
405 for (i = 1; i <= lextr.NbExt(); i++)
407 dist2 = lextr.SquareDistance(i);
408 if (dist2 < dist2min)
411 U2 = lextr.Point(i).Parameter();
414 if (dist2min <= TolProj * TolProj)
419 } // for (; Explo.More(); Explo.Current())
421 if (! theEdge.IsNull())
423 //Construction of pcurve
426 Standard_Real temp = U1;
431 C2d = BRep_Tool::CurveOnSurface( theEdge, theFace, f, l );
432 C2d = new Geom2d_TrimmedCurve( C2d, U1, U2 );
434 if (theSurf->IsUPeriodic() || theSurf->IsVPeriodic())
435 PutInBounds( F, E, C2d );
438 B.UpdateEdge( E, C2d, F, BRep_Tool::Tolerance(E) );
439 BRepLib::SameRange( E );
445 Handle(BRepAdaptor_HSurface) HS = new BRepAdaptor_HSurface(AS);
446 Handle(BRepAdaptor_HCurve) HC = new BRepAdaptor_HCurve(AC);
448 ProjLib_ProjectedCurve Proj(HS,HC,Tolerance);
450 switch ( Proj.GetType()) {
453 C2d = new Geom2d_Line(Proj.Line());
457 C2d = new Geom2d_Circle(Proj.Circle());
460 case GeomAbs_Ellipse:
461 C2d = new Geom2d_Ellipse(Proj.Ellipse());
464 case GeomAbs_Parabola:
465 C2d = new Geom2d_Parabola(Proj.Parabola());
468 case GeomAbs_Hyperbola:
469 C2d = new Geom2d_Hyperbola(Proj.Hyperbola());
472 case GeomAbs_BezierCurve:
476 case GeomAbs_BSplineCurve:
477 C2d = Proj.BSpline();
485 if (AS.IsUPeriodic() || AS.IsVPeriodic()) {
486 PutInBounds(F,E,C2d);
490 B.UpdateEdge (E,C2d,F,BRep_Tool::Tolerance(E));
493 Standard_ConstructionError::Raise("BRepOffset_Tool::BuildPCurves");
494 cout <<"Echec ProjLib"<<endl;
498 //=======================================================================
501 //=======================================================================
503 void BRepOffset_Tool::OrientSection (const TopoDS_Edge& E,
504 const TopoDS_Face& F1,
505 const TopoDS_Face& F2,
506 TopAbs_Orientation& O1,
507 TopAbs_Orientation& O2)
512 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
513 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
514 Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l);
515 Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l);
516 Handle (Geom_Curve) C = BRep_Tool::Curve(E,L,f,l);
518 BRepAdaptor_Curve BAcurve( E );
519 GCPnts_UniformAbscissa Distribution( BAcurve, 3 );
520 Standard_Real ParOnC = Distribution.Parameter(2); //0.5*(f+l);
522 gp_Vec T1 = C->DN(ParOnC,1).Transformed(L.Transformation());
523 if (T1.SquareMagnitude() > gp::Resolution()) {
527 gp_Pnt2d P = C1->Value(ParOnC);
531 S1->D1(P.X(),P.Y(),P3,D1U,D1V);
533 if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse();
535 P = C2->Value(ParOnC);
536 S2->D1(P.X(),P.Y(),P3,D1U,D1V);
538 if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse();
540 gp_Vec ProVec = DN2^T1;
541 Standard_Real Prod = DN1.Dot(ProVec);
546 O1 = TopAbs_REVERSED;
549 Prod = DN2.Dot(ProVec);
554 O2 = TopAbs_REVERSED;
556 if (F1.Orientation() == TopAbs_REVERSED) O1 = TopAbs::Reverse(O1);
557 if (F2.Orientation() == TopAbs_REVERSED) O2 = TopAbs::Reverse(O2);
560 //=======================================================================
561 //function : HasCommonShape
563 //=======================================================================
565 Standard_Boolean BRepOffset_Tool::HasCommonShapes (const TopoDS_Face& F1,
566 const TopoDS_Face& F2,
567 TopTools_ListOfShape& LE,
568 TopTools_ListOfShape& LV)
570 Standard_Boolean Common = Standard_False;
571 LE.Clear(); LV.Clear();
573 TopExp_Explorer exp1;
574 exp1.Init(F1,TopAbs_EDGE);
576 for (; exp1.More(); exp1.Next()) {
577 TopExp_Explorer exp2;
578 exp2.Init(F2,TopAbs_EDGE);
579 for (; exp2.More(); exp2.Next()) {
580 if (exp1.Current().IsSame(exp2.Current())) {
581 Common = Standard_True;
582 LE.Append(exp1.Current());
586 for (exp1.Init(F1,TopAbs_VERTEX); exp1.More(); exp1.Next()) {
587 TopExp_Explorer exp2;
588 exp2.Init(F2,TopAbs_EDGE);
589 for (exp2.Init(F2,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
590 if (exp1.Current().IsSame(exp2.Current())) {
591 Common = Standard_True;
592 LV.Append(exp1.Current());
599 //=======================================================================
602 //=======================================================================
604 static Standard_Boolean ToSmall (const Handle(Geom_Curve)& C)
606 Standard_Real Tol = 10*Precision::Confusion();
607 Standard_Real m = (C->FirstParameter()*0.668 + C->LastParameter()*0.332);
608 gp_Pnt P1 = C->Value(C->FirstParameter());
609 gp_Pnt P2 = C->Value(C->LastParameter());
610 gp_Pnt P3 = C->Value(m);
611 if (P1.Distance(P2) > Tol) return Standard_False;
612 if (P2.Distance(P3) > Tol) return Standard_False;
613 return Standard_True;
617 //=======================================================================
618 //function : IsOnSurface
620 //=======================================================================
622 static Standard_Boolean IsOnSurface(const Handle(Geom_Curve)& C,
623 const Handle(Geom_Surface)& S,
624 Standard_Real TolConf,
625 Standard_Real& TolReached)
627 Standard_Real f = C->FirstParameter();
628 Standard_Real l = C->LastParameter();
629 Standard_Integer n = 5;
630 Standard_Real du = (f-l)/(n-1);
636 GeomAdaptor_Surface AS(S);
638 switch ( AS.GetType()) {
641 gp_Ax3 Ax = AS.Plane().Position();
642 for ( Standard_Integer i = 0; i < n; i++) {
643 P = C->Value(f+i*du);
644 ElSLib::PlaneParameters(Ax,P,U,V);
645 TolReached = P.Distance(ElSLib::PlaneValue(U,V,Ax));
646 if ( TolReached > TolConf)
647 return Standard_False;
651 case GeomAbs_Cylinder:
653 gp_Ax3 Ax = AS.Cylinder().Position();
654 Standard_Real Rad = AS.Cylinder().Radius();
655 for ( Standard_Integer i = 0; i < n; i++) {
656 P = C->Value(f+i*du);
657 ElSLib::CylinderParameters(Ax,Rad,P,U,V);
658 TolReached = P.Distance(ElSLib::CylinderValue(U,V,Ax,Rad));
659 if ( TolReached > TolConf)
660 return Standard_False;
666 gp_Ax3 Ax = AS.Cone().Position();
667 Standard_Real Rad = AS.Cone().RefRadius();
668 Standard_Real Alp = AS.Cone().SemiAngle();
669 for ( Standard_Integer i = 0; i < n; i++) {
670 P = C->Value(f+i*du);
671 ElSLib::ConeParameters(Ax,Rad,Alp,P,U,V);
672 TolReached = P.Distance(ElSLib::ConeValue(U,V,Ax,Rad,Alp));
673 if ( TolReached > TolConf)
674 return Standard_False;
680 gp_Ax3 Ax = AS.Sphere().Position();
681 Standard_Real Rad = AS.Sphere().Radius();
682 for ( Standard_Integer i = 0; i < n; i++) {
683 P = C->Value(f+i*du);
684 ElSLib::SphereParameters(Ax,Rad,P,U,V);
685 TolReached = P.Distance(ElSLib::SphereValue(U,V,Ax,Rad));
686 if ( TolReached > TolConf)
687 return Standard_False;
693 gp_Ax3 Ax = AS.Torus().Position();
694 Standard_Real R1 = AS.Torus().MajorRadius();
695 Standard_Real R2 = AS.Torus().MinorRadius();
696 for ( Standard_Integer i = 0; i < n; i++) {
697 P = C->Value(f+i*du);
698 ElSLib::TorusParameters(Ax,R1,R2,P,U,V);
699 TolReached = P.Distance(ElSLib::TorusValue(U,V,Ax,R1,R2));
700 if ( TolReached > TolConf)
701 return Standard_False;
708 return Standard_False;
712 return Standard_True;
716 //=======================================================================
717 //function : PipeInter
719 //=======================================================================
721 void BRepOffset_Tool::PipeInter(const TopoDS_Face& F1,
722 const TopoDS_Face& F2,
723 TopTools_ListOfShape& L1,
724 TopTools_ListOfShape& L2,
725 const TopAbs_State Side)
730 char* name = new char[100];
731 sprintf(name,"FF_%d",NbFaces++);
733 sprintf(name,"FF_%d",NbFaces++);
738 Handle (Geom_Curve) CI;
740 TopAbs_Orientation O1,O2;
741 L1.Clear(); L2.Clear();
743 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
744 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
746 GeomInt_IntSS Inter (S1,S2, Precision::Confusion(),1,1,1);
748 if (Inter.IsDone()) {
749 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
751 if (ToSmall(CI)) continue;
752 TopoDS_Edge E = BRepLib_MakeEdge(CI);
753 if (Inter.HasLineOnS1(i)) {
754 Handle(Geom2d_Curve) C2 = Inter.LineOnS1(i);
755 PutInBounds (F1,E,C2);
756 B.UpdateEdge (E,C2,F1,BRep_Tool::Tolerance(E));
761 if (Inter.HasLineOnS2(i)) {
762 Handle(Geom2d_Curve) C2 = Inter.LineOnS2(i);
763 PutInBounds (F2,E,C2);
764 B.UpdateEdge (E,C2,F2,BRep_Tool::Tolerance(E));
769 OrientSection (E,F1,F2,O1,O2);
770 if (Side == TopAbs_OUT) {
771 O1 = TopAbs::Reverse(O1);
772 O2 = TopAbs::Reverse(O2);
774 L1.Append (E.Oriented(O1));
775 L2.Append (E.Oriented(O2));
779 char* name = new char[100];
780 sprintf(name,"EI_%d",NbNewEdges++);
781 DBRep::Set(name,E.Oriented(O1));
789 //=======================================================================
790 //function : IsAutonomVertex
791 //purpose : Checks wether a vertex is "autonom" or not
792 //=======================================================================
794 static Standard_Boolean IsAutonomVertex(const TopoDS_Shape& aVertex,
795 const TopoDS_Shape& F1,
796 const TopoDS_Shape& F2,
797 const BooleanOperations_ShapesDataStructure& theDS,
798 const BOPTools_PaveFiller& thePaveFiller)
800 Standard_Integer i, index = theDS.ShapeIndex( aVertex, 1 );
803 index = theDS.ShapeIndex( aVertex, 2 );
806 for (i = theDS.NumberOfSourceShapes()+1; i <= theDS.NumberOfInsertedShapes(); i++)
808 const TopoDS_Shape& aShape = theDS.GetShape(i);
809 if (aVertex.IsSame(aShape))
818 Standard_Integer indF1 = theDS.ShapeIndex( F1, 1 );
819 Standard_Integer indF2 = theDS.ShapeIndex( F2, 2 );
821 BooleanOperations_KindOfInterference theTypeInterf;
822 const BOPTools_PavePool& thePavePool = thePaveFiller.PavePool();
823 BOPTools_ListIteratorOfListOfPave itpave;
824 for (i = 1; i <= thePavePool.Length(); i++)
826 const BOPTools_ListOfPave& aPaveList = thePavePool(i).Set();
827 for (itpave.Initialize( aPaveList ); itpave.More(); itpave.Next())
829 BOPTools_Pave aPave = itpave.Value();
830 if (aPave.Index() == index)
832 theTypeInterf = aPave.Type();
833 if (theTypeInterf != BooleanOperations_SurfaceSurface &&
834 theTypeInterf != BooleanOperations_UnknownInterference)
835 return Standard_False;
840 BOPTools_PaveFiller * pPF = (BOPTools_PaveFiller*) &thePaveFiller;
841 BOPTools_PaveFiller& thePF = *pPF;
842 BOPTools_CArray1OfSSInterference& aFFs = thePF.InterfPool()->SSInterferences();
843 Standard_Integer aNbFFs=aFFs.Extent();
844 for (i = 1; i <= aNbFFs; i++)
846 BOPTools_SSInterference& aFFi = aFFs(i);
848 if (aFFi.Index1() == indF1 && aFFi.Index2() == indF2)
850 const BOPTools_ListOfPave& aPaveList = aFFi.NewPaveSet().Set();
851 for (itpave.Initialize( aPaveList ); itpave.More(); itpave.Next())
853 BOPTools_Pave aPave = itpave.Value();
854 if (aPave.Index() == index)
856 theTypeInterf = aPave.Type();
857 if (theTypeInterf != BooleanOperations_SurfaceSurface &&
858 theTypeInterf != BooleanOperations_UnknownInterference)
859 return Standard_False;
865 return Standard_True;
869 //=======================================================================
870 //function : AreConnex
871 //purpose : define if two shapes are connex by a vertex (vertices)
872 //=======================================================================
874 static Standard_Boolean AreConnex(const TopoDS_Wire& W1,
875 const TopoDS_Wire& W2,
876 const TopoDS_Shape& F1,
877 const TopoDS_Shape& F2,
878 const BOPTools_DSFiller* pDF)
880 TopoDS_Vertex V11, V12, V21, V22;
881 TopExp::Vertices( W1, V11, V12 );
882 TopExp::Vertices( W2, V21, V22 );
884 if (V11.IsSame(V21) || V11.IsSame(V22) ||
885 V12.IsSame(V21) || V12.IsSame(V22))
887 Standard_Boolean isCV1 = V11.IsSame(V21) || V11.IsSame(V22);
888 Standard_Boolean isCV2 = V12.IsSame(V21) || V12.IsSame(V22);
889 if (isCV1 && !IsAutonomVertex(V11, F1, F2, pDF->DS(), pDF->PaveFiller()))
892 return Standard_False;
893 if (!IsAutonomVertex(V12, F1, F2, pDF->DS(), pDF->PaveFiller()))
894 return Standard_False;
896 if (!isCV1 && !IsAutonomVertex(V12, F1, F2, pDF->DS(), pDF->PaveFiller()))
897 return Standard_False;
899 TopoDS_Vertex CV = (V11.IsSame(V21) || V11.IsSame(V22))? V11 : V12;
901 TopoDS_Iterator itw( W1 );
902 for (; itw.More(); itw.Next())
904 E1 = TopoDS::Edge(itw.Value());
905 TopoDS_Vertex V1, V2;
906 TopExp::Vertices( E1, V1, V2 );
907 if (V1.IsSame(CV) || V2.IsSame(CV))
910 itw.Initialize( W2 );
911 E2 = TopoDS::Edge(itw.Value());
914 Handle(Geom_Curve) C1 = BRep_Tool::Curve( E1, f, l );
915 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
916 C1 = (*((Handle(Geom_TrimmedCurve)*)&C1))->BasisCurve();
918 Handle(Geom_Curve) C2 = BRep_Tool::Curve( E2, f, l );
919 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
920 C2 = (*((Handle(Geom_TrimmedCurve)*)&C2))->BasisCurve();
922 if (C1->IsInstance(STANDARD_TYPE(Geom_Line)) &&
923 C2->IsInstance(STANDARD_TYPE(Geom_Line)))
925 Handle(Geom_Line) L1 = *((Handle(Geom_Line)*) &C1);
926 gp_Ax1 Axis1 = L1->Position();
927 Handle(Geom_Line) L2 = *((Handle(Geom_Line)*) &C2);
928 gp_Ax1 Axis2 = L2->Position();
929 if (! Axis1.IsParallel( Axis2, Precision::Angular() ))
930 return Standard_False;
933 return Standard_True;
936 return Standard_False;
939 //=======================================================================
940 //function : AreClosed
941 //purpose : define if two edges are connex by two vertices
942 //=======================================================================
944 static Standard_Boolean AreClosed(const TopoDS_Edge& E1,
945 const TopoDS_Edge& E2)
947 TopoDS_Vertex V11, V12, V21, V22;
948 TopExp::Vertices( E1, V11, V12 );
949 TopExp::Vertices( E2, V21, V22 );
951 if (V11.IsSame(V21) && V12.IsSame(V22) ||
952 V11.IsSame(V22) && V12.IsSame(V21))
953 return Standard_True;
955 return Standard_False;
958 //=======================================================================
959 //function : BSplineEdges
961 //=======================================================================
963 static Standard_Boolean BSplineEdges(const TopoDS_Edge& E1,
964 const TopoDS_Edge& E2,
965 const Standard_Integer par1,
966 const Standard_Integer par2,
967 Standard_Real& angle)
969 Standard_Real first1, last1, first2, last2, Param1, Param2;
971 Handle(Geom_Curve) C1 = BRep_Tool::Curve( E1, first1, last1 );
972 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
973 C1 = (*((Handle(Geom_TrimmedCurve)*)&C1))->BasisCurve();
975 Handle(Geom_Curve) C2 = BRep_Tool::Curve( E2, first2, last2 );
976 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
977 C2 = (*((Handle(Geom_TrimmedCurve)*)&C2))->BasisCurve();
979 if (!C1->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)) ||
980 !C2->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)))
981 return Standard_False;
983 Param1 = (par1 == 0)? first1 : last1;
984 Param2 = (par2 == 0)? first2 : last2;
988 C1->D1( Param1, Pnt1, Der1 );
989 C2->D1( Param2, Pnt2, Der2 );
991 if (Der1.Magnitude() <= gp::Resolution() ||
992 Der2.Magnitude() <= gp::Resolution())
995 angle = Der1.Angle(Der2);
997 return Standard_True;
1000 //=======================================================================
1001 //function : AngleWireEdge
1003 //=======================================================================
1005 static Standard_Real AngleWireEdge(const TopoDS_Wire& aWire,
1006 const TopoDS_Edge& anEdge)
1008 TopoDS_Vertex V11, V12, V21, V22, CV;
1009 TopExp::Vertices( aWire, V11, V12 );
1010 TopExp::Vertices( anEdge, V21, V22 );
1011 CV = (V11.IsSame(V21) || V11.IsSame(V22))? V11 : V12;
1012 TopoDS_Edge FirstEdge;
1013 TopoDS_Iterator itw(aWire);
1014 for (; itw.More(); itw.Next())
1016 FirstEdge = TopoDS::Edge(itw.Value());
1017 TopoDS_Vertex v1, v2;
1018 TopExp::Vertices( FirstEdge, v1, v2 );
1019 if (v1.IsSame(CV) || v2.IsSame(CV))
1026 Standard_Real Angle;
1027 if (V11.IsSame(CV) && V21.IsSame(CV))
1029 BSplineEdges( FirstEdge, anEdge, 0, 0, Angle );
1030 Angle = M_PI - Angle;
1032 else if (V11.IsSame(CV) && V22.IsSame(CV))
1033 BSplineEdges( FirstEdge, anEdge, 0, 1, Angle );
1034 else if (V12.IsSame(CV) && V21.IsSame(CV))
1035 BSplineEdges( FirstEdge, anEdge, 1, 0, Angle );
1038 BSplineEdges( FirstEdge, anEdge, 1, 1, Angle );
1039 Angle = M_PI - Angle;
1045 //=======================================================================
1046 //function : ReconstructPCurves
1048 //=======================================================================
1050 static void ReconstructPCurves(const TopoDS_Edge& anEdge)
1053 Handle(Geom_Curve) C3d = BRep_Tool::Curve(anEdge, f, l);
1055 BRep_ListIteratorOfListOfCurveRepresentation
1056 itcr( (Handle(BRep_TEdge)::DownCast(anEdge.TShape()))->ChangeCurves() );
1057 for (; itcr.More(); itcr.Next())
1059 Handle( BRep_CurveRepresentation ) CurveRep = itcr.Value();
1060 if (CurveRep->IsCurveOnSurface())
1062 Handle(Geom_Surface) theSurf = CurveRep->Surface();
1063 TopLoc_Location theLoc = CurveRep->Location();
1064 theLoc = anEdge.Location() * theLoc;
1065 theSurf = Handle(Geom_Surface)::DownCast
1066 (theSurf->Transformed(theLoc.Transformation()));
1067 Handle(Geom2d_Curve) ProjPCurve =
1068 GeomProjLib::Curve2d( C3d, f, l, theSurf );
1069 CurveRep->PCurve( ProjPCurve );
1074 //=======================================================================
1075 //function : ConcatPCurves
1077 //=======================================================================
1079 static Handle(Geom2d_Curve) ConcatPCurves(const TopoDS_Edge& E1,
1080 const TopoDS_Edge& E2,
1081 const TopoDS_Face& F,
1082 const Standard_Boolean After,
1083 Standard_Real& newFirst,
1084 Standard_Real& newLast)
1086 Standard_Real Tol = 1.e-7;
1087 GeomAbs_Shape Continuity = GeomAbs_C1;
1088 Standard_Integer MaxDeg = 14;
1089 Standard_Integer MaxSeg = 16;
1091 Standard_Real first1, last1, first2, last2;
1092 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1094 PCurve1 = BRep_Tool::CurveOnSurface( E1, F, first1, last1 );
1095 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
1096 PCurve1 = (*((Handle(Geom2d_TrimmedCurve)*)&PCurve1))->BasisCurve();
1098 PCurve2 = BRep_Tool::CurveOnSurface( E2, F, first2, last2 );
1099 if (PCurve2->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
1100 PCurve2 = (*((Handle(Geom2d_TrimmedCurve)*)&PCurve2))->BasisCurve();
1102 if (PCurve1 == PCurve2)
1104 newPCurve = PCurve1;
1105 newFirst = Min( first1, first2 );
1106 newLast = Max( last1, last2 );
1108 else if (PCurve1->DynamicType() == PCurve2->DynamicType() &&
1109 (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)) ||
1110 PCurve1->IsKind(STANDARD_TYPE(Geom2d_Conic))))
1112 newPCurve = PCurve1;
1114 P1 = PCurve2->Value( first2 );
1115 P2 = PCurve2->Value( last2 );
1116 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)))
1118 Handle(Geom2d_Line) Lin1 = *((Handle(Geom2d_Line)*) &PCurve1);
1119 gp_Lin2d theLin = Lin1->Lin2d();
1120 first2 = ElCLib::Parameter( theLin, P1 );
1121 last2 = ElCLib::Parameter( theLin, P2 );
1123 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Circle)))
1125 Handle(Geom2d_Circle) Circ1 = *((Handle(Geom2d_Circle)*) &PCurve1);
1126 gp_Circ2d theCirc = Circ1->Circ2d();
1127 first2 = ElCLib::Parameter( theCirc, P1 );
1128 last2 = ElCLib::Parameter( theCirc, P2 );
1130 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Ellipse)))
1132 Handle(Geom2d_Ellipse) Ell1 = *((Handle(Geom2d_Ellipse)*) &PCurve1);
1133 gp_Elips2d theElips = Ell1->Elips2d();
1134 first2 = ElCLib::Parameter( theElips, P1 );
1135 last2 = ElCLib::Parameter( theElips, P2 );
1137 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Parabola)))
1139 Handle(Geom2d_Parabola) Parab1 = *((Handle(Geom2d_Parabola)*) &PCurve1);
1140 gp_Parab2d theParab = Parab1->Parab2d();
1141 first2 = ElCLib::Parameter( theParab, P1 );
1142 last2 = ElCLib::Parameter( theParab, P2 );
1144 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Hyperbola)))
1146 Handle(Geom2d_Hyperbola) Hypr1 = *((Handle(Geom2d_Hyperbola)*) &PCurve1);
1147 gp_Hypr2d theHypr = Hypr1->Hypr2d();
1148 first2 = ElCLib::Parameter( theHypr, P1 );
1149 last2 = ElCLib::Parameter( theHypr, P2 );
1151 newFirst = Min( first1, first2 );
1152 newLast = Max( last1, last2 );
1156 Handle(Geom2d_TrimmedCurve) TC1 = new Geom2d_TrimmedCurve( PCurve1, first1, last1 );
1157 Handle(Geom2d_TrimmedCurve) TC2 = new Geom2d_TrimmedCurve( PCurve2, first2, last2 );
1158 Geom2dConvert_CompCurveToBSplineCurve Concat2d( TC1 );
1159 Concat2d.Add( TC2, Precision::Confusion(), After );
1160 newPCurve = Concat2d.BSplineCurve();
1161 if (newPCurve->Continuity() < GeomAbs_C1)
1163 Geom2dConvert_ApproxCurve Approx2d( newPCurve, Tol, Continuity, MaxSeg, MaxDeg );
1164 if (Approx2d.HasResult())
1165 newPCurve = Approx2d.Curve();
1167 newFirst = newPCurve->FirstParameter();
1168 newLast = newPCurve->LastParameter();
1174 //=======================================================================
1176 //purpose : glue two edges.
1177 //=======================================================================
1179 static TopoDS_Edge Glue(const TopoDS_Edge& E1,
1180 const TopoDS_Edge& E2,
1181 const TopoDS_Vertex& Vfirst,
1182 const TopoDS_Vertex& Vlast,
1183 const Standard_Boolean After,
1184 const TopoDS_Face& F1,
1185 const Standard_Boolean addPCurve1,
1186 const TopoDS_Face& F2,
1187 const Standard_Boolean addPCurve2)
1189 Standard_Real Tol = 1.e-7;
1190 GeomAbs_Shape Continuity = GeomAbs_C1;
1191 Standard_Integer MaxDeg = 14;
1192 Standard_Integer MaxSeg = 16;
1194 Handle(Geom_Curve) C1, C2, newCurve;
1195 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1196 Standard_Real first1, last1, first2, last2, fparam=0., lparam=0.;
1197 Standard_Boolean IsCanonic = Standard_False;
1199 C1 = BRep_Tool::Curve( E1, first1, last1 );
1200 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
1201 C1 = (*((Handle(Geom_TrimmedCurve)*)&C1))->BasisCurve();
1203 C2 = BRep_Tool::Curve( E2, first2, last2 );
1204 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
1205 C2 = (*((Handle(Geom_TrimmedCurve)*)&C2))->BasisCurve();
1210 fparam = Min( first1, first2 );
1211 lparam = Max( last1, last2 );
1213 else if (C1->DynamicType() == C2->DynamicType() &&
1214 (C1->IsInstance(STANDARD_TYPE(Geom_Line)) ||
1215 C1->IsKind(STANDARD_TYPE(Geom_Conic))))
1217 IsCanonic = Standard_True;
1222 Handle(Geom_TrimmedCurve) TC1 = new Geom_TrimmedCurve( C1, first1, last1 );
1223 Handle(Geom_TrimmedCurve) TC2 = new Geom_TrimmedCurve( C2, first2, last2 );
1224 GeomConvert_CompCurveToBSplineCurve Concat( TC1 );
1225 Concat.Add( TC2, Precision::Confusion(), After );
1226 newCurve = Concat.BSplineCurve();
1227 if (newCurve->Continuity() < GeomAbs_C1)
1229 GeomConvert_ApproxCurve Approx3d( newCurve, Tol, Continuity, MaxSeg, MaxDeg );
1230 if (Approx3d.HasResult())
1231 newCurve = Approx3d.Curve();
1233 fparam = newCurve->FirstParameter();
1234 lparam = newCurve->LastParameter();
1237 TopoDS_Edge newEdge;
1241 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast );
1243 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast, fparam, lparam );
1245 Standard_Real newFirst, newLast;
1248 newPCurve = ConcatPCurves( E1, E2, F1, After, newFirst, newLast );
1249 BB.UpdateEdge( newEdge, newPCurve, F1, 0. );
1250 BB.Range( newEdge, F1, newFirst, newLast );
1254 newPCurve = ConcatPCurves( E1, E2, F2, After, newFirst, newLast );
1255 BB.UpdateEdge( newEdge, newPCurve, F2, 0. );
1256 BB.Range( newEdge, F2, newFirst, newLast );
1263 //=======================================================================
1264 //function : FindNewVerticesOnBoundsOfFace
1266 //=======================================================================
1268 static void FindNewVerticesOnBoundsOfFace(const BOPTools_DSFiller& pDF,
1269 const TopoDS_Face& aFace,
1270 const Standard_Integer iFace,
1271 TopTools_DataMapOfShapeShape& VEmap)
1273 TopTools_IndexedMapOfShape OldVertices;
1274 TopExp::MapShapes( aFace, TopAbs_VERTEX, OldVertices );
1276 const BOPTools_SplitShapesPool& aPool = pDF.SplitShapesPool();
1278 TopExp_Explorer Explo( aFace, TopAbs_EDGE );
1279 for (; Explo.More(); Explo.Next())
1281 TopoDS_Shape anEdge = Explo.Current();
1282 Standard_Integer eind = pDF.DS().ShapeIndex(anEdge,iFace);
1283 const BOPTools_ListOfPaveBlock& aSplitEdges = aPool( pDF.DS().RefEdge(eind) );
1284 BOPTools_ListIteratorOfListOfPaveBlock itpb( aSplitEdges );
1285 for (; itpb.More(); itpb.Next())
1287 BOPTools_PaveBlock& aPaveBlock = itpb.Value();
1288 TopoDS_Shape aSplit = pDF.DS().GetShape( aPaveBlock.Edge() );
1289 TopoDS_Edge aNewEdge = TopoDS::Edge(aSplit);
1290 TopoDS_Vertex V1, V2;
1291 TopExp::Vertices( aNewEdge, V1, V2 );
1292 if (!OldVertices.Contains( V1 ))
1293 VEmap.Bind( V1, anEdge );
1294 if (!OldVertices.Contains( V2 ))
1295 VEmap.Bind( V2, anEdge );
1300 //=======================================================================
1301 //function : CheckIntersFF
1303 //=======================================================================
1305 static Standard_Boolean CheckIntersFF(const BOPTools_DSFiller& pDF,
1306 const TopoDS_Edge& RefEdge,
1307 const TopoDS_Face& F1,
1308 const TopoDS_Face& F2,
1309 TopTools_IndexedMapOfShape& TrueEdges)
1311 Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
1312 Standard_Boolean isPlane1 = Standard_False, isPlane2 = Standard_False;
1314 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F1);
1315 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1316 aSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&aSurf))->BasisSurface();
1317 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1318 isPlane1 = Standard_True;
1319 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1320 isEl1 = Standard_True;
1322 aSurf = BRep_Tool::Surface(F2);
1323 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1324 aSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&aSurf))->BasisSurface();
1325 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1326 isPlane2 = Standard_True;
1327 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1328 isEl2 = Standard_True;
1330 if (isPlane1 || isPlane2)
1331 return Standard_True;
1334 return Standard_True;
1336 const BooleanOperations_ShapesDataStructure& aDS = pDF.DS();
1337 BOPTools_InterferencePool* anIntrPool = (BOPTools_InterferencePool*)&pDF.InterfPool();
1338 BOPTools_CArray1OfSSInterference& aFFs = anIntrPool->SSInterferences();
1339 Standard_Integer aNb = aFFs.Extent();
1340 Standard_Integer i, j, nbe = 0;
1342 TopTools_SequenceOfShape Edges;
1344 for (i = 1; i <= aNb; i++)
1346 BOPTools_SSInterference& aFFi = aFFs(i);
1347 BOPTools_SequenceOfCurves& aBCurves = aFFi.Curves();
1348 Standard_Integer aNbCurves = aBCurves.Length();
1350 for (j = 1; j <= aNbCurves; j++)
1352 BOPTools_Curve& aBC = aBCurves(j);
1353 const BOPTools_ListOfPaveBlock& aSectEdges = aBC.NewPaveBlocks();
1355 BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSectEdges);
1357 for (; aPBIt.More(); aPBIt.Next())
1359 BOPTools_PaveBlock& aPB=aPBIt.Value();
1360 Standard_Integer nSect = aPB.Edge();
1361 TopoDS_Edge anEdge = TopoDS::Edge(aDS.Shape(nSect));
1362 Edges.Append( anEdge );
1369 return Standard_True;
1371 //define tangents of RefEdge on start and on end
1372 BRepAdaptor_Curve cref(RefEdge);
1373 gp_Vec RefTangFirst = cref.DN(cref.FirstParameter(), 1);
1374 gp_Vec RefTangLast = cref.DN(cref.LastParameter(), 1);
1376 //find the start edge and take it from Edges
1377 TopoDS_Edge StartEdge; //, StartEonF1, StartEonF2, EndEonF1, EndEonF2;
1379 TopTools_DataMapOfShapeShape VEmapF1, VEmapF2;
1380 FindNewVerticesOnBoundsOfFace( pDF, F1, 1, VEmapF1 );
1381 FindNewVerticesOnBoundsOfFace( pDF, F2, 2, VEmapF2 );
1383 Standard_Real AngTol = 0.1;
1384 Standard_Boolean V1onBound = Standard_False;
1385 Standard_Boolean V2onBound = Standard_False;
1386 TopoDS_Vertex V1, V2, Vcur;
1387 gp_Vec TangFirst, TangLast, TangCur;
1388 for (i = 1; i <= Edges.Length(); i++)
1390 StartEdge = TopoDS::Edge(Edges(i));
1391 TopExp::Vertices( StartEdge, V1, V2 );
1392 V1onBound = VEmapF1.IsBound(V1) || VEmapF2.IsBound(V1); // && ?
1393 V2onBound = VEmapF1.IsBound(V2) || VEmapF2.IsBound(V2); // && ?
1394 if (V1onBound || V2onBound)
1396 BRepAdaptor_Curve CE(StartEdge);
1397 TangFirst = CE.DN( CE.FirstParameter(), 1 );
1398 TangLast = CE.DN( CE.LastParameter(), 1 );
1401 if (TangFirst.IsParallel( RefTangFirst, AngTol ) ||
1402 TangFirst.IsParallel( RefTangLast, AngTol ))
1403 break; //start edged found
1407 if (TangLast.IsParallel( RefTangLast, AngTol ) ||
1408 TangLast.IsParallel( RefTangFirst, AngTol ))
1409 break; //start edged found
1414 if (i > Edges.Length()) //start edged not found
1415 return Standard_False;
1417 if (V1onBound && V2onBound)
1419 if (TangFirst.IsParallel(RefTangFirst,AngTol) && TangLast.IsParallel(RefTangLast,AngTol) ||
1420 TangFirst.IsParallel(RefTangLast,AngTol) && TangLast.IsParallel(RefTangFirst,AngTol))
1422 TrueEdges.Add( Edges(i) );
1423 return Standard_True;
1426 return Standard_False;
1429 //StartEonF1 = (V1onBound)? VEmapF1( V1 ) : VEmapF1( V2 );
1430 //StartEonF2 = (V1onBound)? VEmapF2( V1 ) : VEmapF2( V2 );
1432 TrueEdges.Add( Edges(i) );
1434 Vcur = (V1onBound)? V2 : V1;
1435 TangCur = (V1onBound)? TangLast : TangFirst;
1439 //build the chain from StartEdge till the opposite bound of face
1442 TColStd_SequenceOfInteger Candidates;
1443 for (i = 1; i <= Edges.Length(); i++)
1445 TopoDS_Edge anEdge = TopoDS::Edge(Edges(i));
1446 TopExp::Vertices( anEdge, V1, V2 );
1447 if (V1.IsSame(Vcur) || V2.IsSame(Vcur))
1448 Candidates.Append(i);
1450 if (Candidates.IsEmpty())
1453 return Standard_False;
1456 Standard_Integer minind = 1;
1457 if (Candidates.Length() > 1)
1459 Standard_Real MinAngle = RealLast();
1460 for (i = 1; i <= Candidates.Length(); i++)
1462 TopoDS_Edge anEdge = TopoDS::Edge(Edges(Candidates(i)));
1463 TopExp::Vertices( anEdge, V1, V2 );
1464 Standard_Boolean ConnectByFirst = (Vcur.IsSame(V1))? Standard_True : Standard_False;
1465 BRepAdaptor_Curve CE(anEdge);
1466 gp_Vec aTang = (ConnectByFirst)?
1467 CE.DN( CE.FirstParameter(), 1 ) : CE.DN( CE.LastParameter(), 1 );
1468 if (!ConnectByFirst)
1470 Standard_Real anAngle = TangCur.Angle(aTang);
1471 if (anAngle < MinAngle)
1478 TopoDS_Edge CurEdge = TopoDS::Edge(Edges(Candidates(minind)));
1479 TrueEdges.Add( CurEdge );
1480 Edges.Remove(Candidates(minind));
1481 TopExp::Vertices( CurEdge, V1, V2 );
1482 Standard_Boolean ConnectByFirst = (Vcur.IsSame(V1))? Standard_True : Standard_False;
1483 Vcur = (ConnectByFirst)? V2 : V1;
1484 BRepAdaptor_Curve CE(CurEdge);
1485 TangCur = (ConnectByFirst)? CE.DN( CE.LastParameter(), 1 ) : CE.DN( CE.FirstParameter(), 1 );
1486 if (!ConnectByFirst)
1488 //check if Vcur is on bounds of faces
1489 if (VEmapF1.IsBound(Vcur) || VEmapF2.IsBound(Vcur))
1493 if (TangCur.IsParallel( RefTangFirst, AngTol ) ||
1494 TangCur.IsParallel( RefTangLast, AngTol ))
1495 return Standard_True;
1498 return Standard_False;
1501 //=======================================================================
1502 //function : AssembleEdge
1504 //=======================================================================
1506 static TopoDS_Edge AssembleEdge(const BOPTools_DSFiller* pDF,
1507 const TopoDS_Face& F1,
1508 const TopoDS_Face& F2,
1509 const Standard_Boolean addPCurve1,
1510 const Standard_Boolean addPCurve2,
1511 const TopTools_SequenceOfShape& EdgesForConcat)
1513 TopoDS_Edge CurEdge = TopoDS::Edge( EdgesForConcat(1) );
1514 for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
1516 TopoDS_Edge anEdge = TopoDS::Edge( EdgesForConcat(j) );
1517 Standard_Boolean After = Standard_False;
1518 TopoDS_Vertex Vfirst, Vlast;
1519 if (AreClosed( CurEdge, anEdge ))
1521 TopoDS_Vertex V1, V2;
1522 TopExp::Vertices( CurEdge, V1, V2 );
1523 if (IsAutonomVertex( V1, F1, F2, pDF->DS(), pDF->PaveFiller() ))
1525 After = Standard_False;
1526 Vfirst = Vlast = V2;
1530 After = Standard_True;
1531 Vfirst = Vlast = V1;
1536 TopoDS_Vertex CV, V11, V12, V21, V22;
1537 TopExp::CommonVertex( CurEdge, anEdge, CV );
1538 TopExp::Vertices( CurEdge, V11, V12 );
1539 TopExp::Vertices( anEdge, V21, V22 );
1540 if (V11.IsSame(CV) && V21.IsSame(CV))
1545 else if (V11.IsSame(CV) && V22.IsSame(CV))
1550 else if (V12.IsSame(CV) && V21.IsSame(CV))
1560 } //end of else (open wire)
1562 TopoDS_Edge NewEdge = Glue(CurEdge, anEdge,
1563 Vfirst, Vlast, After,
1564 F1, addPCurve1, F2, addPCurve2);
1566 } //end of for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
1571 //=======================================================================
1572 //function : Inter3D
1574 //=======================================================================
1576 void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1,
1577 const TopoDS_Face& F2,
1578 TopTools_ListOfShape& L1,
1579 TopTools_ListOfShape& L2,
1580 const TopAbs_State Side,
1581 const TopoDS_Edge& RefEdge,
1582 const Standard_Boolean IsRefEdgeDefined)
1587 char* name = new char[100];
1588 sprintf(name,"FF_%d",NbFaces++);
1589 DBRep::Set(name,F1);
1590 sprintf(name,"FF_%d",NbFaces++);
1591 DBRep::Set(name,F2);
1595 TopoDS_Face cpF1=F1;
1596 TopoDS_Face cpF2=F2;
1597 // create 3D curves on faces
1598 BRepLib::BuildCurves3d(cpF1);
1599 BRepLib::BuildCurves3d(cpF2);
1601 BOPTools_DSFiller pDF1, pDF2;
1602 pDF1.SetShapes(cpF1, cpF2);
1606 BOPTools_DSFiller * pDF = &pDF1;
1607 TopTools_IndexedMapOfShape TrueEdges;
1608 if (IsRefEdgeDefined && !CheckIntersFF( pDF1, RefEdge, cpF1, cpF2, TrueEdges ))
1612 pDF2.SetShapes(cpF1, cpF2);
1614 CheckIntersFF( pDF2, RefEdge, cpF1, cpF2, TrueEdges );
1618 Standard_Boolean addPCurve1 = pDF->PaveFiller().SectionAttribute().PCurveOnS1();
1619 Standard_Boolean addPCurve2 = pDF->PaveFiller().SectionAttribute().PCurveOnS2();
1621 const BooleanOperations_ShapesDataStructure& aDS = pDF->DS();
1622 BOPTools_InterferencePool* anIntrPool = (BOPTools_InterferencePool*)& pDF->InterfPool();
1623 BOPTools_CArray1OfSSInterference& aFFs = anIntrPool->SSInterferences();
1624 Standard_Integer aNb = aFFs.Extent();
1625 Standard_Integer i = 0, j = 0, k;
1627 L1.Clear(); L2.Clear();
1628 TopAbs_Orientation O1,O2;
1630 for (i = 1; i <= aNb; i++) {
1631 BOPTools_SSInterference& aFFi = aFFs(i);
1632 BOPTools_SequenceOfCurves& aBCurves = aFFi.Curves();
1633 Standard_Integer aNbCurves = aBCurves.Length();
1635 for (j = 1; j <= aNbCurves; j++) {
1636 BOPTools_Curve& aBC = aBCurves(j);
1637 const BOPTools_ListOfPaveBlock& aSectEdges = aBC.NewPaveBlocks();
1639 BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSectEdges);
1641 for (; aPBIt.More(); aPBIt.Next()) {
1642 BOPTools_PaveBlock& aPB=aPBIt.Value();
1643 Standard_Integer nSect = aPB.Edge();
1644 TopoDS_Edge anEdge = TopoDS::Edge(aDS.Shape(nSect));
1645 if (!TrueEdges.IsEmpty() && !TrueEdges.Contains(anEdge))
1649 const Handle(Geom_Curve)& aC3DE = BRep_Tool::Curve(anEdge, f, l);
1650 Handle(Geom_TrimmedCurve) aC3DETrim;
1653 aC3DETrim = new Geom_TrimmedCurve(aC3DE, f, l);
1656 Standard_Real aTolEdge = BRep_Tool::Tolerance(anEdge);
1658 if (!BOPTools_Tools2D::HasCurveOnSurface(anEdge, cpF1)) {
1659 Handle(Geom2d_Curve) aC2d = aBC.Curve().FirstCurve2d();
1660 if(!aC3DETrim.IsNull()) {
1661 Handle(Geom2d_Curve) aC2dNew;
1663 if(aC3DE->IsPeriodic()) {
1664 BOPTools_Tools2D::AdjustPCurveOnFace(cpF1, f, l, aC2d, aC2dNew);
1667 BOPTools_Tools2D::AdjustPCurveOnFace(cpF1, aC3DETrim, aC2d, aC2dNew);
1671 aBB.UpdateEdge(anEdge, aC2d, cpF1, aTolEdge);
1674 if (!BOPTools_Tools2D::HasCurveOnSurface(anEdge, cpF2)) {
1675 Handle(Geom2d_Curve) aC2d = aBC.Curve().SecondCurve2d();
1676 if(!aC3DETrim.IsNull()) {
1677 Handle(Geom2d_Curve) aC2dNew;
1679 if(aC3DE->IsPeriodic()) {
1680 BOPTools_Tools2D::AdjustPCurveOnFace(cpF2, f, l, aC2d, aC2dNew);
1683 BOPTools_Tools2D::AdjustPCurveOnFace(cpF2, aC3DETrim, aC2d, aC2dNew);
1687 aBB.UpdateEdge(anEdge, aC2d, cpF2, aTolEdge);
1690 OrientSection (anEdge, F1, F2, O1, O2);
1691 if (Side == TopAbs_OUT) {
1692 O1 = TopAbs::Reverse(O1);
1693 O2 = TopAbs::Reverse(O2);
1696 L1.Append (anEdge.Oriented(O1));
1697 L2.Append (anEdge.Oriented(O2));
1701 char* name = new char[100];
1702 sprintf(name,"EI_%d",NbNewEdges++);
1703 DBRep::Set(name,anEdge.Oriented(O1));
1711 Standard_Real aSameParTol = Precision::Confusion();
1712 Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
1714 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(cpF1);
1715 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1716 aSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&aSurf))->BasisSurface();
1717 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1718 addPCurve1 = Standard_False;
1719 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1720 isEl1 = Standard_True;
1722 aSurf = BRep_Tool::Surface(cpF2);
1723 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1724 aSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&aSurf))->BasisSurface();
1725 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1726 addPCurve2 = Standard_False;
1727 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1728 isEl2 = Standard_True;
1730 if (L1.Extent() > 1 && (!isEl1 || !isEl2)) {
1731 TopTools_SequenceOfShape eseq;
1732 TopTools_SequenceOfShape EdgesForConcat;
1734 if (!TrueEdges.IsEmpty())
1736 for (i = TrueEdges.Extent(); i >= 1; i--)
1737 EdgesForConcat.Append( TrueEdges(i) );
1738 TopoDS_Edge theEdge =
1739 AssembleEdge( pDF, cpF1, cpF2, addPCurve1, addPCurve2, EdgesForConcat );
1740 eseq.Append(theEdge);
1744 const BOPTools_PaveFiller& thePaveFiller = pDF->PaveFiller();
1746 TopTools_SequenceOfShape wseq;
1747 TopTools_SequenceOfShape edges;
1748 TopTools_ListIteratorOfListOfShape itl(L1);
1749 for (; itl.More(); itl.Next())
1750 edges.Append( itl.Value() );
1751 while (!edges.IsEmpty())
1753 TopoDS_Edge anEdge = TopoDS::Edge( edges.First() );
1754 TopoDS_Wire aWire = BRepLib_MakeWire( anEdge ), resWire;
1755 TColStd_SequenceOfInteger Candidates;
1756 for (k = 1; k <= wseq.Length(); k++)
1758 resWire = TopoDS::Wire(wseq(k));
1759 if (AreConnex( resWire, aWire, cpF1, cpF2, pDF ))
1761 Candidates.Append( 1 );
1765 if (Candidates.IsEmpty())
1767 wseq.Append( aWire );
1772 for (j = 2; j <= edges.Length(); j++)
1774 anEdge = TopoDS::Edge( edges(j) );
1775 //if (anEdge.IsSame(edges(Candidates.First())))
1777 aWire = BRepLib_MakeWire( anEdge );
1778 if (AreConnex( resWire, aWire, cpF1, cpF2, pDF ))
1779 Candidates.Append( j );
1781 Standard_Integer minind = 1;
1782 if (Candidates.Length() > 1)
1784 Standard_Real MinAngle = RealLast();
1785 for (j = 1; j <= Candidates.Length(); j++)
1787 anEdge = TopoDS::Edge( edges(Candidates(j)) );
1788 Standard_Real anAngle = AngleWireEdge( resWire, anEdge );
1789 if (anAngle < MinAngle)
1796 TopoDS_Wire NewWire = BRepLib_MakeWire( resWire, TopoDS::Edge(edges(Candidates(minind))) );
1798 edges.Remove(Candidates(minind));
1800 } //end of while (!edges.IsEmpty())
1802 for (i = 1; i <= wseq.Length(); i++)
1804 TopoDS_Wire aWire = TopoDS::Wire(wseq(i));
1805 TopTools_SequenceOfShape EdgesForConcat;
1808 TopoDS_Vertex StartVertex;
1809 TopoDS_Edge StartEdge;
1810 Standard_Boolean StartFound = Standard_False;
1811 TopTools_ListOfShape Elist;
1813 TopoDS_Iterator itw(aWire);
1814 for (; itw.More(); itw.Next())
1816 TopoDS_Edge anEdge = TopoDS::Edge(itw.Value());
1818 Elist.Append(anEdge);
1821 TopoDS_Vertex V1, V2;
1822 TopExp::Vertices( anEdge, V1, V2 );
1823 if (!IsAutonomVertex( V1, cpF1, cpF2, aDS, thePaveFiller ))
1827 StartFound = Standard_True;
1829 else if (!IsAutonomVertex( V2, cpF1, cpF2, aDS, thePaveFiller ))
1833 StartFound = Standard_True;
1836 Elist.Append(anEdge);
1838 } //end of for (; itw.More(); itw.Next())
1841 itl.Initialize(Elist);
1842 StartEdge = TopoDS::Edge(itl.Value());
1844 TopoDS_Vertex V1, V2;
1845 TopExp::Vertices( StartEdge, V1, V2 );
1848 EdgesForConcat.Append( StartEdge );
1849 while (!Elist.IsEmpty())
1851 for (itl.Initialize(Elist); itl.More(); itl.Next())
1853 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
1854 TopoDS_Vertex V1, V2;
1855 TopExp::Vertices( anEdge, V1, V2 );
1856 if (V1.IsSame(StartVertex))
1859 EdgesForConcat.Append( anEdge );
1863 else if (V2.IsSame(StartVertex))
1866 EdgesForConcat.Append( anEdge );
1871 } //end of while (!Elist.IsEmpty())
1872 } //end of if (aWire.Closed())
1875 BRepTools_WireExplorer Wexp( aWire );
1876 for (; Wexp.More(); Wexp.Next())
1877 EdgesForConcat.Append( Wexp.Current() );
1880 TopoDS_Edge theEdge =
1881 AssembleEdge( pDF, cpF1, cpF2, addPCurve1, addPCurve2, EdgesForConcat );
1882 eseq.Append( theEdge );
1884 } //end of else (when TrueEdges is empty)
1886 if (eseq.Length() < L1.Extent())
1890 for (i = 1; i <= eseq.Length(); i++)
1892 TopoDS_Edge anEdge = TopoDS::Edge(eseq(i));
1893 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1894 Standard_Real EdgeTol = BRep_Tool::Tolerance(anEdge);
1896 cout<<"Tolerance of glued E = "<<EdgeTol<<endl;
1898 if (EdgeTol > 1.e-2)
1901 if (EdgeTol >= 1.e-4)
1903 ReconstructPCurves(anEdge);
1904 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1906 cout<<"After projection tol of E = "<<BRep_Tool::Tolerance(anEdge)<<endl;
1910 OrientSection( anEdge, F1, F2, O1, O2 );
1911 if (Side == TopAbs_OUT)
1913 O1 = TopAbs::Reverse(O1);
1914 O2 = TopAbs::Reverse(O2);
1917 L1.Append( anEdge.Oriented(O1) );
1918 L2.Append( anEdge.Oriented(O2) );
1921 } //end of if (L1.Extent() > 1)
1925 TopTools_ListIteratorOfListOfShape itl(L1);
1926 for (; itl.More(); itl.Next())
1928 const TopoDS_Edge& anEdge = TopoDS::Edge( itl.Value() );
1929 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1934 //=======================================================================
1935 //function : TryProject
1937 //=======================================================================
1939 Standard_Boolean BRepOffset_Tool::TryProject
1940 (const TopoDS_Face& F1,
1941 const TopoDS_Face& F2,
1942 const TopTools_ListOfShape& Edges,
1943 TopTools_ListOfShape& LInt1,
1944 TopTools_ListOfShape& LInt2,
1945 const TopAbs_State Side,
1946 const Standard_Real TolConf)
1951 char* name = new char[100];
1952 sprintf(name,"FF_%d",NbFaces++);
1953 DBRep::Set(name,F1);
1954 sprintf(name,"FF_%d",NbFaces++);
1955 DBRep::Set(name,F2);
1959 // try to find if the edges <Edges> are laying on the face F1.
1960 LInt1.Clear(); LInt2.Clear();
1961 TopTools_ListIteratorOfListOfShape it(Edges);
1962 Standard_Boolean isOk = Standard_True;
1963 Standard_Boolean Ok = Standard_True;
1964 TopAbs_Orientation O1,O2;
1965 Handle(Geom_Surface) Bouchon = BRep_Tool::Surface(F1);
1968 for ( ; it.More(); it.Next()) {
1971 TopoDS_Edge CurE = TopoDS::Edge(it.Value());
1972 Handle(Geom_Curve) C = BRep_Tool::Curve(CurE,L,f,l);
1974 BRepLib::BuildCurve3d(CurE,BRep_Tool::Tolerance(CurE));
1975 C = BRep_Tool::Curve(CurE,L,f,l);
1977 C = new Geom_TrimmedCurve(C,f,l);
1978 if ( !L.IsIdentity()) C->Transform(L);
1979 Standard_Real TolReached;
1980 isOk = IsOnSurface(C,Bouchon,TolConf,TolReached);
1983 B.UpdateEdge(CurE,TolReached);
1984 BuildPCurves(CurE,F1);
1985 OrientSection (CurE,F1,F2,O1,O2);
1986 if (Side == TopAbs_OUT) {
1987 O1 = TopAbs::Reverse(O1);
1988 O2 = TopAbs::Reverse(O2);
1990 LInt1.Append (CurE.Oriented(O1));
1991 LInt2.Append (CurE.Oriented(O2));
1995 char* name = new char[100];
1996 sprintf(name,"EI_%d",NbNewEdges++);
1997 DBRep::Set(name,CurE.Oriented(O1));
2002 Ok = Standard_False;
2008 //=======================================================================
2009 //function : InterOrExtent
2011 //=======================================================================
2013 void BRepOffset_Tool::InterOrExtent(const TopoDS_Face& F1,
2014 const TopoDS_Face& F2,
2015 TopTools_ListOfShape& L1,
2016 TopTools_ListOfShape& L2,
2017 const TopAbs_State Side)
2022 char* name = new char[100];
2023 sprintf(name,"FF_%d",NbFaces++);
2024 DBRep::Set(name,F1);
2025 sprintf(name,"FF_%d",NbFaces++);
2026 DBRep::Set(name,F2);
2030 Handle (Geom_Curve) CI;
2032 TopAbs_Orientation O1,O2;
2033 L1.Clear(); L2.Clear();
2034 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
2035 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
2037 if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2038 Handle(Geom_RectangularTrimmedSurface) RTS ;
2039 RTS = *((Handle(Geom_RectangularTrimmedSurface)*) &S1);
2040 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
2041 S1 = RTS->BasisSurface();
2044 if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2045 Handle(Geom_RectangularTrimmedSurface) RTS ;
2046 RTS = *((Handle(Geom_RectangularTrimmedSurface)*) &S2);
2047 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
2048 S2 = RTS->BasisSurface();
2052 GeomInt_IntSS Inter (S1,S2, Precision::Confusion());
2054 if (Inter.IsDone()) {
2055 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
2058 if (ToSmall(CI)) continue;
2059 TopoDS_Edge E = BRepLib_MakeEdge(CI);
2060 BuildPCurves (E,F1);
2061 BuildPCurves (E,F2);
2062 OrientSection (E,F1,F2,O1,O2);
2063 if (Side == TopAbs_OUT) {
2064 O1 = TopAbs::Reverse(O1);
2065 O2 = TopAbs::Reverse(O2);
2067 L1.Append (E.Oriented(O1));
2068 L2.Append (E.Oriented(O2));
2072 char* name = new char[100];
2073 sprintf(name,"EI_%d",NbNewEdges++);
2074 DBRep::Set(name,E.Oriented(O1));
2081 //=======================================================================
2082 //function : ExtentEdge
2084 //=======================================================================
2086 static void ExtentEdge(const TopoDS_Face& F,
2087 const TopoDS_Face& EF,
2088 const TopoDS_Edge& E,
2091 BRepAdaptor_Curve CE(E);
2092 GeomAbs_CurveType Type = CE.GetType();
2093 TopoDS_Shape aLocalEdge = E.EmptyCopied();
2094 NE = TopoDS::Edge(aLocalEdge);
2095 // NE = TopoDS::Edge(E.EmptyCopied());
2097 if (Type == GeomAbs_Line || Type == GeomAbs_Circle || Type == GeomAbs_Ellipse ||
2098 Type == GeomAbs_Hyperbola || Type == GeomAbs_Parabola) {
2101 // Extension en tangence jusqu'au bord de la surface.
2102 Standard_Real PMax = 1.e2;
2104 Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
2105 Standard_Real umin,umax,vmin,vmax;
2107 S->Bounds(umin,umax,vmin,vmax);
2108 umin = Max(umin,-PMax);vmin = Max(vmin,-PMax);
2109 umax = Min(umax, PMax);vmax = Min(vmax, PMax);
2113 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f,l);
2115 //calcul point cible . ie point d'intersection du prolongement tangent et des bords.
2118 C2d->D1(CE.FirstParameter(),P,Tang);
2119 Standard_Real tx,ty,tmin;
2120 tx = ty = Precision::Infinite();
2121 if (Abs(Tang.X()) > Precision::Confusion())
2122 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
2123 if (Abs(Tang.Y()) > Precision::Confusion())
2124 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
2127 gp_Pnt2d PF2d (P.X() - Tang.X(),P.Y() - Tang.Y());
2129 C2d->D1(CE.LastParameter(),P,Tang);
2130 tx = ty = Precision::Infinite();
2131 if (Abs(Tang.X()) > Precision::Confusion())
2132 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
2133 if (Abs(Tang.Y()) > Precision::Confusion())
2134 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
2137 gp_Pnt2d PL2d (P.X() + Tang.X(),P.Y() + Tang.Y());
2139 Handle(Geom_Curve) CC = GeomAPI::To3d(C2d,gp_Pln(gp::XOY()));
2140 gp_Pnt PF(PF2d.X(),PF2d.Y(),0.);
2141 gp_Pnt PL(PL2d.X(),PL2d.Y(),0.);
2143 Handle(Geom_BoundedCurve) ExtC = Handle(Geom_BoundedCurve)::DownCast(CC);
2144 if (ExtC.IsNull()) return;
2146 GeomLib::ExtendCurveToPoint(ExtC,PF,1,0);
2147 GeomLib::ExtendCurveToPoint(ExtC,PL,1,1);
2149 Handle(Geom2d_Curve) CNE2d = GeomAPI::To2d(ExtC,gp_Pln(gp::XOY()));
2151 //Construction de la nouvelle arrete;
2154 // B.UpdateEdge (NE,CNE2d,F,BRep_Tool::Tolerance(E));
2155 B.UpdateEdge (NE,CNE2d,EF,BRep_Tool::Tolerance(E));
2156 B.Range (NE,CNE2d->FirstParameter(), CNE2d->LastParameter());
2157 NE.Orientation(E.Orientation());
2160 char* name = new char[100];
2161 sprintf (name,"F_%d",NbExtE);
2162 DBRep::Set(name,EF);
2163 sprintf (name,"OE_%d",NbExtE);
2164 DBRep::Set (name,E);
2165 sprintf (name,"ExtE_%d",NbExtE++);
2166 DBRep::Set(name,NE);
2171 //=======================================================================
2172 //function : ProjectVertexOnEdge
2174 //=======================================================================
2176 static Standard_Boolean ProjectVertexOnEdge(TopoDS_Vertex& V,
2177 const TopoDS_Edge& E,
2178 Standard_Real TolConf)
2189 Standard_Real U = 0.;
2194 Standard_Boolean found = Standard_False;
2196 gp_Pnt P = BRep_Tool::Pnt (V);
2197 BRepAdaptor_Curve C = BRepAdaptor_Curve(E);
2198 f = C.FirstParameter(); l = C.LastParameter();
2200 if (V.Orientation() == TopAbs_FORWARD) {
2201 if (Abs(f) < Precision::Infinite()) {
2202 gp_Pnt PF = C.Value (f);
2203 if (PF.IsEqual(P,TolConf)) {
2205 found = Standard_True;
2209 if (V.Orientation() == TopAbs_REVERSED) {
2210 if (!found && Abs(l) < Precision::Infinite()) {
2211 gp_Pnt PL = C.Value (l);
2212 if (PL.IsEqual(P,TolConf)) {
2214 found = Standard_True;
2219 Extrema_ExtPC Proj(P,C);
2220 if (Proj.IsDone() && Proj.NbExt() > 0) {
2221 Standard_Real Dist2,Dist2Min = Proj.SquareDistance(1);
2222 U = Proj.Point(1).Parameter();
2223 for (Standard_Integer i = 2; i <= Proj.NbExt(); i++) {
2224 Dist2 = Proj.SquareDistance(i);
2225 if (Dist2 < Dist2Min) {
2227 U = Proj.Point(i).Parameter();
2230 found = Standard_True;
2236 Standard_Real Dist = P.Distance(C.Value(U));
2237 if (Dist > TolConf) {
2238 cout << " ProjectVertexOnEdge :distance vertex edge :"<<Dist<<endl;
2240 if (U < f - Precision::Confusion() ||
2241 U > l + Precision::Confusion()) {
2242 cout << " ProjectVertexOnEdge : hors borne :"<<endl;
2243 cout << " f = "<<f<<" l ="<<l<< " U ="<<U<<endl;
2247 cout <<"BRepOffset_Tool::ProjectVertexOnEdge Parameter no found"<<endl;
2248 if (Abs(f) < Precision::Infinite() &&
2249 Abs(l) < Precision::Infinite()) {
2257 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
2258 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
2259 aLocalShape = V.Oriented(TopAbs_INTERNAL);
2260 // TopoDS_Edge EE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
2261 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
2262 U,EE,BRep_Tool::Tolerance(E));
2268 //=======================================================================
2269 //function : Inter2d
2271 //=======================================================================
2273 void BRepOffset_Tool::Inter2d (const TopoDS_Face& F,
2274 const TopoDS_Edge& E1,
2275 const TopoDS_Edge& E2,
2276 TopTools_ListOfShape& LV,
2277 const Standard_Real TolConf)
2281 DBRep::Set("E1",E1);
2282 DBRep::Set("E2",E2);
2287 Standard_Real fl1[2],fl2[2];
2290 // Si l edge a ete etendu les pcurves ne sont pas forcement
2296 // Construction des curves 3d si elles n existent pas
2297 // utile pour coder correctement les parametres des vertex
2298 // d intersection sur les edges.
2299 //TopLoc_Location L;
2300 //Standard_Real f,l;
2301 //Handle(Geom_Curve) C3d1 = BRep_Tool::Curve(E1,L,f,l);
2302 //if (C3d1.IsNull()) {
2303 // BRepLib::BuildCurve3d(E1,BRep_Tool::Tolerance(E1));
2305 //Handle(Geom_Curve) C3d2 = BRep_Tool::Curve(E2,L,f,l);
2306 //if (C3d2.IsNull()) {
2307 // BRepLib::BuildCurve3d(E2,BRep_Tool::Tolerance(E2));
2310 Standard_Integer NbPC1 = 1, NbPC2 = 1;
2311 if (BRep_Tool::IsClosed(E1,F)) NbPC1++;
2312 if (BRep_Tool::IsClosed(E2,F)) NbPC2++;
2314 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
2315 Handle(Geom2d_Curve) C1, C2;
2316 Standard_Boolean YaSol = Standard_False;
2317 Standard_Integer itry = 0;
2319 while (!YaSol && itry < 2) {
2320 for ( Standard_Integer i = 1; i <= NbPC1 ; i++) {
2321 TopoDS_Shape aLocalEdge = E1.Reversed();
2322 if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
2323 else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdge),
2325 // if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
2326 // else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E1.Reversed()),
2327 // F,fl1[0],fl1[1]);
2328 for ( Standard_Integer j = 1; j <= NbPC2; j++ ) {
2329 TopoDS_Shape aLocalEdge = E2.Reversed();
2330 if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2331 else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdge),
2333 // if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2334 // else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E2.Reversed()),
2335 // F,fl2[0],fl2[1]);
2337 if (C1.IsNull() || C2.IsNull()) {
2338 cout <<"Inter2d : Pas de pcurve"<<endl;
2340 DBRep::Set("E1",E1);
2341 DBRep::Set("E2",E2);
2348 Standard_Real U1 = 0.,U2 = 0.;
2350 Standard_Real U1,U2;
2354 fl1[0] = C1->FirstParameter(); fl1[1] = C1->LastParameter();
2355 fl2[0] = C2->FirstParameter(); fl2[1] = C2->LastParameter();
2357 Geom2dAdaptor_Curve AC1(C1,fl1[0],fl1[1]);
2358 Geom2dAdaptor_Curve AC2(C2,fl2[0],fl2[1]);
2361 gp_Pnt2d P1[2],P2[2];
2362 P1[0] = C1->Value(fl1[0]); P1[1] = C1->Value(fl1[1]);
2363 P2[0] = C2->Value(fl2[0]); P2[1] = C2->Value(fl2[1]);
2365 Standard_Integer i1 ;
2366 for ( i1 = 0; i1 < 2; i1++) {
2367 for (Standard_Integer i2 = 0; i2 < 2; i2++) {
2368 if (Abs(fl1[i1]) < Precision::Infinite() &&
2369 Abs(fl2[i2]) < Precision::Infinite() ) {
2370 if (P1[i1].IsEqual(P2[i2],TolConf)) {
2371 YaSol = Standard_True;
2372 U1 = fl1[i1]; U2 = fl2[i2];
2373 P2d = C1->Value(U1);
2379 for (i1 = 0; i1 < 2; i1++)
2381 Extrema_ExtPC2d extr( P1[i1], AC2 );
2382 if (extr.IsDone() && extr.NbExt() > 0)
2384 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2385 Standard_Integer IndexMin = 1;
2386 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2388 Dist2 = extr.SquareDistance(ind);
2389 if (Dist2 < Dist2Min)
2395 if (Dist2Min <= Precision::Confusion() * Precision::Confusion())
2397 YaSol = Standard_True;
2400 U2 = (extr.Point(IndexMin)).Parameter();
2406 for (Standard_Integer i2 = 0; i2 < 2; i2++)
2408 Extrema_ExtPC2d extr( P2[i2], AC1 );
2409 if (extr.IsDone() && extr.NbExt() > 0)
2411 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2412 Standard_Integer IndexMin = 1;
2413 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2415 Dist2 = extr.SquareDistance(ind);
2416 if (Dist2 < Dist2Min)
2422 if (Dist2Min <= Precision::Confusion() * Precision::Confusion())
2424 YaSol = Standard_True;
2427 U1 = (extr.Point(IndexMin)).Parameter();
2435 Geom2dInt_GInter Inter (AC1,AC2,TolConf,TolConf);
2437 if (!Inter.IsEmpty() && Inter.NbPoints() > 0) {
2438 YaSol = Standard_True;
2439 U1 = Inter.Point(1).ParamOnFirst();
2440 U2 = Inter.Point(1).ParamOnSecond();
2441 P2d = Inter.Point(1).Value();
2443 else if (!Inter.IsEmpty() && Inter.NbSegments() > 0) {
2444 YaSol = Standard_True;
2445 IntRes2d_IntersectionSegment Seg = Inter.Segment(1);
2446 IntRes2d_IntersectionPoint IntP1 = Seg.FirstPoint();
2447 IntRes2d_IntersectionPoint IntP2 = Seg.LastPoint();
2448 Standard_Real U1on1 = IntP1.ParamOnFirst();
2449 Standard_Real U1on2 = IntP2.ParamOnFirst();
2450 Standard_Real U2on1 = IntP1.ParamOnSecond();
2451 Standard_Real U2on2 = IntP2.ParamOnSecond();
2453 cout << " BRepOffset_Tool::Inter2d SEGMENT d intersection" << endl;
2454 cout << " ===> Parametres sur Curve1 : ";
2455 cout << U1on1 << " " << U1on2 << endl;
2456 cout << " ===> Parametres sur Curve2 : ";
2457 cout << U2on1 << " " << U2on2 << endl;
2459 U1 = (U1on1 + U1on2)/2.;
2460 U2 = (U2on1 + U2on2)/2.;
2461 gp_Pnt2d P2d1 = C1->Value(U1);
2462 gp_Pnt2d P2d2 = C2->Value(U2);
2463 P2d.SetX( (P2d1.X() + P2d2.X()) / 2.);
2464 P2d.SetY( (P2d1.Y() + P2d2.Y()) / 2.);
2468 gp_Pnt P = S->Value(P2d.X(),P2d.Y());
2469 TopoDS_Vertex V = BRepLib_MakeVertex(P);
2470 V.Orientation(TopAbs_INTERNAL);
2471 TopoDS_Shape aLocalEdge = E1.Oriented(TopAbs_FORWARD);
2472 B.UpdateVertex(V,U1,TopoDS::Edge(aLocalEdge),TolConf);
2473 aLocalEdge = E2.Oriented(TopAbs_FORWARD);
2474 B.UpdateVertex(V,U2,TopoDS::Edge(aLocalEdge),TolConf);
2475 // B.UpdateVertex(V,U1,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)),TolConf);
2476 // B.UpdateVertex(V,U2,TopoDS::Edge(E2.Oriented(TopAbs_FORWARD)),TolConf);
2484 if (LV.Extent() > 1) {
2485 //------------------------------------------------
2486 // garde seulement les vertex les plus proches du
2487 //debut et de la fin.
2488 //------------------------------------------------
2489 TopTools_ListIteratorOfListOfShape it(LV);
2490 TopoDS_Vertex VF,VL;
2491 Standard_Real UMin = Precision::Infinite();
2492 Standard_Real UMax = -Precision::Infinite();
2495 for ( ; it.More(); it.Next()) {
2496 TopoDS_Vertex CV = TopoDS::Vertex(it.Value());
2497 TopoDS_Shape aLocalEdge = E1.Oriented(TopAbs_FORWARD);
2498 U = BRep_Tool::Parameter(CV,TopoDS::Edge(aLocalEdge));
2499 // U = BRep_Tool::Parameter(CV,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)));
2507 LV.Clear();LV.Append(VF); LV.Append(VL);
2512 cout <<"Inter2d : Pas de solution"<<endl;
2514 DBRep::Set("E1",E1);
2515 DBRep::Set("E2",E2);
2522 //=======================================================================
2523 //function : SelectEdge
2525 //=======================================================================
2527 static void SelectEdge (const TopoDS_Face& F,
2528 const TopoDS_Face& EF,
2529 const TopoDS_Edge& E,
2530 TopTools_ListOfShape& LInt)
2532 //------------------------------------------------------------
2533 // detrompeur sur les intersections sur les faces periodiques
2534 //------------------------------------------------------------
2535 TopTools_ListIteratorOfListOfShape it(LInt);
2536 Standard_Real dU = 1.0e100;
2539 Standard_Real Fst, Lst, tmp;
2540 BRep_Tool::Range(E, Fst, Lst);
2541 BRepAdaptor_Curve Ad1(E);
2543 gp_Pnt PFirst = Ad1.Value( Fst );
2544 gp_Pnt PLast = Ad1.Value( Lst );
2546 //----------------------------------------------------------------------
2547 // Selection de l edge qui couvre le plus le domaine de l edge initiale.
2548 //----------------------------------------------------------------------
2549 for (; it.More(); it.Next()) {
2550 const TopoDS_Edge& EI = TopoDS::Edge(it.Value());
2552 BRep_Tool::Range(EI, Fst, Lst);
2553 BRepAdaptor_Curve Ad2(EI);
2554 gp_Pnt P1 = Ad2.Value(Fst);
2555 gp_Pnt P2 = Ad2.Value(Lst);
2557 tmp = P1.Distance(PFirst) + P2.Distance(PLast);
2569 //=======================================================================
2572 //=======================================================================
2574 static void MakeFace(const Handle(Geom_Surface)& S,
2575 const Standard_Real Um,
2576 const Standard_Real UM,
2577 const Standard_Real Vm,
2578 const Standard_Real VM,
2579 const Standard_Boolean isVminDegen,
2580 const Standard_Boolean isVmaxDegen,
2583 Standard_Real UMin = Um;
2584 Standard_Real UMax = UM;
2585 Standard_Real VMin = Vm;
2586 Standard_Real VMax = VM;
2587 Standard_Real epsilon = Precision::Confusion();
2589 Standard_Real umin,umax,vmin,vmax;
2590 S->Bounds(umin,umax,vmin,vmax);
2593 // compute infinite flags
2594 Standard_Boolean umininf = Precision::IsNegativeInfinite(UMin);
2595 Standard_Boolean umaxinf = Precision::IsPositiveInfinite(UMax);
2596 Standard_Boolean vmininf = Precision::IsNegativeInfinite(VMin);
2597 Standard_Boolean vmaxinf = Precision::IsPositiveInfinite(VMax);
2600 Standard_Boolean IsSuclosed = S->IsUClosed(), IsSvclosed = S->IsVClosed();
2601 if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2603 Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&S))->BasisSurface();
2604 IsSuclosed = BasisSurf->IsUClosed();
2605 IsSvclosed = BasisSurf->IsVClosed();
2608 Standard_Boolean uclosed =
2610 Abs(UMin - umin) < epsilon &&
2611 Abs(UMax - umax) < epsilon;
2613 Standard_Boolean vclosed =
2615 Abs(VMin - vmin) < epsilon &&
2616 Abs(VMax - vmax) < epsilon;
2618 // degenerated flags (for cones)
2619 Standard_Boolean vmindegen = isVminDegen, vmaxdegen = isVmaxDegen;
2620 Handle(Geom_Surface) theSurf = S;
2621 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
2622 theSurf = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface();
2623 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
2625 Handle(Geom_ConicalSurface) ConicalS = *((Handle(Geom_ConicalSurface)*) &theSurf);
2626 gp_Cone theCone = ConicalS->Cone();
2627 gp_Pnt theApex = theCone.Apex();
2628 Standard_Real Uapex, Vapex;
2629 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
2630 if (Abs(VMin - Vapex) <= Precision::Confusion())
2631 vmindegen = Standard_True;
2632 if (Abs(VMax - Vapex) <= Precision::Confusion())
2633 vmaxdegen = Standard_True;
2638 Standard_Real tol = Precision::Confusion();
2640 TopoDS_Vertex V00,V10,V11,V01;
2643 if (!vmininf) B.MakeVertex(V00,S->Value(UMin,VMin),tol);
2644 if (!vmaxinf) B.MakeVertex(V01,S->Value(UMin,VMax),tol);
2647 if (!vmininf) B.MakeVertex(V10,S->Value(UMax,VMin),tol);
2648 if (!vmaxinf) B.MakeVertex(V11,S->Value(UMax,VMax),tol);
2667 Handle(Geom2d_Line) Lumin,Lumax,Lvmin,Lvmax;
2669 Lumin = new Geom2d_Line(gp_Pnt2d(UMin,0),gp_Dir2d(0,1));
2671 Lumax = new Geom2d_Line(gp_Pnt2d(UMax,0),gp_Dir2d(0,1));
2673 Lvmin = new Geom2d_Line(gp_Pnt2d(0,VMin),gp_Dir2d(1,0));
2675 Lvmax = new Geom2d_Line(gp_Pnt2d(0,VMax),gp_Dir2d(1,0));
2677 Handle(Geom_Curve) Cumin,Cumax,Cvmin,Cvmax;
2678 Standard_Real TolApex = 1.e-5;
2679 //Standard_Boolean hasiso = ! S->IsKind(STANDARD_TYPE(Geom_OffsetSurface));
2680 Standard_Boolean hasiso = S->IsKind(STANDARD_TYPE(Geom_ElementarySurface));
2683 Cumin = S->UIso(UMin);
2685 Cumax = S->UIso(UMax);
2688 Cvmin = S->VIso(VMin);
2689 if (BRepOffset_Tool::Gabarit( Cvmin ) <= TolApex)
2690 vmindegen = Standard_True;
2694 Cvmax = S->VIso(VMax);
2695 if (BRepOffset_Tool::Gabarit( Cvmax ) <= TolApex)
2696 vmaxdegen = Standard_True;
2701 B.MakeFace(F,S,tol);
2704 TopoDS_Edge eumin,eumax,evmin,evmax;
2708 B.MakeEdge(eumin,Cumin,tol);
2712 B.UpdateEdge(eumin,Lumax,Lumin,F,tol);
2714 B.UpdateEdge(eumin,Lumin,F,tol);
2716 V00.Orientation(TopAbs_FORWARD);
2720 V01.Orientation(TopAbs_REVERSED);
2723 B.Range(eumin,VMin,VMax);
2731 B.MakeEdge(eumax,Cumax,tol);
2734 B.UpdateEdge(eumax,Lumax,F,tol);
2736 V10.Orientation(TopAbs_FORWARD);
2740 V11.Orientation(TopAbs_REVERSED);
2743 B.Range(eumax,VMin,VMax);
2748 if (hasiso && !vmindegen)
2749 B.MakeEdge(evmin,Cvmin,tol);
2753 B.UpdateEdge(evmin,Lvmin,Lvmax,F,tol);
2755 B.UpdateEdge(evmin,Lvmin,F,tol);
2757 V00.Orientation(TopAbs_FORWARD);
2761 V10.Orientation(TopAbs_REVERSED);
2764 B.Range(evmin,UMin,UMax);
2766 B.Degenerated(evmin, Standard_True);
2773 if (hasiso && !vmaxdegen)
2774 B.MakeEdge(evmax,Cvmax,tol);
2777 B.UpdateEdge(evmax,Lvmax,F,tol);
2779 V01.Orientation(TopAbs_FORWARD);
2783 V11.Orientation(TopAbs_REVERSED);
2786 B.Range(evmax,UMin,UMax);
2788 B.Degenerated(evmax, Standard_True);
2792 // make the wires and add them to the face
2793 eumin.Orientation(TopAbs_REVERSED);
2794 evmax.Orientation(TopAbs_REVERSED);
2798 if (!umininf && !umaxinf && vmininf && vmaxinf) {
2809 else if (umininf && umaxinf && !vmininf && !vmaxinf) {
2820 else if (!umininf || !umaxinf || !vmininf || !vmaxinf) {
2823 if (!umininf) B.Add(W,eumin);
2824 if (!vmininf) B.Add(W,evmin);
2825 if (!umaxinf) B.Add(W,eumax);
2826 if (!vmaxinf) B.Add(W,evmax);
2828 W.Closed(!umininf && !umaxinf && !vmininf && !vmaxinf);
2829 F.Closed(uclosed && vclosed);
2833 //=======================================================================
2834 //function : EnLargeGeometry
2836 //=======================================================================
2838 static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S,
2843 Standard_Boolean& IsV1degen,
2844 Standard_Boolean& IsV2degen,
2845 const Standard_Real uf1,
2846 const Standard_Real uf2,
2847 const Standard_Real vf1,
2848 const Standard_Real vf2,
2849 const Standard_Boolean GlobalEnlargeU,
2850 const Standard_Boolean GlobalEnlargeVfirst,
2851 const Standard_Boolean GlobalEnlargeVlast)
2853 const Standard_Real coeff = 4.;
2854 const Standard_Real TolApex = 1.e-5;
2856 Standard_Boolean SurfaceChange = Standard_False;
2857 if ( S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2858 Handle(Geom_Surface) BS = (*((Handle(Geom_RectangularTrimmedSurface)*)&S))->BasisSurface();
2859 EnlargeGeometry(BS,U1,U2,V1,V2,IsV1degen,IsV2degen,
2860 uf1,uf2,vf1,vf2,GlobalEnlargeU,GlobalEnlargeVfirst,GlobalEnlargeVlast);
2861 if (!GlobalEnlargeVfirst)
2863 if (!GlobalEnlargeVlast)
2865 if (!GlobalEnlargeVfirst || !GlobalEnlargeVlast)
2866 //(*((Handle(Geom_RectangularTrimmedSurface)*)&S))->SetTrim( U1, U2, V1, V2 );
2867 S = new Geom_RectangularTrimmedSurface( BS, U1, U2, V1, V2 );
2870 SurfaceChange = Standard_True;
2872 else if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)) {
2873 Handle(Geom_Surface) Surf = (*((Handle(Geom_OffsetSurface)*)&S))->BasisSurface();
2874 SurfaceChange = EnlargeGeometry(Surf,U1,U2,V1,V2,IsV1degen,IsV2degen,
2875 uf1,uf2,vf1,vf2,GlobalEnlargeU,GlobalEnlargeVfirst,GlobalEnlargeVlast);
2876 Handle(Geom_OffsetSurface)::DownCast(S)->SetBasisSurface(Surf);
2878 else if (S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
2879 S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution))
2881 Standard_Real du=0., dv=0.;
2882 Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
2883 Standard_Real u1, u2, v1, v2;
2884 Standard_Boolean enlargeU = GlobalEnlargeU, enlargeV = Standard_True;
2885 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2886 Standard_Boolean enlargeVfirst = GlobalEnlargeVfirst, enlargeVlast = GlobalEnlargeVlast;
2887 S->Bounds( u1, u2, v1, v2 );
2888 if (Precision::IsInfinite(u1) || Precision::IsInfinite(u2))
2893 enlargeU = Standard_False;
2895 else if (S->IsUClosed())
2896 enlargeU = Standard_False;
2899 viso = S->VIso( vf1 );
2900 GeomAdaptor_Curve gac( viso );
2901 du = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2902 uiso1 = S->UIso( uf1 );
2903 uiso2 = S->UIso( uf2 );
2904 if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
2905 enlargeUfirst = Standard_False;
2906 if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
2907 enlargeUlast = Standard_False;
2909 if (Precision::IsInfinite(v1) || Precision::IsInfinite(v2))
2914 enlargeV = Standard_False;
2916 else if (S->IsVClosed())
2917 enlargeV = Standard_False;
2920 uiso = S->UIso( uf1 );
2921 GeomAdaptor_Curve gac( uiso );
2922 dv = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2923 viso1 = S->VIso( vf1 );
2924 viso2 = S->VIso( vf2 );
2925 if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
2927 enlargeVfirst = Standard_False;
2928 IsV1degen = Standard_True;
2930 if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
2932 enlargeVlast = Standard_False;
2933 IsV2degen = Standard_True;
2936 S = new Geom_RectangularTrimmedSurface( S, u1, u2, v1, v2 );
2940 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), du, 1, Standard_True, Standard_False );
2942 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), du, 1, Standard_True, Standard_True );
2947 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), dv, 1, Standard_False, Standard_False );
2949 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), dv, 1, Standard_False, Standard_True );
2951 S->Bounds( U1, U2, V1, V2 );
2952 SurfaceChange = Standard_True;
2954 else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
2955 S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
2957 Standard_Boolean enlargeU = GlobalEnlargeU, enlargeV = Standard_True;
2958 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2959 Standard_Boolean enlargeVfirst = GlobalEnlargeVfirst, enlargeVlast = GlobalEnlargeVlast;
2961 enlargeU = Standard_False;
2963 enlargeV = Standard_False;
2965 Standard_Real duf = uf2-uf1, dvf = vf2-vf1;
2966 Standard_Real u1, u2, v1, v2;
2967 S->Bounds( u1, u2, v1, v2 );
2969 Standard_Real du=0., dv=0.;
2970 Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
2971 GeomAdaptor_Curve gac;
2974 viso = S->VIso( v1 );
2976 du = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2977 uiso1 = S->UIso( u1 );
2978 uiso2 = S->UIso( u2 );
2979 if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
2980 enlargeUfirst = Standard_False;
2981 if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
2982 enlargeUlast = Standard_False;
2986 uiso = S->UIso( u1 );
2988 dv = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2989 viso1 = S->VIso( v1 );
2990 viso2 = S->VIso( v2 );
2991 if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
2993 enlargeVfirst = Standard_False;
2994 IsV1degen = Standard_True;
2996 if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
2998 enlargeVlast = Standard_False;
2999 IsV2degen = Standard_True;
3005 if (enlargeUfirst && uf1-u1 < duf)
3006 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), du, 1, Standard_True, Standard_False );
3007 if (enlargeUlast && u2-uf2 < duf)
3008 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), du, 1, Standard_True, Standard_True );
3012 if (enlargeVfirst && vf1-v1 < dvf)
3013 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), dv, 1, Standard_False, Standard_False );
3014 if (enlargeVlast && v2-vf2 < dvf)
3015 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), dv, 1, Standard_False, Standard_True );
3018 S->Bounds( U1, U2, V1, V2 );
3019 SurfaceChange = Standard_True;
3021 // else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
3022 // S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface)) {
3023 // S->Bounds(U1,U2,V1,V2);
3026 Standard_Real UU1,UU2,VV1,VV2;
3027 S->Bounds(UU1,UU2,VV1,VV2);
3028 // Pas d extension au dela des bornes de la surface.
3034 return SurfaceChange;
3037 //=======================================================================
3038 //function : UpDatePCurve
3039 //purpose : Mise a jour des pcurves de F sur la surface de de BF.
3040 // F and BF has to be FORWARD,
3041 //=======================================================================
3043 static void UpdatePCurves (const TopoDS_Face& F,
3049 TopTools_IndexedMapOfShape Emap;
3050 Handle(Geom2d_Curve) NullPCurve;
3052 TopExp::MapShapes( F, TopAbs_EDGE, Emap );
3054 for (i = 1; i <= Emap.Extent(); i++)
3056 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
3057 CE.Orientation( TopAbs_FORWARD );
3058 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface( CE, F, f, l );
3061 if (BRep_Tool::IsClosed( CE, F ))
3064 Handle(Geom2d_Curve) C2R = BRep_Tool::CurveOnSurface( CE, F, f, l );
3065 B.UpdateEdge( CE, NullPCurve, NullPCurve, F, BRep_Tool::Tolerance(CE) );
3066 B.UpdateEdge( CE, C2, C2R, BF, BRep_Tool::Tolerance(CE) );
3070 B.UpdateEdge( CE, NullPCurve, F, BRep_Tool::Tolerance(CE) );
3071 B.UpdateEdge( CE, C2, BF, BRep_Tool::Tolerance(CE) );
3079 //=======================================================================
3080 //function :CompactUVBounds
3082 //=======================================================================
3084 static void CompactUVBounds (const TopoDS_Face& F,
3085 Standard_Real& UMin,
3086 Standard_Real& UMax,
3087 Standard_Real& VMin,
3088 Standard_Real& VMax)
3090 // Calcul serre pour que les bornes ne couvrent pas plus d une periode
3091 Standard_Real U1,U2;
3092 Standard_Real N = 33;
3095 TopExp_Explorer exp;
3096 for (exp.Init(F, TopAbs_EDGE); exp.More(); exp.Next()) {
3097 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3098 BRepAdaptor_Curve2d C(E,F);
3099 BRep_Tool::Range(E,U1,U2);
3101 Standard_Real U = U1;
3102 Standard_Real DU = (U2-U1)/(N-1);
3103 for (Standard_Integer j=1;j<N;j++) {
3111 B.Get(UMin,VMin,UMax,VMax);
3114 //=======================================================================
3115 //function : CheckBounds
3117 //=======================================================================
3119 void BRepOffset_Tool::CheckBounds(const TopoDS_Face& F,
3120 const BRepOffset_Analyse& Analyse,
3121 Standard_Boolean& enlargeU,
3122 Standard_Boolean& enlargeVfirst,
3123 Standard_Boolean& enlargeVlast)
3125 enlargeU = Standard_True;
3126 enlargeVfirst = Standard_True; enlargeVlast = Standard_True;
3128 Standard_Integer Ubound = 0, Vbound = 0;
3129 Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
3130 Standard_Real Vfirst = RealLast(), Vlast = RealFirst();
3132 Standard_Real UF1,UF2,VF1,VF2;
3133 CompactUVBounds(F,UF1,UF2,VF1,VF2);
3135 Handle(Geom_Surface) theSurf = BRep_Tool::Surface(F);
3136 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
3137 theSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&theSurf))->BasisSurface();
3139 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
3140 theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution) ||
3141 theSurf->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
3142 theSurf->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
3144 TopExp_Explorer Explo(F, TopAbs_EDGE);
3145 for (; Explo.More(); Explo.Next())
3147 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
3148 const BRepOffset_ListOfInterval& L = Analyse.Type(anEdge);
3149 if (!L.IsEmpty() || BRep_Tool::Degenerated(anEdge))
3151 BRepOffset_Type OT = L.First().Type();
3152 if (OT == BRepOffset_Tangent || BRep_Tool::Degenerated(anEdge))
3154 Standard_Real fpar, lpar;
3155 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, F, fpar, lpar);
3156 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
3157 aCurve = (*((Handle(Geom2d_TrimmedCurve)*)&aCurve))->BasisCurve();
3159 Handle(Geom2d_Line) theLine;
3160 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_Line))
3161 theLine = *((Handle(Geom2d_Line)*)&aCurve);
3162 else if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BezierCurve) ||
3163 aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BSplineCurve))
3165 Standard_Real newFpar, newLpar, deviation;
3166 theLine = ShapeCustom_Curve2d::ConvertToLine2d(aCurve, fpar, lpar, Precision::Confusion(),
3167 newFpar, newLpar, deviation);
3170 if (!theLine.IsNull())
3172 gp_Dir2d theDir = theLine->Direction();
3173 if (theDir.IsParallel( gp::DX2d(), Precision::Angular() ))
3176 if (BRep_Tool::Degenerated(anEdge))
3178 if (Abs(theLine->Location().Y() - VF1) <= Precision::Confusion())
3179 enlargeVfirst = Standard_False;
3180 else //theLine->Location().Y() is near VF2
3181 enlargeVlast = Standard_False;
3185 if (theLine->Location().Y() < Vfirst)
3186 Vfirst = theLine->Location().Y();
3187 if (theLine->Location().Y() > Vlast)
3188 Vlast = theLine->Location().Y();
3191 else if (theDir.IsParallel( gp::DY2d(), Precision::Angular() ))
3194 if (theLine->Location().X() < Ufirst)
3195 Ufirst = theLine->Location().X();
3196 if (theLine->Location().X() > Ulast)
3197 Ulast = theLine->Location().X();
3205 if (Ubound >= 2 || Vbound >= 2)
3208 Abs(UF1-Ufirst) <= Precision::Confusion() &&
3209 Abs(UF2-Ulast) <= Precision::Confusion())
3210 enlargeU = Standard_False;
3212 Abs(VF1-Vfirst) <= Precision::Confusion() &&
3213 Abs(VF2-Vlast) <= Precision::Confusion())
3215 enlargeVfirst = Standard_False;
3216 enlargeVlast = Standard_False;
3221 //=======================================================================
3222 //function : EnLargeFace
3224 //=======================================================================
3226 Standard_Boolean BRepOffset_Tool::EnLargeFace
3227 (const TopoDS_Face& F,
3229 const Standard_Boolean CanExtentSurface,
3230 const Standard_Boolean UpdatePCurve,
3231 const Standard_Boolean enlargeU,
3232 const Standard_Boolean enlargeVfirst,
3233 const Standard_Boolean enlargeVlast)
3235 //---------------------------
3236 // extension de la geometrie.
3237 //---------------------------
3239 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
3240 Standard_Real UU1,VV1,UU2,VV2;
3241 Standard_Boolean isVV1degen = Standard_False, isVV2degen = Standard_False;
3242 Standard_Real US1,VS1,US2,VS2;
3243 Standard_Real UF1,VF1,UF2,VF2;
3244 Standard_Real infini = 1.e8;
3245 Standard_Boolean SurfaceChange = Standard_False;
3247 if (S->IsUPeriodic() || S->IsVPeriodic()) {
3248 // Calcul serre pour que les bornes ne couvre pas plus d une periode
3249 CompactUVBounds(F,UF1,UF2,VF1,VF2);
3252 BRepTools::UVBounds(F,UF1,UF2,VF1,VF2);
3255 S->Bounds (US1,US2,VS1,VS2);
3256 UU1 = VV1 = - infini;
3259 if (CanExtentSurface) {
3260 SurfaceChange = EnlargeGeometry( S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2,
3261 enlargeU, enlargeVfirst, enlargeVlast );
3264 UU1 = Max(US1,UU1); UU2 = Min(UU2,US2);
3265 VV1 = Max(VS1,VV1); VV2 = Min(VS2,VV2);
3268 if (S->IsUPeriodic()) {
3269 Standard_Real Period = S->UPeriod();
3270 Standard_Real Delta = Period - (UF2 - UF1);
3271 Standard_Real alpha = 0.1;
3272 UU1 = UF1 - alpha*Delta; UU2 = UF2 + alpha*Delta;
3273 if ((UU2 - UU1) > Period) {
3277 if (S->IsVPeriodic()) {
3278 Standard_Real Period = S->VPeriod();
3279 Standard_Real Delta = Period - (VF2 - VF1);
3280 Standard_Real alpha = 0.1;
3281 VV1 = VF1 - alpha*Delta; VV2 = VF2 + alpha*Delta;
3282 if ((VV2 - VV1) > Period) {
3287 //Special treatment for conical surfaces
3288 Handle(Geom_Surface) theSurf = S;
3289 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
3290 theSurf = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface();
3291 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
3293 Handle(Geom_ConicalSurface) ConicalS = *((Handle(Geom_ConicalSurface)*) &theSurf);
3294 gp_Cone theCone = ConicalS->Cone();
3295 gp_Pnt theApex = theCone.Apex();
3296 Standard_Real Uapex, Vapex;
3297 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
3298 if (VV1 < Vapex && Vapex < VV2)
3300 //consider that VF1 and VF2 are on the same side from apex
3301 Standard_Real TolApex = 1.e-5;
3302 if (Vapex - VF1 >= TolApex ||
3303 Vapex - VF2 >= TolApex) //if (VF1 < Vapex || VF2 < Vapex)
3312 UU1 = UF1; UU2 = UF2;
3319 MakeFace(S,UU1,UU2,VV1,VV2,isVV1degen,isVV2degen,BF);
3322 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
3324 //----------------------------------------------------------------
3325 // utile pour les bouchons on ne doit pas changer leur geometrie.
3326 // (Ce que fait BRepLib_MakeFace si S est restreinte).
3327 // On remet S et on update les pcurves.
3328 //----------------------------------------------------------------
3329 TopExp_Explorer exp;
3330 exp.Init(BF,TopAbs_EDGE);
3331 Standard_Real f=0.,l=0.;
3332 for (; exp.More(); exp.Next()) {
3333 TopoDS_Edge CE = TopoDS::Edge(exp.Current());
3334 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,BF,f,l);
3335 B.UpdateEdge (CE,C2,S,L,BRep_Tool::Tolerance(CE));
3337 B.UpdateFace(BF,S,L,BRep_Tool::Tolerance(F));
3340 if (SurfaceChange && UpdatePCurve) {
3341 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3342 UpdatePCurves(TopoDS::Face(aLocalFace),BF);
3343 //UpdatePCurves(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),BF);
3345 BB.UpdateFace( F, S, L, BRep_Tool::Tolerance(F) );
3348 BF.Orientation(F.Orientation());
3349 return SurfaceChange;
3352 //=======================================================================
3353 //function : TryParameter
3355 //=======================================================================
3357 static Standard_Boolean TryParameter (const TopoDS_Edge& OE,
3359 const TopoDS_Edge& NE,
3360 Standard_Real TolConf)
3362 BRepAdaptor_Curve OC(OE);
3363 BRepAdaptor_Curve NC(NE);
3364 Standard_Real Of = OC.FirstParameter(); Standard_Real Ol = OC.LastParameter();
3365 Standard_Real Nf = NC.FirstParameter(); Standard_Real Nl = NC.LastParameter();
3367 Standard_Real U = 0.;
3371 gp_Pnt P = BRep_Tool::Pnt(V);
3372 Standard_Boolean OK = Standard_False;
3374 if (P.Distance(OC.Value(Of)) < TolConf) {
3375 if (Of > Nf && Of < Nl && P.Distance(NC.Value(Of)) < TolConf) {
3380 if (P.Distance(OC.Value(Ol)) < TolConf) {
3381 if (Ol > Nf && Ol < Nl && P.Distance(NC.Value(Ol)) < TolConf) {
3388 TopoDS_Shape aLocalShape = NE.Oriented(TopAbs_FORWARD);
3389 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
3390 // TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD));
3391 aLocalShape = V.Oriented(TopAbs_INTERNAL);
3392 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
3393 U,NE,BRep_Tool::Tolerance(NE));
3394 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
3395 // U,NE,BRep_Tool::Tolerance(NE));
3400 //=======================================================================
3403 //=======================================================================
3405 void BRepOffset_Tool::MapVertexEdges (const TopoDS_Shape& S,
3406 TopTools_DataMapOfShapeListOfShape& MEV)
3408 TopExp_Explorer exp;
3409 exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3410 TopTools_MapOfShape DejaVu;
3411 for ( ; exp.More(); exp.Next()) {
3412 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3413 if (DejaVu.Add(E)) {
3414 TopoDS_Vertex V1,V2;
3415 TopExp::Vertices (E,V1,V2);
3416 if (!MEV.IsBound(V1)) {
3417 TopTools_ListOfShape empty;
3421 if (!V1.IsSame(V2)) {
3422 if (!MEV.IsBound(V2)) {
3423 TopTools_ListOfShape empty;
3432 //=======================================================================
3435 //=======================================================================
3437 void BRepOffset_Tool::BuildNeighbour (const TopoDS_Wire& W,
3438 const TopoDS_Face& F,
3439 TopTools_DataMapOfShapeShape& NOnV1,
3440 TopTools_DataMapOfShapeShape& NOnV2)
3442 TopoDS_Vertex V1,V2,VP1,VP2,FV1,FV2;
3443 TopoDS_Edge CurE,FirstE,PrecE;
3444 BRepTools_WireExplorer wexp;
3446 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3447 TopoDS_Shape aLocalWire = W.Oriented(TopAbs_FORWARD);
3448 wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
3449 // wexp.Init(TopoDS::Wire(W.Oriented(TopAbs_FORWARD)),
3450 // TopoDS::Face(F.Oriented(TopAbs_FORWARD)));
3451 CurE = FirstE = PrecE = wexp.Current();
3452 TopExp::Vertices(CurE,V1,V2);
3453 FV1 = VP1 = V1; FV2 = VP2 = V2;
3455 while (wexp.More()) {
3456 CurE = wexp.Current();
3457 TopExp::Vertices(CurE,V1,V2);
3458 if (V1.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3459 if (V1.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3460 if (V2.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3461 if (V2.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3466 if (V1.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3467 if (V1.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3468 if (V2.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3469 if (V2.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3472 //=======================================================================
3473 //function : ExtentFace
3475 //=======================================================================
3477 void BRepOffset_Tool::ExtentFace (const TopoDS_Face& F,
3478 TopTools_DataMapOfShapeShape& ConstShapes,
3479 TopTools_DataMapOfShapeShape& ToBuild,
3480 const TopAbs_State Side,
3481 const Standard_Real TolConf,
3487 char* name = new char[100];
3488 sprintf(name,"FTE_%d",NbFTE++);
3493 TopExp_Explorer exp,exp2;
3494 TopTools_DataMapOfShapeShape Build;
3495 TopTools_DataMapOfShapeShape Extent;
3496 TopoDS_Edge FirstE,PrecE,CurE,NE;
3500 // Construction de la boite englobante de la face a etendre et des bouchons pour
3501 // limiter les extensions.
3502 //Bnd_Box ContextBox;
3503 //BRepBndLib::Add(F,B);
3504 //TopTools_DataMapIteratorOfDataMapOfShape itTB(ToBuild);
3505 //for (; itTB.More(); itTB.Next()) {
3506 //BRepBndLib::Add(TopBuild.Value(), ContextBox);
3510 Standard_Boolean SurfaceChange;
3511 SurfaceChange = EnLargeFace (F,EF,Standard_True);
3513 TopoDS_Shape aLocalShape = EF.EmptyCopied();
3514 NF = TopoDS::Face(aLocalShape);
3515 // NF = TopoDS::Face(EF.EmptyCopied());
3516 NF.Orientation(TopAbs_FORWARD);
3518 if (SurfaceChange) {
3519 //------------------------------------------------
3520 // Mise a jour des pcurves sur la surface de base.
3521 //------------------------------------------------
3522 TopoDS_Face Fforward = F;
3523 Fforward.Orientation(TopAbs_FORWARD);
3524 TopTools_IndexedMapOfShape Emap;
3525 TopExp::MapShapes( Fforward, TopAbs_EDGE, Emap );
3527 for (Standard_Integer i = 1; i <= Emap.Extent(); i++) {
3528 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
3529 CE.Orientation(TopAbs_FORWARD);
3530 TopoDS_Edge Ecs; //patch
3531 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,Fforward,f,l);
3533 if (ConstShapes.IsBound(CE)) {
3534 Ecs = TopoDS::Edge(ConstShapes(CE));
3535 BRep_Tool::Range(Ecs,f,l);
3537 if (BRep_Tool::IsClosed(CE,Fforward)) {
3538 TopoDS_Shape aLocalShape = CE.Reversed();
3539 Handle(Geom2d_Curve) C2R =
3540 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),Fforward,f,l);
3541 // Handle(Geom2d_Curve) C2R =
3542 // BRep_Tool::CurveOnSurface(TopoDS::Edge(CE.Reversed()),F,f,l);
3543 B.UpdateEdge (CE,C2,C2R,EF,BRep_Tool::Tolerance(CE));
3545 B.UpdateEdge (Ecs,C2,C2R,EF,BRep_Tool::Tolerance(CE));
3548 B.UpdateEdge (CE,C2,EF,BRep_Tool::Tolerance(CE));
3550 B.UpdateEdge (Ecs,C2,EF,BRep_Tool::Tolerance(CE));
3559 for (exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
3562 const TopoDS_Wire& W = TopoDS::Wire(exp.Current());
3563 TopTools_DataMapOfShapeListOfShape MVE; // Vertex -> Edges incidentes.
3564 TopTools_DataMapOfShapeShape NOnV1;
3565 TopTools_DataMapOfShapeShape NOnV2;
3567 MapVertexEdges (W,MVE);
3568 BuildNeighbour (W,F,NOnV1,NOnV2);
3570 TopTools_ListOfShape LInt1,LInt2;
3571 TopoDS_Face StopFace;
3572 //------------------------------------------------
3573 // Construction edges
3574 //------------------------------------------------
3575 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3576 exp2.More(); exp2.Next()) {
3577 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3578 if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
3579 if (ToBuild.IsBound(E)) {
3580 TopTools_ListOfShape LOE;
3582 BRepOffset_Tool::TryProject (TopoDS::Face(ToBuild(E)),
3583 EF,LOE,LInt2,LInt1,Side,TolConf);
3584 if (!LInt1.IsEmpty())
3589 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3590 exp2.More(); exp2.Next()) {
3591 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3592 if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
3593 if (ToBuild.IsBound(E)) {
3594 EnLargeFace(TopoDS::Face(ToBuild(E)),StopFace,Standard_False);
3595 BRepOffset_Tool::Inter3D (EF,StopFace,LInt1,LInt2,Side,E,Standard_True);
3596 if (LInt1.Extent() > 1) {
3597 // l intersection est en plusieurs edges (franchissement de couture)
3598 SelectEdge (F,EF,E,LInt1);
3600 NE = TopoDS::Edge(LInt1.First());
3601 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &NE.TShape());
3602 TE->Tolerance( TE->Tolerance()*10. ); //????
3603 if (NE.Orientation() == E.Orientation()) {
3604 Build.Bind(E,NE.Oriented(TopAbs_FORWARD));
3607 Build.Bind(E,NE.Oriented(TopAbs_REVERSED));
3609 const TopoDS_Edge& EOnV1 = TopoDS::Edge(NOnV1(E));
3610 if (!ToBuild .IsBound(EOnV1) &&
3611 !ConstShapes.IsBound(EOnV1) &&
3612 !Build .IsBound(EOnV1)) {
3613 ExtentEdge (F,EF,EOnV1,NE);
3614 Build.Bind (EOnV1,NE.Oriented(TopAbs_FORWARD));
3616 const TopoDS_Edge& EOnV2 = TopoDS::Edge(NOnV2(E));
3617 if (!ToBuild .IsBound(EOnV2) &&
3618 !ConstShapes.IsBound(EOnV2) &&
3619 !Build .IsBound(EOnV2)) {
3620 ExtentEdge (F,EF,EOnV2,NE);
3621 Build.Bind (EOnV2,NE.Oriented (TopAbs_FORWARD));
3626 //------------------------------------------------
3627 // Construction Vertex.
3628 //------------------------------------------------
3629 TopTools_ListOfShape LV;
3632 TopoDS_Vertex V1,V2;
3634 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3635 exp2.More(); exp2.Next()) {
3636 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3637 TopExp::Vertices (E,V1,V2);
3638 BRep_Tool::Range (E,f,l);
3640 if (Build.IsBound(E)) {
3641 const TopoDS_Edge& NEOnV1 = TopoDS::Edge(NOnV1(E));
3642 if (Build.IsBound(NEOnV1) &&
3643 (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV1))) {
3644 if (E.IsSame(NEOnV1))
3645 V = TopExp::FirstVertex(TopoDS::Edge(Build(E)));
3650 if (!Build.IsBound(V1)) {
3651 Inter2d (EF,TopoDS::Edge(Build(E)),
3652 TopoDS::Edge(Build(NEOnV1)),LV,/*TolConf*/Precision::Confusion());
3653 if (Build(E).Orientation() == TopAbs_FORWARD) {
3654 V = TopoDS::Vertex(LV.First());
3657 V = TopoDS::Vertex(LV.Last());
3661 V = TopoDS::Vertex(Build(V1));
3662 if (MVE (V1).Extent() > 2) {
3663 V.Orientation(TopAbs_FORWARD);
3664 if (Build(E).Orientation() == TopAbs_REVERSED)
3665 V.Orientation(TopAbs_REVERSED);
3666 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3676 if (ConstShapes.IsBound(V1)) V = TopoDS::Vertex(ConstShapes(V1));
3677 V.Orientation(TopAbs_FORWARD);
3678 if (Build(E).Orientation() == TopAbs_REVERSED)
3679 V.Orientation(TopAbs_REVERSED);
3680 if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
3681 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3683 ConstShapes.Bind(V1,V);
3685 const TopoDS_Edge& NEOnV2 = TopoDS::Edge(NOnV2(E));
3686 if (Build.IsBound(NEOnV2) &&
3687 (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV2))) {
3688 if (E.IsSame(NEOnV2))
3689 V = TopExp::LastVertex(TopoDS::Edge(Build(E)));
3694 if (!Build.IsBound(V2)) {
3695 Inter2d (EF,TopoDS::Edge(Build(E)),
3696 TopoDS::Edge(Build(NEOnV2)),LV,/*TolConf*/Precision::Confusion());
3697 if (Build(E).Orientation() == TopAbs_FORWARD) {
3698 V = TopoDS::Vertex(LV.Last());
3701 V = TopoDS::Vertex(LV.First());
3705 V = TopoDS::Vertex(Build(V2));
3706 if (MVE (V2).Extent() > 2) {
3707 V.Orientation(TopAbs_REVERSED);
3708 if (Build(E).Orientation() == TopAbs_REVERSED)
3709 V.Orientation(TopAbs_FORWARD);
3710 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3720 if (ConstShapes.IsBound(V2)) V = TopoDS::Vertex(ConstShapes(V2));
3721 V.Orientation(TopAbs_REVERSED);
3722 if (Build(E).Orientation() == TopAbs_REVERSED)
3723 V.Orientation(TopAbs_FORWARD);
3724 if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
3725 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3727 ConstShapes.Bind(V2,V);
3733 TopoDS_Vertex NV1,NV2;
3734 TopAbs_Orientation Or;
3735 Standard_Real U1,U2;
3736 Standard_Real eps = Precision::Confusion();
3746 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3747 exp2.More(); exp2.Next()) {
3748 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3749 TopExp::Vertices (E,V1,V2);
3750 if (Build.IsBound(E)) {
3751 NE = TopoDS::Edge(Build(E));
3752 BRep_Tool::Range(NE,f,l);
3753 Or = NE.Orientation();
3754 //-----------------------------------------------------
3755 // Copy pour virer les vertex deja sur la nouvelle edge.
3756 //-----------------------------------------------------
3757 NV1 = TopoDS::Vertex(ConstShapes(V1));
3758 NV2 = TopoDS::Vertex(ConstShapes(V2));
3760 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_INTERNAL);
3761 TopoDS_Shape aLocalEdge = NE.Oriented(TopAbs_INTERNAL);
3763 U1 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalVertex),
3764 TopoDS::Edge (aLocalEdge));
3765 aLocalVertex = NV2.Oriented(TopAbs_INTERNAL);
3766 aLocalEdge = NE.Oriented(TopAbs_FORWARD);
3767 U2 = BRep_Tool::Parameter
3768 (TopoDS::Vertex(aLocalVertex),TopoDS::Edge (aLocalEdge));
3769 // U1 = BRep_Tool::Parameter
3770 // (TopoDS::Vertex(NV1.Oriented(TopAbs_INTERNAL)),
3771 // TopoDS::Edge (NE .Oriented(TopAbs_FORWARD)));
3772 // U2 = BRep_Tool::Parameter
3773 // (TopoDS::Vertex(NV2.Oriented(TopAbs_INTERNAL)),
3774 // TopoDS::Edge (NE.Oriented(TopAbs_FORWARD)));
3775 aLocalEdge = NE.EmptyCopied();
3776 NE = TopoDS::Edge(aLocalEdge);
3777 NE.Orientation(TopAbs_FORWARD);
3778 if (NV1.IsSame(NV2))
3783 if (Or == TopAbs_FORWARD) {U1 = f; U2 = l;}
3784 else {U1 = l; U2 = f;}
3785 if (Or == TopAbs_FORWARD)
3789 if (Abs(U1-l) < eps) U1 = f;
3790 if (Abs(U2-f) < eps) U2 = l;
3792 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3793 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3794 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3795 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3796 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3797 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3799 ConstShapes.Bind(E,NE);
3800 NE.Orientation(E.Orientation());
3806 if (Abs(U2-l) < eps) U2 = f;
3807 if (Abs(U1-f) < eps) U1 = l;
3809 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3810 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3811 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3812 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3813 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3814 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3816 ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
3817 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3822 //-------------------
3823 // edge is not ferme.
3824 //-------------------
3825 if (Or == TopAbs_FORWARD) {
3827 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3828 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3829 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3830 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3831 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3832 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3837 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3838 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3839 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3840 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3841 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3842 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3845 ConstShapes.Bind(E,NE);
3846 NE.Orientation(E.Orientation());
3850 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3851 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3852 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3853 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3854 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3855 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3857 ConstShapes.Bind(E,NE);
3858 NE.Orientation(E.Orientation());
3862 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3863 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3864 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3865 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3866 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3867 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3869 ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
3870 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3875 } // Build.IsBound(E)
3876 else if (ConstShapes.IsBound(E)) { // !Build.IsBound(E)
3877 NE = TopoDS::Edge(ConstShapes(E));
3878 BuildPCurves(NE,NF);
3879 Or = NE.Orientation();
3880 if (Or == TopAbs_REVERSED) {
3881 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3884 NE.Orientation(E.Orientation());
3889 ConstShapes.Bind(E,NE.Oriented(TopAbs_FORWARD));
3893 B.Add(NF,NW.Oriented(W.Orientation()));
3895 NF.Orientation(F.Orientation());
3896 BRepTools::Update(NF); // Maj des UVPoints
3901 char* name = new char[100];
3902 sprintf(name,"FOB_%d",NbFOB++);
3903 DBRep::Set(name,NF);
3909 //=======================================================================
3910 //function : Deboucle3D
3912 //=======================================================================
3914 TopoDS_Shape BRepOffset_Tool::Deboucle3D(const TopoDS_Shape& S,
3915 const TopTools_MapOfShape& Boundary)
3917 return BRepAlgo_Tool::Deboucle3D(S,Boundary);
3920 //=======================================================================
3921 //function : IsInOut
3923 //=======================================================================
3925 static Standard_Boolean IsInOut (BRepTopAdaptor_FClass2d& FC,
3926 Geom2dAdaptor_Curve AC,
3927 const TopAbs_State& S )
3929 Standard_Real Def = 100*Precision::Confusion();
3930 GCPnts_QuasiUniformDeflection QU(AC,Def);
3932 for (Standard_Integer i = 1; i <= QU.NbPoints(); i++) {
3933 gp_Pnt2d P = AC.Value(QU.Parameter(i));
3934 if (FC.Perform(P) != S) {
3935 return Standard_False;
3939 return Standard_True;
3942 //=======================================================================
3943 //function : CorrectOrientation
3945 //=======================================================================
3947 void BRepOffset_Tool::CorrectOrientation(const TopoDS_Shape& SI,
3948 const TopTools_IndexedMapOfShape& NewEdges,
3949 Handle(BRepAlgo_AsDes)& AsDes,
3950 BRepAlgo_Image& InitOffset,
3951 const Standard_Real Offset)
3954 TopExp_Explorer exp;
3955 exp.Init(SI,TopAbs_FACE);
3956 Standard_Real f=0.,l=0.;
3958 for (; exp.More(); exp.Next()) {
3960 const TopoDS_Face& FI = TopoDS::Face(exp.Current());
3961 const TopTools_ListOfShape& LOF = InitOffset.Image(FI);
3962 TopTools_ListIteratorOfListOfShape it(LOF);
3963 for (; it.More(); it.Next()) {
3964 const TopoDS_Face& OF = TopoDS::Face(it.Value());
3965 TopTools_ListOfShape& LOE = AsDes->ChangeDescendant(OF);
3966 TopTools_ListIteratorOfListOfShape itE(LOE);
3968 Standard_Boolean YaInt = Standard_False;
3969 for (; itE.More(); itE.Next()) {
3970 const TopoDS_Edge& OE = TopoDS::Edge(itE.Value());
3971 if (NewEdges.Contains(OE)) {YaInt = Standard_True; break;}
3974 TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
3975 BRepTopAdaptor_FClass2d FC (TopoDS::Face(aLocalFace),
3976 Precision::Confusion());
3977 // BRepTopAdaptor_FClass2d FC (TopoDS::Face(FI.Oriented(TopAbs_FORWARD)),
3978 // Precision::Confusion());
3979 for (itE.Initialize(LOE); itE.More(); itE.Next()) {
3980 TopoDS_Shape& OE = itE.Value();
3981 if (NewEdges.Contains(OE)) {
3982 Handle(Geom2d_Curve) CO2d =
3983 BRep_Tool::CurveOnSurface(TopoDS::Edge(OE),OF,f,l);
3984 Geom2dAdaptor_Curve AC(CO2d,f,l);
3987 if (IsInOut(FC,AC,TopAbs_OUT)) OE.Reverse();
3990 // if (IsInOut(FC,AC,TopAbs_IN)) OE.Reverse();