1 // Created on: 1995-10-23
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Bnd_Box2d.hxx>
19 #include <BndLib_Add3dCurve.hxx>
20 #include <BOPAlgo_PaveFiller.hxx>
21 #include <BOPDS_DS.hxx>
22 #include <BOPTools_AlgoTools2D.hxx>
23 #include <BRep_CurveRepresentation.hxx>
24 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
25 #include <BRep_TEdge.hxx>
26 #include <BRep_Tool.hxx>
27 #include <BRep_Builder.hxx>
28 #include <BRepAdaptor_Curve.hxx>
29 #include <BRepAdaptor_Curve2d.hxx>
30 #include <BRepAdaptor_HCurve.hxx>
31 #include <BRepAdaptor_HSurface.hxx>
32 #include <BRepAdaptor_Surface.hxx>
33 #include <BRepAlgo_AsDes.hxx>
34 #include <BRepAlgo_Image.hxx>
35 #include <BRepAlgo_Tool.hxx>
36 #include <BRepBndLib.hxx>
37 #include <BRepLib.hxx>
38 #include <BRepLib_MakeEdge.hxx>
39 #include <BRepLib_MakeFace.hxx>
40 #include <BRepLib_MakePolygon.hxx>
41 #include <BRepLib_MakeVertex.hxx>
42 #include <BRepLib_MakeWire.hxx>
43 #include <BRepOffset_Analyse.hxx>
44 #include <BRepOffset_Interval.hxx>
45 #include <BRepOffset_ListOfInterval.hxx>
46 #include <BRepOffset_Tool.hxx>
47 #include <BRepTools.hxx>
48 #include <BRepTools_Modifier.hxx>
49 #include <BRepTools_TrsfModification.hxx>
50 #include <BRepTools_WireExplorer.hxx>
51 #include <BRepTopAdaptor_FClass2d.hxx>
54 #include <Extrema_ExtPC.hxx>
55 #include <Extrema_ExtPC2d.hxx>
56 #include <GCPnts_AbscissaPoint.hxx>
57 #include <GCPnts_QuasiUniformDeflection.hxx>
58 #include <GCPnts_UniformAbscissa.hxx>
59 #include <Geom2d_BezierCurve.hxx>
60 #include <Geom2d_BSplineCurve.hxx>
61 #include <Geom2d_Circle.hxx>
62 #include <Geom2d_Curve.hxx>
63 #include <Geom2d_Ellipse.hxx>
64 #include <Geom2d_Hyperbola.hxx>
65 #include <Geom2d_Line.hxx>
66 #include <Geom2d_Parabola.hxx>
67 #include <Geom2d_TrimmedCurve.hxx>
68 #include <Geom2dAdaptor_Curve.hxx>
69 #include <Geom2dConvert_ApproxCurve.hxx>
70 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
71 #include <Geom2dInt_GInter.hxx>
72 #include <Geom_BezierSurface.hxx>
73 #include <Geom_BSplineCurve.hxx>
74 #include <Geom_BSplineSurface.hxx>
75 #include <Geom_Conic.hxx>
76 #include <Geom_ConicalSurface.hxx>
77 #include <Geom_Curve.hxx>
78 #include <Geom_Line.hxx>
79 #include <Geom_OffsetSurface.hxx>
80 #include <Geom_Plane.hxx>
81 #include <Geom_RectangularTrimmedSurface.hxx>
82 #include <Geom_Surface.hxx>
83 #include <Geom_SurfaceOfLinearExtrusion.hxx>
84 #include <Geom_SurfaceOfRevolution.hxx>
85 #include <Geom_TrimmedCurve.hxx>
86 #include <GeomAdaptor_Surface.hxx>
87 #include <GeomAPI.hxx>
88 #include <GeomAPI_ExtremaCurveCurve.hxx>
89 #include <GeomAPI_ProjectPointOnCurve.hxx>
90 #include <GeomConvert_ApproxCurve.hxx>
91 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
92 #include <GeomInt_IntSS.hxx>
93 #include <GeomLib.hxx>
94 #include <GeomProjLib.hxx>
98 #include <IntRes2d_IntersectionPoint.hxx>
99 #include <IntRes2d_IntersectionSegment.hxx>
100 #include <IntTools_FaceFace.hxx>
101 #include <Precision.hxx>
102 #include <ProjLib_HProjectedCurve.hxx>
103 #include <ProjLib_ProjectedCurve.hxx>
104 #include <ShapeCustom_Curve2d.hxx>
105 #include <Standard_ConstructionError.hxx>
106 #include <TColgp_Array1OfPnt2d.hxx>
107 #include <TopAbs.hxx>
108 #include <TopExp.hxx>
109 #include <TopExp_Explorer.hxx>
110 #include <TopoDS.hxx>
111 #include <TopoDS_Compound.hxx>
112 #include <TopoDS_Edge.hxx>
113 #include <TopoDS_Face.hxx>
114 #include <TopoDS_Iterator.hxx>
115 #include <TopoDS_Shape.hxx>
116 #include <TopoDS_Vertex.hxx>
117 #include <TopoDS_Wire.hxx>
118 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
119 #include <TopTools_ListIteratorOfListOfShape.hxx>
120 #include <TopTools_SequenceOfShape.hxx>
124 // The constant defines the maximal value to enlarge surfaces.
125 // It is limited to 1.e+7. This limitation is justified by the
126 // floating point format. As we can have only 15
127 // valuable decimal numbers, then during intersection of surfaces with
128 // bounds of 1.e+8 the possible inaccuracy might appear already in seventh
129 // decimal place which will be more than Precision::Confusion value -
130 // 1.e-7, default tolerance value for the section curves.
131 // By decreasing the max enlarge value to 1.e+7 the inaccuracy will be
132 // shifted to eighth decimal place, i.e. the inaccuracy will be
133 // decreased to values less than 1.e-7.
134 const Standard_Real TheInfini = 1.e+7;
136 //tma: for new boolean operation
139 #include <Geom2d_Conic.hxx>
140 #include <Geom_ElementarySurface.hxx>
141 #include <Geom_BoundedCurve.hxx>
142 Standard_Boolean AffichInter = Standard_False;
143 static Standard_Integer NbNewEdges = 1;
144 static Standard_Integer NbFaces = 1;
145 static Standard_Integer NbFOB = 1;
146 static Standard_Integer NbFTE = 1;
147 static Standard_Integer NbExtE = 1;
151 static Standard_Boolean AffichExtent = Standard_False;
155 void PerformPlanes(const TopoDS_Face& theFace1,
156 const TopoDS_Face& theFace2,
157 const TopAbs_State theState,
158 TopTools_ListOfShape& theL1,
159 TopTools_ListOfShape& theL2);
162 Standard_Boolean IsInf(const Standard_Real theVal);
164 //=======================================================================
165 //function : EdgeVertices
167 //=======================================================================
169 void BRepOffset_Tool::EdgeVertices (const TopoDS_Edge& E,
173 if (E.Orientation() == TopAbs_REVERSED) {
174 TopExp::Vertices(E,V2,V1);
177 TopExp::Vertices(E,V1,V2);
181 //=======================================================================
182 //function : OriEdgeInFace
184 //=======================================================================
186 TopAbs_Orientation BRepOffset_Tool::OriEdgeInFace (const TopoDS_Edge& E,
187 const TopoDS_Face& F )
191 Exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
193 for (; Exp.More() ;Exp.Next()) {
194 if (Exp.Current().IsSame(E)) {
195 return Exp.Current().Orientation();
198 throw Standard_ConstructionError("BRepOffset_Tool::OriEdgeInFace");
202 //=======================================================================
203 //function : FindPeriod
205 //=======================================================================
207 static void FindPeriod (const TopoDS_Face& F,
216 for (exp.Init(F,TopAbs_EDGE); exp.More(); exp.Next()) {
217 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
220 const Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,pf,pl);
221 if (C.IsNull()) return;
222 Geom2dAdaptor_Curve PC(C,pf,pl);
223 Standard_Real i, nbp = 20;
224 if (PC.GetType() == GeomAbs_Line) nbp = 2;
225 Standard_Real step = (pl - pf) / nbp;
229 for (i = 2; i < nbp; i++) {
236 B.Get(umin,vmin,umax,vmax);
240 //=======================================================================
241 //function : PutInBounds
242 //purpose : Recadre la courbe 2d dans les bounds de la face
243 //=======================================================================
245 static void PutInBounds (const TopoDS_Face& F,
246 const TopoDS_Edge& E,
247 Handle(Geom2d_Curve)& C2d)
249 Standard_Real umin,umax,vmin,vmax;
251 BRep_Tool::Range(E,f,l);
253 TopLoc_Location L; // Recup S avec la location pour eviter la copie.
254 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
256 if (S->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
257 S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
262 if (!S->IsUPeriodic() && !S->IsVPeriodic()) return;
264 FindPeriod (F,umin,umax,vmin,vmax);
266 if (S->IsUPeriodic()) {
267 Standard_Real period = S->UPeriod();
268 Standard_Real eps = period*1.e-6;
269 gp_Pnt2d Pf = C2d->Value(f);
270 gp_Pnt2d Pl = C2d->Value(l);
271 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
272 Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
273 Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
274 Standard_Real du = 0.;
275 if (minC< umin - eps) {
276 du = (int((umin - minC)/period) + 1)*period;
278 if (minC > umax + eps) {
279 du = -(int((minC - umax)/period) + 1)*period;
284 minC += du; maxC += du;
286 // Ajuste au mieux la courbe dans le domaine.
287 if (maxC > umax +100*eps) {
288 Standard_Real d1 = maxC - umax;
289 Standard_Real d2 = umin - minC + period;
290 if (d2 < d1) du =-period;
300 if (S->IsVPeriodic()) {
301 Standard_Real period = S->VPeriod();
302 Standard_Real eps = period*1.e-6;
303 gp_Pnt2d Pf = C2d->Value(f);
304 gp_Pnt2d Pl = C2d->Value(l);
305 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
306 Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
307 Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
308 Standard_Real dv = 0.;
309 if (minC< vmin - eps) {
310 dv = (int((vmin - minC)/period) + 1)*period;
312 if (minC > vmax + eps) {
313 dv = -(int((minC - vmax)/period) + 1)*period;
318 minC += dv; maxC += dv;
320 // Ajuste au mieux la courbe dans le domaine.
321 if (maxC > vmax +100*eps) {
322 Standard_Real d1 = maxC - vmax;
323 Standard_Real d2 = vmin - minC + period;
324 if (d2 < d1) dv =-period;
333 //=======================================================================
336 //=======================================================================
338 Standard_Real BRepOffset_Tool::Gabarit(const Handle(Geom_Curve)& aCurve)
340 GeomAdaptor_Curve GC( aCurve );
342 BndLib_Add3dCurve::Add( GC, Precision::Confusion(), aBox );
343 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dist;
344 aBox.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
345 dist = Max( (aXmax-aXmin), (aYmax-aYmin) );
346 dist = Max( dist, (aZmax-aZmin) );
350 //=======================================================================
351 //function : BuildPCurves
353 //=======================================================================
355 static void BuildPCurves (const TopoDS_Edge& E,
356 const TopoDS_Face& F)
359 Handle (Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E,F,ff,ll);
360 if (!C2d.IsNull()) return;
362 //Standard_Real Tolerance = Max(Precision::Confusion(),BRep_Tool::Tolerance(E));
363 Standard_Real Tolerance = Precision::Confusion();
365 BRepAdaptor_Surface AS(F,0);
366 BRepAdaptor_Curve AC(E);
368 //Try to find pcurve on a bound of BSpline or Bezier surface
369 Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( F );
370 Handle( Standard_Type ) typS = theSurf->DynamicType();
371 if (typS == STANDARD_TYPE(Geom_OffsetSurface))
372 typS = Handle(Geom_OffsetSurface)::DownCast (theSurf)->BasisSurface()->DynamicType();
373 if (typS == STANDARD_TYPE(Geom_BezierSurface) || typS == STANDARD_TYPE(Geom_BSplineSurface))
375 gp_Pnt fpoint = AC.Value( AC.FirstParameter() );
376 gp_Pnt lpoint = AC.Value( AC.LastParameter() );
377 TopoDS_Face theFace = BRepLib_MakeFace( theSurf, Precision::Confusion() );
378 Standard_Real U1 = 0., U2 = 0., TolProj = 1.e-4; //1.e-5;
380 TopExp_Explorer Explo;
381 Explo.Init( theFace, TopAbs_EDGE );
382 for (; Explo.More(); Explo.Next())
384 TopoDS_Edge anEdge = TopoDS::Edge( Explo.Current() );
385 BRepAdaptor_Curve aCurve( anEdge );
386 Extrema_ExtPC fextr( fpoint, aCurve );
387 if (!fextr.IsDone() || fextr.NbExt() < 1)
389 Standard_Real dist2, dist2min = RealLast();
391 for (i = 1; i <= fextr.NbExt(); i++)
393 dist2 = fextr.SquareDistance(i);
394 if (dist2 < dist2min)
397 U1 = fextr.Point(i).Parameter();
400 if (dist2min > TolProj * TolProj)
402 Extrema_ExtPC lextr( lpoint, aCurve );
403 if (!lextr.IsDone() || lextr.NbExt() <1)
405 dist2min = RealLast();
406 for (i = 1; i <= lextr.NbExt(); i++)
408 dist2 = lextr.SquareDistance(i);
409 if (dist2 < dist2min)
412 U2 = lextr.Point(i).Parameter();
415 if (dist2min <= TolProj * TolProj)
420 } // for (; Explo.More(); Explo.Current())
422 if (! theEdge.IsNull())
424 //Construction of pcurve
427 Standard_Real temp = U1;
432 C2d = BRep_Tool::CurveOnSurface( theEdge, theFace, f, l );
433 C2d = new Geom2d_TrimmedCurve( C2d, U1, U2 );
435 if (theSurf->IsUPeriodic() || theSurf->IsVPeriodic())
436 PutInBounds( F, E, C2d );
439 B.UpdateEdge( E, C2d, F, BRep_Tool::Tolerance(E) );
440 BRepLib::SameRange( E );
446 Handle(BRepAdaptor_HSurface) HS = new BRepAdaptor_HSurface(AS);
447 Handle(BRepAdaptor_HCurve) HC = new BRepAdaptor_HCurve(AC);
449 ProjLib_ProjectedCurve Proj(HS,HC,Tolerance);
451 switch ( Proj.GetType()) {
454 C2d = new Geom2d_Line(Proj.Line());
458 C2d = new Geom2d_Circle(Proj.Circle());
461 case GeomAbs_Ellipse:
462 C2d = new Geom2d_Ellipse(Proj.Ellipse());
465 case GeomAbs_Parabola:
466 C2d = new Geom2d_Parabola(Proj.Parabola());
469 case GeomAbs_Hyperbola:
470 C2d = new Geom2d_Hyperbola(Proj.Hyperbola());
473 case GeomAbs_BezierCurve:
477 case GeomAbs_BSplineCurve:
478 C2d = Proj.BSpline();
484 if (AS.IsUPeriodic() || AS.IsVPeriodic()) {
485 PutInBounds(F,E,C2d);
489 B.UpdateEdge (E,C2d,F,BRep_Tool::Tolerance(E));
492 throw Standard_ConstructionError("BRepOffset_Tool::BuildPCurves");
496 //=======================================================================
499 //=======================================================================
501 void BRepOffset_Tool::OrientSection (const TopoDS_Edge& E,
502 const TopoDS_Face& F1,
503 const TopoDS_Face& F2,
504 TopAbs_Orientation& O1,
505 TopAbs_Orientation& O2)
511 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
512 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
513 Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l);
514 Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l);
515 Handle (Geom_Curve) C = BRep_Tool::Curve(E,L,f,l);
517 BRepAdaptor_Curve BAcurve( E );
519 GCPnts_AbscissaPoint AP(BAcurve,GCPnts_AbscissaPoint::Length(BAcurve)/2.0,f);
520 Standard_Real ParOnC;
523 ParOnC = AP.Parameter();
525 ParOnC = BOPTools_AlgoTools2D::IntermediatePoint(f, l);
527 gp_Vec T1 = C->DN(ParOnC,1).Transformed(L.Transformation());
528 if (T1.SquareMagnitude() > gp::Resolution()) {
532 gp_Pnt2d P = C1->Value(ParOnC);
536 S1->D1(P.X(),P.Y(),P3,D1U,D1V);
538 if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse();
540 P = C2->Value(ParOnC);
541 S2->D1(P.X(),P.Y(),P3,D1U,D1V);
543 if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse();
545 gp_Vec ProVec = DN2^T1;
546 Standard_Real Prod = DN1.Dot(ProVec);
551 O1 = TopAbs_REVERSED;
554 Prod = DN2.Dot(ProVec);
559 O2 = TopAbs_REVERSED;
561 if (F1.Orientation() == TopAbs_REVERSED) O1 = TopAbs::Reverse(O1);
562 if (F2.Orientation() == TopAbs_REVERSED) O2 = TopAbs::Reverse(O2);
565 //=======================================================================
566 //function : FindCommonShapes
568 //=======================================================================
569 Standard_Boolean BRepOffset_Tool::FindCommonShapes(const TopoDS_Face& theF1,
570 const TopoDS_Face& theF2,
571 TopTools_ListOfShape& theLE,
572 TopTools_ListOfShape& theLV)
574 Standard_Boolean bFoundEdges =
575 FindCommonShapes(theF1, theF2, TopAbs_EDGE, theLE);
576 Standard_Boolean bFoundVerts =
577 FindCommonShapes(theF1, theF2, TopAbs_VERTEX, theLV);
578 return bFoundEdges || bFoundVerts;
581 //=======================================================================
582 //function : FindCommonShapes
584 //=======================================================================
585 Standard_Boolean BRepOffset_Tool::FindCommonShapes(const TopoDS_Shape& theS1,
586 const TopoDS_Shape& theS2,
587 const TopAbs_ShapeEnum theType,
588 TopTools_ListOfShape& theLSC)
592 TopTools_MapOfShape aMS;
593 TopExp_Explorer aExp(theS1, theType);
594 for (; aExp.More(); aExp.Next()) {
595 aMS.Add(aExp.Current());
599 return Standard_False;
602 TopTools_MapOfShape aMFence;
603 aExp.Init(theS2, theType);
604 for (; aExp.More(); aExp.Next()) {
605 const TopoDS_Shape& aS2 = aExp.Current();
606 if (aMS.Contains(aS2)) {
607 if (aMFence.Add(aS2)) {
613 return !theLSC.IsEmpty();
616 //=======================================================================
619 //=======================================================================
621 static Standard_Boolean ToSmall (const Handle(Geom_Curve)& C)
623 Standard_Real Tol = 10*Precision::Confusion();
624 Standard_Real m = (C->FirstParameter()*0.668 + C->LastParameter()*0.332);
625 gp_Pnt P1 = C->Value(C->FirstParameter());
626 gp_Pnt P2 = C->Value(C->LastParameter());
627 gp_Pnt P3 = C->Value(m);
628 if (P1.Distance(P2) > Tol) return Standard_False;
629 if (P2.Distance(P3) > Tol) return Standard_False;
630 return Standard_True;
634 //=======================================================================
635 //function : IsOnSurface
637 //=======================================================================
639 static Standard_Boolean IsOnSurface(const Handle(Geom_Curve)& C,
640 const Handle(Geom_Surface)& S,
641 Standard_Real TolConf,
642 Standard_Real& TolReached)
644 Standard_Real f = C->FirstParameter();
645 Standard_Real l = C->LastParameter();
646 Standard_Integer n = 5;
647 Standard_Real du = (f-l)/(n-1);
653 GeomAdaptor_Surface AS(S);
655 switch ( AS.GetType()) {
658 gp_Ax3 Ax = AS.Plane().Position();
659 for ( Standard_Integer i = 0; i < n; i++) {
660 P = C->Value(f+i*du);
661 ElSLib::PlaneParameters(Ax,P,U,V);
662 TolReached = P.Distance(ElSLib::PlaneValue(U,V,Ax));
663 if ( TolReached > TolConf)
664 return Standard_False;
668 case GeomAbs_Cylinder:
670 gp_Ax3 Ax = AS.Cylinder().Position();
671 Standard_Real Rad = AS.Cylinder().Radius();
672 for ( Standard_Integer i = 0; i < n; i++) {
673 P = C->Value(f+i*du);
674 ElSLib::CylinderParameters(Ax,Rad,P,U,V);
675 TolReached = P.Distance(ElSLib::CylinderValue(U,V,Ax,Rad));
676 if ( TolReached > TolConf)
677 return Standard_False;
683 gp_Ax3 Ax = AS.Cone().Position();
684 Standard_Real Rad = AS.Cone().RefRadius();
685 Standard_Real Alp = AS.Cone().SemiAngle();
686 for ( Standard_Integer i = 0; i < n; i++) {
687 P = C->Value(f+i*du);
688 ElSLib::ConeParameters(Ax,Rad,Alp,P,U,V);
689 TolReached = P.Distance(ElSLib::ConeValue(U,V,Ax,Rad,Alp));
690 if ( TolReached > TolConf)
691 return Standard_False;
697 gp_Ax3 Ax = AS.Sphere().Position();
698 Standard_Real Rad = AS.Sphere().Radius();
699 for ( Standard_Integer i = 0; i < n; i++) {
700 P = C->Value(f+i*du);
701 ElSLib::SphereParameters(Ax,Rad,P,U,V);
702 TolReached = P.Distance(ElSLib::SphereValue(U,V,Ax,Rad));
703 if ( TolReached > TolConf)
704 return Standard_False;
710 gp_Ax3 Ax = AS.Torus().Position();
711 Standard_Real R1 = AS.Torus().MajorRadius();
712 Standard_Real R2 = AS.Torus().MinorRadius();
713 for ( Standard_Integer i = 0; i < n; i++) {
714 P = C->Value(f+i*du);
715 ElSLib::TorusParameters(Ax,R1,R2,P,U,V);
716 TolReached = P.Distance(ElSLib::TorusValue(U,V,Ax,R1,R2));
717 if ( TolReached > TolConf)
718 return Standard_False;
725 return Standard_False;
729 return Standard_True;
733 //=======================================================================
734 //function : PipeInter
736 //=======================================================================
738 void BRepOffset_Tool::PipeInter(const TopoDS_Face& F1,
739 const TopoDS_Face& F2,
740 TopTools_ListOfShape& L1,
741 TopTools_ListOfShape& L2,
742 const TopAbs_State Side)
747 sprintf(name,"FF_%d",NbFaces++);
749 sprintf(name,"FF_%d",NbFaces++);
754 Handle (Geom_Curve) CI;
755 TopAbs_Orientation O1,O2;
756 L1.Clear(); L2.Clear();
758 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
759 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
761 GeomInt_IntSS Inter (S1,S2, Precision::Confusion(),1,1,1);
763 if (Inter.IsDone()) {
764 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
766 if (ToSmall(CI)) continue;
767 TopoDS_Edge E = BRepLib_MakeEdge(CI);
768 if (Inter.HasLineOnS1(i)) {
769 Handle(Geom2d_Curve) C2 = Inter.LineOnS1(i);
770 PutInBounds (F1,E,C2);
771 B.UpdateEdge (E,C2,F1,BRep_Tool::Tolerance(E));
776 if (Inter.HasLineOnS2(i)) {
777 Handle(Geom2d_Curve) C2 = Inter.LineOnS2(i);
778 PutInBounds (F2,E,C2);
779 B.UpdateEdge (E,C2,F2,BRep_Tool::Tolerance(E));
784 OrientSection (E,F1,F2,O1,O2);
785 if (Side == TopAbs_OUT) {
786 O1 = TopAbs::Reverse(O1);
787 O2 = TopAbs::Reverse(O2);
789 L1.Append (E.Oriented(O1));
790 L2.Append (E.Oriented(O2));
794 sprintf(name,"EI_%d",NbNewEdges++);
795 DBRep::Set(name,E.Oriented(O1));
803 //=======================================================================
804 //function : IsAutonomVertex
805 //purpose : Checks wether a vertex is "autonom" or not
806 //=======================================================================
808 static Standard_Boolean IsAutonomVertex(const TopoDS_Shape& aVertex,
809 const BOPDS_PDS& pDS)
811 Standard_Integer index;
812 Standard_Integer aNbVVs, aNbEEs, aNbEFs, aInt;
814 index = pDS->Index(aVertex);
816 Standard_Integer i, i1, i2;
817 i1=pDS->NbSourceShapes();
819 for (i=i1; i<i2; ++i) {
820 const TopoDS_Shape& aSx=pDS->Shape(i);
821 if(aSx.IsSame(aVertex)) {
828 if (!pDS->IsNewShape(index)) {
829 return Standard_False;
831 //check if vertex with index "index" is not created in VV or EE or EF interference
833 BOPDS_VectorOfInterfVV& aVVs=pDS->InterfVV();
834 aNbVVs = aVVs.Length();
835 for(aInt = 0; aInt < aNbVVs; aInt++) {
836 const BOPDS_InterfVV& aVV = aVVs(aInt);
837 if (aVV.HasIndexNew()) {
838 if (aVV.IndexNew() == index) {
839 return Standard_False;
844 BOPDS_VectorOfInterfEE& aEEs=pDS->InterfEE();
845 aNbEEs = aEEs.Length();
846 for(aInt = 0; aInt < aNbEEs; aInt++) {
847 const BOPDS_InterfEE& aEE = aEEs(aInt);
848 IntTools_CommonPrt aCP = aEE.CommonPart();
849 if(aCP.Type() == TopAbs_VERTEX) {
850 if (aEE.IndexNew() == index) {
851 return Standard_False;
856 BOPDS_VectorOfInterfEF& aEFs=pDS->InterfEF();
857 aNbEFs = aEFs.Length();
858 for(aInt = 0; aInt < aNbEFs; aInt++) {
859 const BOPDS_InterfEF& aEF = aEFs(aInt);
860 IntTools_CommonPrt aCP = aEF.CommonPart();
861 if(aCP.Type() == TopAbs_VERTEX) {
862 if (aEF.IndexNew() == index) {
863 return Standard_False;
867 return Standard_True;
871 //=======================================================================
872 //function : AreConnex
873 //purpose : define if two shapes are connex by a vertex (vertices)
874 //=======================================================================
876 static Standard_Boolean AreConnex(const TopoDS_Wire& W1,
877 const TopoDS_Wire& W2,
878 const BOPDS_PDS& pDS)
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, pDS))
892 return Standard_False;
893 if (!IsAutonomVertex(V12, pDS))
894 return Standard_False;
896 if (!isCV1 && !IsAutonomVertex(V12, pDS))
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)::DownCast (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)::DownCast (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)::DownCast (C1);
926 gp_Ax1 Axis1 = L1->Position();
927 Handle(Geom_Line) L2 = Handle(Geom_Line)::DownCast (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)::DownCast (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)::DownCast (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 if(!ProjPCurve.IsNull())
1071 CurveRep->PCurve( ProjPCurve );
1077 //=======================================================================
1078 //function : ConcatPCurves
1080 //=======================================================================
1082 static Handle(Geom2d_Curve) ConcatPCurves(const TopoDS_Edge& E1,
1083 const TopoDS_Edge& E2,
1084 const TopoDS_Face& F,
1085 const Standard_Boolean After,
1086 Standard_Real& newFirst,
1087 Standard_Real& newLast)
1089 Standard_Real Tol = 1.e-7;
1090 GeomAbs_Shape Continuity = GeomAbs_C1;
1091 Standard_Integer MaxDeg = 14;
1092 Standard_Integer MaxSeg = 16;
1094 Standard_Real first1, last1, first2, last2;
1095 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1097 PCurve1 = BRep_Tool::CurveOnSurface( E1, F, first1, last1 );
1098 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
1099 PCurve1 = Handle(Geom2d_TrimmedCurve)::DownCast (PCurve1)->BasisCurve();
1101 PCurve2 = BRep_Tool::CurveOnSurface( E2, F, first2, last2 );
1102 if (PCurve2->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
1103 PCurve2 = Handle(Geom2d_TrimmedCurve)::DownCast (PCurve2)->BasisCurve();
1105 if (PCurve1 == PCurve2)
1107 newPCurve = PCurve1;
1108 newFirst = Min( first1, first2 );
1109 newLast = Max( last1, last2 );
1111 else if (PCurve1->DynamicType() == PCurve2->DynamicType() &&
1112 (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)) ||
1113 PCurve1->IsKind(STANDARD_TYPE(Geom2d_Conic))))
1115 newPCurve = PCurve1;
1117 P1 = PCurve2->Value( first2 );
1118 P2 = PCurve2->Value( last2 );
1119 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)))
1121 Handle(Geom2d_Line) Lin1 = Handle(Geom2d_Line)::DownCast (PCurve1);
1122 gp_Lin2d theLin = Lin1->Lin2d();
1123 first2 = ElCLib::Parameter( theLin, P1 );
1124 last2 = ElCLib::Parameter( theLin, P2 );
1126 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Circle)))
1128 Handle(Geom2d_Circle) Circ1 = Handle(Geom2d_Circle)::DownCast (PCurve1);
1129 gp_Circ2d theCirc = Circ1->Circ2d();
1130 first2 = ElCLib::Parameter( theCirc, P1 );
1131 last2 = ElCLib::Parameter( theCirc, P2 );
1133 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Ellipse)))
1135 Handle(Geom2d_Ellipse) Ell1 = Handle(Geom2d_Ellipse)::DownCast (PCurve1);
1136 gp_Elips2d theElips = Ell1->Elips2d();
1137 first2 = ElCLib::Parameter( theElips, P1 );
1138 last2 = ElCLib::Parameter( theElips, P2 );
1140 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Parabola)))
1142 Handle(Geom2d_Parabola) Parab1 = Handle(Geom2d_Parabola)::DownCast (PCurve1);
1143 gp_Parab2d theParab = Parab1->Parab2d();
1144 first2 = ElCLib::Parameter( theParab, P1 );
1145 last2 = ElCLib::Parameter( theParab, P2 );
1147 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Hyperbola)))
1149 Handle(Geom2d_Hyperbola) Hypr1 = Handle(Geom2d_Hyperbola)::DownCast (PCurve1);
1150 gp_Hypr2d theHypr = Hypr1->Hypr2d();
1151 first2 = ElCLib::Parameter( theHypr, P1 );
1152 last2 = ElCLib::Parameter( theHypr, P2 );
1154 newFirst = Min( first1, first2 );
1155 newLast = Max( last1, last2 );
1159 Handle(Geom2d_TrimmedCurve) TC1 = new Geom2d_TrimmedCurve( PCurve1, first1, last1 );
1160 Handle(Geom2d_TrimmedCurve) TC2 = new Geom2d_TrimmedCurve( PCurve2, first2, last2 );
1161 Geom2dConvert_CompCurveToBSplineCurve Concat2d( TC1 );
1162 Concat2d.Add( TC2, Precision::Confusion(), After );
1163 newPCurve = Concat2d.BSplineCurve();
1164 if (newPCurve->Continuity() < GeomAbs_C1)
1166 Geom2dConvert_ApproxCurve Approx2d( newPCurve, Tol, Continuity, MaxSeg, MaxDeg );
1167 if (Approx2d.HasResult())
1168 newPCurve = Approx2d.Curve();
1170 newFirst = newPCurve->FirstParameter();
1171 newLast = newPCurve->LastParameter();
1177 //=======================================================================
1179 //purpose : glue two edges.
1180 //=======================================================================
1182 static TopoDS_Edge Glue(const TopoDS_Edge& E1,
1183 const TopoDS_Edge& E2,
1184 const TopoDS_Vertex& Vfirst,
1185 const TopoDS_Vertex& Vlast,
1186 const Standard_Boolean After,
1187 const TopoDS_Face& F1,
1188 const Standard_Boolean addPCurve1,
1189 const TopoDS_Face& F2,
1190 const Standard_Boolean addPCurve2,
1191 const Standard_Real theGlueTol)
1193 Standard_Real Tol = 1.e-7;
1194 GeomAbs_Shape Continuity = GeomAbs_C1;
1195 Standard_Integer MaxDeg = 14;
1196 Standard_Integer MaxSeg = 16;
1198 Handle(Geom_Curve) C1, C2, newCurve;
1199 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1200 Standard_Real first1, last1, first2, last2, fparam=0., lparam=0.;
1201 Standard_Boolean IsCanonic = Standard_False;
1203 C1 = BRep_Tool::Curve( E1, first1, last1 );
1204 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
1205 C1 = Handle(Geom_TrimmedCurve)::DownCast (C1)->BasisCurve();
1207 C2 = BRep_Tool::Curve( E2, first2, last2 );
1208 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
1209 C2 = Handle(Geom_TrimmedCurve)::DownCast (C2)->BasisCurve();
1214 fparam = Min( first1, first2 );
1215 lparam = Max( last1, last2 );
1217 else if (C1->DynamicType() == C2->DynamicType() &&
1218 (C1->IsInstance(STANDARD_TYPE(Geom_Line)) ||
1219 C1->IsKind(STANDARD_TYPE(Geom_Conic))))
1221 IsCanonic = Standard_True;
1226 Handle(Geom_TrimmedCurve) TC1 = new Geom_TrimmedCurve( C1, first1, last1 );
1227 Handle(Geom_TrimmedCurve) TC2 = new Geom_TrimmedCurve( C2, first2, last2 );
1228 GeomConvert_CompCurveToBSplineCurve Concat( TC1 );
1229 Concat.Add( TC2, theGlueTol, After );
1230 newCurve = Concat.BSplineCurve();
1231 if (newCurve->Continuity() < GeomAbs_C1)
1233 GeomConvert_ApproxCurve Approx3d( newCurve, Tol, Continuity, MaxSeg, MaxDeg );
1234 if (Approx3d.HasResult())
1235 newCurve = Approx3d.Curve();
1237 fparam = newCurve->FirstParameter();
1238 lparam = newCurve->LastParameter();
1241 TopoDS_Edge newEdge;
1245 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast );
1247 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast, fparam, lparam );
1249 Standard_Real newFirst, newLast;
1252 newPCurve = ConcatPCurves( E1, E2, F1, After, newFirst, newLast );
1253 BB.UpdateEdge( newEdge, newPCurve, F1, 0. );
1254 BB.Range( newEdge, F1, newFirst, newLast );
1258 newPCurve = ConcatPCurves( E1, E2, F2, After, newFirst, newLast );
1259 BB.UpdateEdge( newEdge, newPCurve, F2, 0. );
1260 BB.Range( newEdge, F2, newFirst, newLast );
1267 //=======================================================================
1268 //function : FindNewVerticesOnBoundsOfFace
1270 //=======================================================================
1272 static void FindNewVerticesOnBoundsOfFace(const BOPDS_PDS& pDS,
1273 const TopoDS_Face& aFace,
1274 TopTools_DataMapOfShapeShape& VEmap)
1276 TopTools_IndexedMapOfShape OldVertices;
1277 TopExp::MapShapes( aFace, TopAbs_VERTEX, OldVertices );
1278 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
1279 TopoDS_Vertex V1, V2;
1281 TopExp_Explorer Explo( aFace, TopAbs_EDGE );
1282 for (; Explo.More(); Explo.Next()) {
1283 const TopoDS_Shape& aE = Explo.Current();
1284 Standard_Integer nE = pDS->Index(aE);
1286 const BOPDS_ListOfPaveBlock& aLPB = pDS->PaveBlocks(nE);
1287 aItLPB.Initialize(aLPB);
1288 for (; aItLPB.More(); aItLPB.Next()) {
1289 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
1290 const TopoDS_Edge& aESp = *(TopoDS_Edge*)&pDS->Shape(aPB->Edge());
1292 TopExp::Vertices( aESp, V1, V2 );
1293 if (!OldVertices.Contains( V1 )) {
1294 VEmap.Bind( V1, aE );
1297 if (!OldVertices.Contains( V2 )) {
1298 VEmap.Bind( V2, aE );
1304 //=======================================================================
1305 //function : CheckIntersFF
1307 //=======================================================================
1309 static Standard_Boolean CheckIntersFF(const BOPDS_PDS& pDS,
1310 const TopoDS_Edge& RefEdge,
1311 const TopoDS_Face& F1,
1312 const TopoDS_Face& F2,
1313 TopTools_IndexedMapOfShape& TrueEdges)
1315 Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
1316 Standard_Boolean isPlane1 = Standard_False, isPlane2 = Standard_False;
1318 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F1);
1319 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1320 aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
1321 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1322 isPlane1 = Standard_True;
1323 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1324 isEl1 = Standard_True;
1326 aSurf = BRep_Tool::Surface(F2);
1327 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1328 aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
1329 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1330 isPlane2 = Standard_True;
1331 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1332 isEl2 = Standard_True;
1334 if (isPlane1 || isPlane2)
1335 return Standard_True;
1338 return Standard_True;
1340 BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF();
1341 Standard_Integer aNb = aFFs.Length();
1342 Standard_Integer i, j, nbe = 0;
1344 TopTools_SequenceOfShape Edges;
1346 for (i = 0; i < aNb; ++i)
1348 BOPDS_InterfFF& aFFi=aFFs(i);
1349 const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
1350 Standard_Integer aNbCurves = aBCurves.Length();
1352 for (j = 0; j < aNbCurves; ++j)
1354 const BOPDS_Curve& aBC=aBCurves(j);
1355 const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
1357 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1358 aPBIt.Initialize(aSectEdges);
1360 for (; aPBIt.More(); aPBIt.Next())
1362 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
1363 Standard_Integer nSect = aPB->Edge();
1364 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
1365 Edges.Append( anEdge );
1372 return Standard_True;
1374 //define tangents of RefEdge on start and on end
1375 BRepAdaptor_Curve cref(RefEdge);
1376 gp_Vec RefTangFirst = cref.DN(cref.FirstParameter(), 1);
1377 gp_Vec RefTangLast = cref.DN(cref.LastParameter(), 1);
1379 //find the start edge and take it from Edges
1380 TopoDS_Edge StartEdge; //, StartEonF1, StartEonF2, EndEonF1, EndEonF2;
1382 TopTools_DataMapOfShapeShape VEmapF1, VEmapF2;
1383 FindNewVerticesOnBoundsOfFace( pDS, F1, VEmapF1 );
1384 FindNewVerticesOnBoundsOfFace( pDS, F2, VEmapF2 );
1386 Standard_Real AngTol = 0.1;
1387 Standard_Boolean V1onBound = Standard_False;
1388 Standard_Boolean V2onBound = Standard_False;
1389 TopoDS_Vertex V1, V2, Vcur;
1390 gp_Vec TangFirst, TangLast, TangCur;
1391 for (i = 1; i <= Edges.Length(); i++)
1393 StartEdge = TopoDS::Edge(Edges(i));
1394 TopExp::Vertices( StartEdge, V1, V2 );
1395 V1onBound = VEmapF1.IsBound(V1) || VEmapF2.IsBound(V1); // && ?
1396 V2onBound = VEmapF1.IsBound(V2) || VEmapF2.IsBound(V2); // && ?
1397 if (V1onBound || V2onBound)
1399 BRepAdaptor_Curve CE(StartEdge);
1400 TangFirst = CE.DN( CE.FirstParameter(), 1 );
1401 TangLast = CE.DN( CE.LastParameter(), 1 );
1404 if (TangFirst.IsParallel( RefTangFirst, AngTol ) ||
1405 TangFirst.IsParallel( RefTangLast, AngTol ))
1406 break; //start edged found
1410 if (TangLast.IsParallel( RefTangLast, AngTol ) ||
1411 TangLast.IsParallel( RefTangFirst, AngTol ))
1412 break; //start edged found
1417 if (i > Edges.Length()) //start edged not found
1418 return Standard_False;
1420 if (V1onBound && V2onBound)
1422 if ((TangFirst.IsParallel(RefTangFirst,AngTol) && TangLast.IsParallel(RefTangLast,AngTol)) ||
1423 (TangFirst.IsParallel(RefTangLast,AngTol) && TangLast.IsParallel(RefTangFirst,AngTol)))
1425 TrueEdges.Add( Edges(i) );
1426 return Standard_True;
1429 return Standard_False;
1432 //StartEonF1 = (V1onBound)? VEmapF1( V1 ) : VEmapF1( V2 );
1433 //StartEonF2 = (V1onBound)? VEmapF2( V1 ) : VEmapF2( V2 );
1435 TrueEdges.Add( Edges(i) );
1437 Vcur = (V1onBound)? V2 : V1;
1438 TangCur = (V1onBound)? TangLast : TangFirst;
1442 //build the chain from StartEdge till the opposite bound of face
1445 TColStd_SequenceOfInteger Candidates;
1446 for (i = 1; i <= Edges.Length(); i++)
1448 TopoDS_Edge anEdge = TopoDS::Edge(Edges(i));
1449 TopExp::Vertices( anEdge, V1, V2 );
1450 if (V1.IsSame(Vcur) || V2.IsSame(Vcur))
1451 Candidates.Append(i);
1453 if (Candidates.IsEmpty())
1456 return Standard_False;
1459 Standard_Integer minind = 1;
1460 if (Candidates.Length() > 1)
1462 Standard_Real MinAngle = RealLast();
1463 for (i = 1; i <= Candidates.Length(); i++)
1465 TopoDS_Edge anEdge = TopoDS::Edge(Edges(Candidates(i)));
1466 TopExp::Vertices( anEdge, V1, V2 );
1467 Standard_Boolean ConnectByFirst = (Vcur.IsSame(V1))? Standard_True : Standard_False;
1468 BRepAdaptor_Curve CE(anEdge);
1469 gp_Vec aTang = (ConnectByFirst)?
1470 CE.DN( CE.FirstParameter(), 1 ) : CE.DN( CE.LastParameter(), 1 );
1471 if (!ConnectByFirst)
1473 Standard_Real anAngle = TangCur.Angle(aTang);
1474 if (anAngle < MinAngle)
1481 TopoDS_Edge CurEdge = TopoDS::Edge(Edges(Candidates(minind)));
1482 TrueEdges.Add( CurEdge );
1483 Edges.Remove(Candidates(minind));
1484 TopExp::Vertices( CurEdge, V1, V2 );
1485 Standard_Boolean ConnectByFirst = (Vcur.IsSame(V1))? Standard_True : Standard_False;
1486 Vcur = (ConnectByFirst)? V2 : V1;
1487 BRepAdaptor_Curve CE(CurEdge);
1488 TangCur = (ConnectByFirst)? CE.DN( CE.LastParameter(), 1 ) : CE.DN( CE.FirstParameter(), 1 );
1489 if (!ConnectByFirst)
1491 //check if Vcur is on bounds of faces
1492 if (VEmapF1.IsBound(Vcur) || VEmapF2.IsBound(Vcur))
1496 if (TangCur.IsParallel( RefTangFirst, AngTol ) ||
1497 TangCur.IsParallel( RefTangLast, AngTol ))
1498 return Standard_True;
1501 return Standard_False;
1504 //=======================================================================
1505 //function : AssembleEdge
1507 //=======================================================================
1509 static TopoDS_Edge AssembleEdge(const BOPDS_PDS& pDS,
1510 const TopoDS_Face& F1,
1511 const TopoDS_Face& F2,
1512 const Standard_Boolean addPCurve1,
1513 const Standard_Boolean addPCurve2,
1514 const TopTools_SequenceOfShape& EdgesForConcat)
1516 TopoDS_Edge CurEdge = TopoDS::Edge( EdgesForConcat(1) );
1517 Standard_Real aGlueTol = Precision::Confusion();
1518 for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
1520 TopoDS_Edge anEdge = TopoDS::Edge( EdgesForConcat(j) );
1521 Standard_Boolean After = Standard_False;
1522 TopoDS_Vertex Vfirst, Vlast;
1523 if (AreClosed( CurEdge, anEdge ))
1525 TopoDS_Vertex V1, V2;
1526 TopExp::Vertices( CurEdge, V1, V2 );
1527 if (IsAutonomVertex( V1, pDS ))
1529 After = Standard_False;
1530 Vfirst = Vlast = V2;
1534 After = Standard_True;
1535 Vfirst = Vlast = V1;
1540 TopoDS_Vertex CV, V11, V12, V21, V22;
1541 TopExp::CommonVertex( CurEdge, anEdge, CV );
1542 aGlueTol = BRep_Tool::Tolerance(CV);
1543 TopExp::Vertices( CurEdge, V11, V12 );
1544 TopExp::Vertices( anEdge, V21, V22 );
1545 if (V11.IsSame(CV) && V21.IsSame(CV))
1550 else if (V11.IsSame(CV) && V22.IsSame(CV))
1555 else if (V12.IsSame(CV) && V21.IsSame(CV))
1565 } //end of else (open wire)
1567 TopoDS_Edge NewEdge = Glue(CurEdge, anEdge, Vfirst, Vlast, After,
1568 F1, addPCurve1, F2, addPCurve2, aGlueTol);
1570 } //end of for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
1575 //=======================================================================
1576 //function : Inter3D
1578 //=======================================================================
1580 void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1,
1581 const TopoDS_Face& F2,
1582 TopTools_ListOfShape& L1,
1583 TopTools_ListOfShape& L2,
1584 const TopAbs_State Side,
1585 const TopoDS_Edge& RefEdge,
1586 const Standard_Boolean IsRefEdgeDefined)
1591 sprintf(name,"FF_%d",NbFaces++);
1592 DBRep::Set(name,F1);
1593 sprintf(name,"FF_%d",NbFaces++);
1594 DBRep::Set(name,F2);
1598 // Check if the faces are planar and not trimmed - in this case
1599 // the IntTools_FaceFace intersection algorithm will be used directly.
1600 BRepAdaptor_Surface aBAS1(F1, Standard_False), aBAS2(F2, Standard_False);
1601 if (aBAS1.GetType() == GeomAbs_Plane &&
1602 aBAS2.GetType() == GeomAbs_Plane) {
1603 aBAS1.Initialize(F1, Standard_True);
1604 if (IsInf(aBAS1.LastUParameter()) && IsInf(aBAS1.LastVParameter())) {
1605 aBAS2.Initialize(F2, Standard_True);
1606 if (IsInf(aBAS2.LastUParameter()) && IsInf(aBAS2.LastVParameter())) {
1607 // Intersect the planes without pave filler
1608 PerformPlanes(F1, F2, Side, L1, L2);
1614 TopoDS_Face cpF1=F1;
1615 TopoDS_Face cpF2=F2;
1616 // create 3D curves on faces
1617 BRepLib::BuildCurves3d(cpF1);
1618 BRepLib::BuildCurves3d(cpF2);
1620 BOPAlgo_PaveFiller aPF1, aPF2;
1621 TopTools_ListOfShape aLS;
1624 aPF1.SetArguments(aLS);
1628 BOPAlgo_PaveFiller *pPF = &aPF1;
1631 TopTools_IndexedMapOfShape TrueEdges;
1632 if (IsRefEdgeDefined && !CheckIntersFF( pPF->PDS(), RefEdge, cpF1, cpF2, TrueEdges ))
1638 aPF2.SetArguments(aLS);
1641 CheckIntersFF( pPF->PDS(), RefEdge, cpF1, cpF2, TrueEdges );
1644 Standard_Boolean addPCurve1 = 1;
1645 Standard_Boolean addPCurve2 = 1;
1647 const BOPDS_PDS& pDS = pPF->PDS();
1648 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
1649 Standard_Integer aNb = aFFs.Length();
1650 Standard_Integer i = 0, j = 0, k;
1652 L1.Clear(); L2.Clear();
1653 TopAbs_Orientation O1,O2;
1655 const Handle(IntTools_Context)& aContext = pPF->Context();
1657 for (i = 0; i < aNb; i++) {
1658 BOPDS_InterfFF& aFFi=aFFs(i);
1659 const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
1661 Standard_Integer aNbCurves = aBCurves.Length();
1663 for (j = 0; j < aNbCurves; j++) {
1664 const BOPDS_Curve& aBC=aBCurves(j);
1665 const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
1667 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1668 aPBIt.Initialize(aSectEdges);
1670 for (; aPBIt.More(); aPBIt.Next()) {
1671 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
1672 Standard_Integer nSect = aPB->Edge();
1673 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
1674 if (!TrueEdges.IsEmpty() && !TrueEdges.Contains(anEdge))
1678 const Handle(Geom_Curve)& aC3DE = BRep_Tool::Curve(anEdge, f, l);
1679 Handle(Geom_TrimmedCurve) aC3DETrim;
1682 aC3DETrim = new Geom_TrimmedCurve(aC3DE, f, l);
1685 Standard_Real aTolEdge = BRep_Tool::Tolerance(anEdge);
1687 if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, cpF1)) {
1688 Handle(Geom2d_Curve) aC2d = aBC.Curve().FirstCurve2d();
1689 if(!aC3DETrim.IsNull()) {
1690 Handle(Geom2d_Curve) aC2dNew;
1692 if(aC3DE->IsPeriodic()) {
1693 BOPTools_AlgoTools2D::AdjustPCurveOnFace(cpF1, f, l, aC2d, aC2dNew, aContext);
1696 BOPTools_AlgoTools2D::AdjustPCurveOnFace(cpF1, aC3DETrim, aC2d, aC2dNew, aContext);
1700 aBB.UpdateEdge(anEdge, aC2d, cpF1, aTolEdge);
1703 if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, cpF2)) {
1704 Handle(Geom2d_Curve) aC2d = aBC.Curve().SecondCurve2d();
1705 if(!aC3DETrim.IsNull()) {
1706 Handle(Geom2d_Curve) aC2dNew;
1708 if(aC3DE->IsPeriodic()) {
1709 BOPTools_AlgoTools2D::AdjustPCurveOnFace(cpF2, f, l, aC2d, aC2dNew, aContext);
1712 BOPTools_AlgoTools2D::AdjustPCurveOnFace(cpF2, aC3DETrim, aC2d, aC2dNew, aContext);
1716 aBB.UpdateEdge(anEdge, aC2d, cpF2, aTolEdge);
1719 OrientSection (anEdge, F1, F2, O1, O2);
1720 if (Side == TopAbs_OUT) {
1721 O1 = TopAbs::Reverse(O1);
1722 O2 = TopAbs::Reverse(O2);
1725 L1.Append (anEdge.Oriented(O1));
1726 L2.Append (anEdge.Oriented(O2));
1731 sprintf(name,"EI_%d",NbNewEdges++);
1732 DBRep::Set(name,anEdge.Oriented(O1));
1740 Standard_Real aSameParTol = Precision::Confusion();
1741 Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
1743 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(cpF1);
1744 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1745 aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
1746 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1747 addPCurve1 = Standard_False;
1748 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1749 isEl1 = Standard_True;
1751 aSurf = BRep_Tool::Surface(cpF2);
1752 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1753 aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
1754 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1755 addPCurve2 = Standard_False;
1756 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1757 isEl2 = Standard_True;
1759 if (L1.Extent() > 1 && (!isEl1 || !isEl2)) {
1760 TopTools_SequenceOfShape eseq;
1761 TopTools_SequenceOfShape EdgesForConcat;
1763 if (!TrueEdges.IsEmpty())
1765 for (i = TrueEdges.Extent(); i >= 1; i--)
1766 EdgesForConcat.Append( TrueEdges(i) );
1767 TopoDS_Edge theEdge =
1768 AssembleEdge( pDS, cpF1, cpF2, addPCurve1, addPCurve2, EdgesForConcat );
1769 eseq.Append(theEdge);
1774 TopTools_SequenceOfShape wseq;
1775 TopTools_SequenceOfShape edges;
1776 TopTools_ListIteratorOfListOfShape itl(L1);
1777 for (; itl.More(); itl.Next())
1778 edges.Append( itl.Value() );
1779 while (!edges.IsEmpty())
1781 TopoDS_Edge anEdge = TopoDS::Edge( edges.First() );
1782 TopoDS_Wire aWire = BRepLib_MakeWire( anEdge ), resWire;
1783 TColStd_SequenceOfInteger Candidates;
1784 for (k = 1; k <= wseq.Length(); k++)
1786 resWire = TopoDS::Wire(wseq(k));
1787 if (AreConnex( resWire, aWire, pDS ))
1789 Candidates.Append( 1 );
1793 if (Candidates.IsEmpty())
1795 wseq.Append( aWire );
1800 for (j = 2; j <= edges.Length(); j++)
1802 anEdge = TopoDS::Edge( edges(j) );
1803 //if (anEdge.IsSame(edges(Candidates.First())))
1805 aWire = BRepLib_MakeWire( anEdge );
1806 if (AreConnex( resWire, aWire, pDS ))
1807 Candidates.Append( j );
1809 Standard_Integer minind = 1;
1810 if (Candidates.Length() > 1)
1812 Standard_Real MinAngle = RealLast();
1813 for (j = 1; j <= Candidates.Length(); j++)
1815 anEdge = TopoDS::Edge( edges(Candidates(j)) );
1816 Standard_Real anAngle = AngleWireEdge( resWire, anEdge );
1817 if (anAngle < MinAngle)
1824 TopoDS_Wire NewWire = BRepLib_MakeWire( resWire, TopoDS::Edge(edges(Candidates(minind))) );
1826 edges.Remove(Candidates(minind));
1828 } //end of while (!edges.IsEmpty())
1830 for (i = 1; i <= wseq.Length(); i++)
1832 TopoDS_Wire aWire = TopoDS::Wire(wseq(i));
1833 TopTools_SequenceOfShape aLocalEdgesForConcat;
1836 TopoDS_Vertex StartVertex;
1837 TopoDS_Edge StartEdge;
1838 Standard_Boolean StartFound = Standard_False;
1839 TopTools_ListOfShape Elist;
1841 TopoDS_Iterator itw(aWire);
1842 for (; itw.More(); itw.Next())
1844 TopoDS_Edge anEdge = TopoDS::Edge(itw.Value());
1846 Elist.Append(anEdge);
1849 TopoDS_Vertex V1, V2;
1850 TopExp::Vertices( anEdge, V1, V2 );
1851 if (!IsAutonomVertex( V1, pDS ))
1855 StartFound = Standard_True;
1857 else if (!IsAutonomVertex( V2, pDS ))
1861 StartFound = Standard_True;
1864 Elist.Append(anEdge);
1866 } //end of for (; itw.More(); itw.Next())
1869 itl.Initialize(Elist);
1870 StartEdge = TopoDS::Edge(itl.Value());
1872 TopoDS_Vertex V1, V2;
1873 TopExp::Vertices( StartEdge, V1, V2 );
1876 aLocalEdgesForConcat.Append( StartEdge );
1877 while (!Elist.IsEmpty())
1879 for (itl.Initialize(Elist); itl.More(); itl.Next())
1881 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
1882 TopoDS_Vertex V1, V2;
1883 TopExp::Vertices( anEdge, V1, V2 );
1884 if (V1.IsSame(StartVertex))
1887 aLocalEdgesForConcat.Append( anEdge );
1891 else if (V2.IsSame(StartVertex))
1894 aLocalEdgesForConcat.Append( anEdge );
1899 } //end of while (!Elist.IsEmpty())
1900 } //end of if (aWire.Closed())
1903 BRepTools_WireExplorer Wexp( aWire );
1904 for (; Wexp.More(); Wexp.Next())
1905 aLocalEdgesForConcat.Append( Wexp.Current() );
1908 TopoDS_Edge theEdge =
1909 AssembleEdge( pDS, cpF1, cpF2, addPCurve1, addPCurve2, aLocalEdgesForConcat );
1910 eseq.Append( theEdge );
1912 } //end of else (when TrueEdges is empty)
1914 if (eseq.Length() < L1.Extent())
1918 for (i = 1; i <= eseq.Length(); i++)
1920 TopoDS_Edge anEdge = TopoDS::Edge(eseq(i));
1921 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1922 Standard_Real EdgeTol = BRep_Tool::Tolerance(anEdge);
1924 cout<<"Tolerance of glued E = "<<EdgeTol<<endl;
1926 if (EdgeTol > 1.e-2)
1929 if (EdgeTol >= 1.e-4)
1931 ReconstructPCurves(anEdge);
1932 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1934 cout<<"After projection tol of E = "<<BRep_Tool::Tolerance(anEdge)<<endl;
1938 OrientSection( anEdge, F1, F2, O1, O2 );
1939 if (Side == TopAbs_OUT)
1941 O1 = TopAbs::Reverse(O1);
1942 O2 = TopAbs::Reverse(O2);
1945 L1.Append( anEdge.Oriented(O1) );
1946 L2.Append( anEdge.Oriented(O2) );
1949 } //end of if (L1.Extent() > 1)
1953 TopTools_ListIteratorOfListOfShape itl(L1);
1954 for (; itl.More(); itl.Next())
1956 const TopoDS_Edge& anEdge = TopoDS::Edge( itl.Value() );
1957 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1962 //=======================================================================
1963 //function : TryProject
1965 //=======================================================================
1967 Standard_Boolean BRepOffset_Tool::TryProject
1968 (const TopoDS_Face& F1,
1969 const TopoDS_Face& F2,
1970 const TopTools_ListOfShape& Edges,
1971 TopTools_ListOfShape& LInt1,
1972 TopTools_ListOfShape& LInt2,
1973 const TopAbs_State Side,
1974 const Standard_Real TolConf)
1979 sprintf(name,"FF_%d",NbFaces++);
1980 DBRep::Set(name,F1);
1981 sprintf(name,"FF_%d",NbFaces++);
1982 DBRep::Set(name,F2);
1986 // try to find if the edges <Edges> are laying on the face F1.
1987 LInt1.Clear(); LInt2.Clear();
1988 TopTools_ListIteratorOfListOfShape it(Edges);
1989 Standard_Boolean isOk = Standard_True;
1990 Standard_Boolean Ok = Standard_True;
1991 TopAbs_Orientation O1,O2;
1992 Handle(Geom_Surface) Bouchon = BRep_Tool::Surface(F1);
1995 for ( ; it.More(); it.Next()) {
1998 TopoDS_Edge CurE = TopoDS::Edge(it.Value());
1999 Handle(Geom_Curve) C = BRep_Tool::Curve(CurE,L,f,l);
2001 BRepLib::BuildCurve3d(CurE,BRep_Tool::Tolerance(CurE));
2002 C = BRep_Tool::Curve(CurE,L,f,l);
2004 C = new Geom_TrimmedCurve(C,f,l);
2005 if ( !L.IsIdentity()) C->Transform(L);
2006 Standard_Real TolReached;
2007 isOk = IsOnSurface(C,Bouchon,TolConf,TolReached);
2010 B.UpdateEdge(CurE,TolReached);
2011 BuildPCurves(CurE,F1);
2012 OrientSection (CurE,F1,F2,O1,O2);
2013 if (Side == TopAbs_OUT) {
2014 O1 = TopAbs::Reverse(O1);
2015 O2 = TopAbs::Reverse(O2);
2017 LInt1.Append (CurE.Oriented(O1));
2018 LInt2.Append (CurE.Oriented(O2));
2022 sprintf(name,"EI_%d",NbNewEdges++);
2023 DBRep::Set(name,CurE.Oriented(O1));
2028 Ok = Standard_False;
2034 //=======================================================================
2035 //function : InterOrExtent
2037 //=======================================================================
2039 void BRepOffset_Tool::InterOrExtent(const TopoDS_Face& F1,
2040 const TopoDS_Face& F2,
2041 TopTools_ListOfShape& L1,
2042 TopTools_ListOfShape& L2,
2043 const TopAbs_State Side)
2048 sprintf(name,"FF_%d",NbFaces++);
2049 DBRep::Set(name,F1);
2050 sprintf(name,"FF_%d",NbFaces++);
2051 DBRep::Set(name,F2);
2055 Handle (Geom_Curve) CI;
2056 TopAbs_Orientation O1,O2;
2057 L1.Clear(); L2.Clear();
2058 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
2059 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
2061 if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2062 Handle(Geom_RectangularTrimmedSurface) RTS ;
2063 RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S1);
2064 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
2065 S1 = RTS->BasisSurface();
2068 if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2069 Handle(Geom_RectangularTrimmedSurface) RTS ;
2070 RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S2);
2071 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
2072 S2 = RTS->BasisSurface();
2076 GeomInt_IntSS Inter (S1,S2, Precision::Confusion());
2078 if (Inter.IsDone()) {
2079 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
2082 if (ToSmall(CI)) continue;
2083 TopoDS_Edge E = BRepLib_MakeEdge(CI);
2084 BuildPCurves (E,F1);
2085 BuildPCurves (E,F2);
2086 OrientSection (E,F1,F2,O1,O2);
2087 if (Side == TopAbs_OUT) {
2088 O1 = TopAbs::Reverse(O1);
2089 O2 = TopAbs::Reverse(O2);
2091 L1.Append (E.Oriented(O1));
2092 L2.Append (E.Oriented(O2));
2096 sprintf(name,"EI_%d",NbNewEdges++);
2097 DBRep::Set(name,E.Oriented(O1));
2104 //=======================================================================
2105 //function : ExtentEdge
2107 //=======================================================================
2109 static void ExtentEdge(const TopoDS_Face& F,
2110 const TopoDS_Face& EF,
2111 const TopoDS_Edge& E,
2114 BRepAdaptor_Curve CE(E);
2115 GeomAbs_CurveType Type = CE.GetType();
2116 TopoDS_Shape aLocalEdge = E.EmptyCopied();
2117 NE = TopoDS::Edge(aLocalEdge);
2118 // NE = TopoDS::Edge(E.EmptyCopied());
2120 if (Type == GeomAbs_Line || Type == GeomAbs_Circle || Type == GeomAbs_Ellipse ||
2121 Type == GeomAbs_Hyperbola || Type == GeomAbs_Parabola) {
2124 // Extension en tangence jusqu'au bord de la surface.
2125 Standard_Real PMax = 1.e2;
2127 Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
2128 Standard_Real umin,umax,vmin,vmax;
2130 S->Bounds(umin,umax,vmin,vmax);
2131 umin = Max(umin,-PMax);vmin = Max(vmin,-PMax);
2132 umax = Min(umax, PMax);vmax = Min(vmax, PMax);
2136 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f,l);
2138 //calcul point cible . ie point d'intersection du prolongement tangent et des bords.
2141 C2d->D1(CE.FirstParameter(),P,Tang);
2142 Standard_Real tx,ty,tmin;
2143 tx = ty = Precision::Infinite();
2144 if (Abs(Tang.X()) > Precision::Confusion())
2145 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
2146 if (Abs(Tang.Y()) > Precision::Confusion())
2147 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
2150 gp_Pnt2d PF2d (P.X() - Tang.X(),P.Y() - Tang.Y());
2152 C2d->D1(CE.LastParameter(),P,Tang);
2153 tx = ty = Precision::Infinite();
2154 if (Abs(Tang.X()) > Precision::Confusion())
2155 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
2156 if (Abs(Tang.Y()) > Precision::Confusion())
2157 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
2160 gp_Pnt2d PL2d (P.X() + Tang.X(),P.Y() + Tang.Y());
2162 Handle(Geom_Curve) CC = GeomAPI::To3d(C2d,gp_Pln(gp::XOY()));
2163 gp_Pnt PF(PF2d.X(),PF2d.Y(),0.);
2164 gp_Pnt PL(PL2d.X(),PL2d.Y(),0.);
2166 Handle(Geom_BoundedCurve) ExtC = Handle(Geom_BoundedCurve)::DownCast(CC);
2167 if (ExtC.IsNull()) return;
2169 GeomLib::ExtendCurveToPoint(ExtC,PF,1,0);
2170 GeomLib::ExtendCurveToPoint(ExtC,PL,1,1);
2172 Handle(Geom2d_Curve) CNE2d = GeomAPI::To2d(ExtC,gp_Pln(gp::XOY()));
2174 //Construction de la nouvelle arrete;
2177 // B.UpdateEdge (NE,CNE2d,F,BRep_Tool::Tolerance(E));
2178 B.UpdateEdge (NE,CNE2d,EF,BRep_Tool::Tolerance(E));
2179 B.Range (NE,CNE2d->FirstParameter(), CNE2d->LastParameter());
2180 NE.Orientation(E.Orientation());
2184 sprintf (name,"F_%d",NbExtE);
2185 DBRep::Set(name,EF);
2186 sprintf (name,"OE_%d",NbExtE);
2187 DBRep::Set (name,E);
2188 sprintf (name,"ExtE_%d",NbExtE++);
2189 DBRep::Set(name,NE);
2194 //=======================================================================
2195 //function : ProjectVertexOnEdge
2197 //=======================================================================
2199 static Standard_Boolean ProjectVertexOnEdge(TopoDS_Vertex& V,
2200 const TopoDS_Edge& E,
2201 Standard_Real TolConf)
2211 Standard_Real U = 0.;
2213 Standard_Boolean found = Standard_False;
2215 gp_Pnt P = BRep_Tool::Pnt (V);
2216 BRepAdaptor_Curve C = BRepAdaptor_Curve(E);
2217 f = C.FirstParameter(); l = C.LastParameter();
2219 if (V.Orientation() == TopAbs_FORWARD) {
2220 if (Abs(f) < Precision::Infinite()) {
2221 gp_Pnt PF = C.Value (f);
2222 if (PF.IsEqual(P,TolConf)) {
2224 found = Standard_True;
2228 if (V.Orientation() == TopAbs_REVERSED) {
2229 if (!found && Abs(l) < Precision::Infinite()) {
2230 gp_Pnt PL = C.Value (l);
2231 if (PL.IsEqual(P,TolConf)) {
2233 found = Standard_True;
2238 Extrema_ExtPC Proj(P,C);
2239 if (Proj.IsDone() && Proj.NbExt() > 0) {
2240 Standard_Real Dist2,Dist2Min = Proj.SquareDistance(1);
2241 U = Proj.Point(1).Parameter();
2242 for (Standard_Integer i = 2; i <= Proj.NbExt(); i++) {
2243 Dist2 = Proj.SquareDistance(i);
2244 if (Dist2 < Dist2Min) {
2246 U = Proj.Point(i).Parameter();
2249 found = Standard_True;
2255 Standard_Real Dist = P.Distance(C.Value(U));
2256 if (Dist > TolConf) {
2257 cout << " ProjectVertexOnEdge :distance vertex edge :"<<Dist<<endl;
2259 if (U < f - Precision::Confusion() ||
2260 U > l + Precision::Confusion()) {
2261 cout << " ProjectVertexOnEdge : hors borne :"<<endl;
2262 cout << " f = "<<f<<" l ="<<l<< " U ="<<U<<endl;
2266 cout <<"BRepOffset_Tool::ProjectVertexOnEdge Parameter no found"<<endl;
2267 if (Abs(f) < Precision::Infinite() &&
2268 Abs(l) < Precision::Infinite()) {
2276 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
2277 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
2278 aLocalShape = V.Oriented(TopAbs_INTERNAL);
2279 // TopoDS_Edge EE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
2280 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
2281 U,EE,BRep_Tool::Tolerance(E));
2287 //=======================================================================
2288 //function : Inter2d
2290 //=======================================================================
2292 void BRepOffset_Tool::Inter2d (const TopoDS_Face& F,
2293 const TopoDS_Edge& E1,
2294 const TopoDS_Edge& E2,
2295 TopTools_ListOfShape& LV,
2296 const Standard_Real TolConf)
2300 DBRep::Set("E1",E1);
2301 DBRep::Set("E2",E2);
2306 Standard_Real fl1[2],fl2[2];
2309 // Si l edge a ete etendu les pcurves ne sont pas forcement
2315 // Construction des curves 3d si elles n existent pas
2316 // utile pour coder correctement les parametres des vertex
2317 // d intersection sur les edges.
2318 //TopLoc_Location L;
2319 //Standard_Real f,l;
2320 //Handle(Geom_Curve) C3d1 = BRep_Tool::Curve(E1,L,f,l);
2321 //if (C3d1.IsNull()) {
2322 // BRepLib::BuildCurve3d(E1,BRep_Tool::Tolerance(E1));
2324 //Handle(Geom_Curve) C3d2 = BRep_Tool::Curve(E2,L,f,l);
2325 //if (C3d2.IsNull()) {
2326 // BRepLib::BuildCurve3d(E2,BRep_Tool::Tolerance(E2));
2329 Standard_Integer NbPC1 = 1, NbPC2 = 1;
2330 if (BRep_Tool::IsClosed(E1,F)) NbPC1++;
2331 if (BRep_Tool::IsClosed(E2,F)) NbPC2++;
2333 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
2334 Handle(Geom2d_Curve) C1, C2;
2335 Standard_Boolean YaSol = Standard_False;
2336 Standard_Integer itry = 0;
2338 while (!YaSol && itry < 2) {
2339 for ( Standard_Integer i = 1; i <= NbPC1 ; i++) {
2340 TopoDS_Shape aLocalEdgeReversedE1 = E1.Reversed();
2341 if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
2342 else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdgeReversedE1),
2344 // if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
2345 // else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E1.Reversed()),
2346 // F,fl1[0],fl1[1]);
2347 for ( Standard_Integer j = 1; j <= NbPC2; j++ ) {
2348 TopoDS_Shape aLocalEdge = E2.Reversed();
2349 if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2350 else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdge),
2352 // if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2353 // else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E2.Reversed()),
2354 // F,fl2[0],fl2[1]);
2356 if (C1.IsNull() || C2.IsNull()) {
2357 cout <<"Inter2d : Pas de pcurve"<<endl;
2359 DBRep::Set("E1",E1);
2360 DBRep::Set("E2",E2);
2366 Standard_Real U1 = 0.,U2 = 0.;
2368 Standard_Boolean aCurrentFind = Standard_False;
2370 fl1[0] = C1->FirstParameter(); fl1[1] = C1->LastParameter();
2371 fl2[0] = C2->FirstParameter(); fl2[1] = C2->LastParameter();
2373 Geom2dAdaptor_Curve AC1(C1,fl1[0],fl1[1]);
2374 Geom2dAdaptor_Curve AC2(C2,fl2[0],fl2[1]);
2377 gp_Pnt2d P1[2],P2[2];
2378 P1[0] = C1->Value(fl1[0]); P1[1] = C1->Value(fl1[1]);
2379 P2[0] = C2->Value(fl2[0]); P2[1] = C2->Value(fl2[1]);
2381 Standard_Integer i1 ;
2382 for ( i1 = 0; i1 < 2; i1++) {
2383 for (Standard_Integer i2 = 0; i2 < 2; i2++) {
2384 if (Abs(fl1[i1]) < Precision::Infinite() &&
2385 Abs(fl2[i2]) < Precision::Infinite() ) {
2386 if (P1[i1].IsEqual(P2[i2],TolConf)) {
2387 YaSol = Standard_True;
2388 aCurrentFind = Standard_True;
2389 U1 = fl1[i1]; U2 = fl2[i2];
2390 P2d = C1->Value(U1);
2396 for (i1 = 0; i1 < 2; i1++)
2398 Extrema_ExtPC2d extr( P1[i1], AC2 );
2399 if (extr.IsDone() && extr.NbExt() > 0)
2401 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2402 Standard_Integer IndexMin = 1;
2403 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2405 Dist2 = extr.SquareDistance(ind);
2406 if (Dist2 < Dist2Min)
2412 if (Dist2Min <= Precision::SquareConfusion())
2414 YaSol = Standard_True;
2415 aCurrentFind = Standard_True;
2418 U2 = (extr.Point(IndexMin)).Parameter();
2424 for (Standard_Integer i2 = 0; i2 < 2; i2++)
2426 Extrema_ExtPC2d extr( P2[i2], AC1 );
2427 if (extr.IsDone() && extr.NbExt() > 0)
2429 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2430 Standard_Integer IndexMin = 1;
2431 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2433 Dist2 = extr.SquareDistance(ind);
2434 if (Dist2 < Dist2Min)
2440 if (Dist2Min <= Precision::SquareConfusion())
2442 YaSol = Standard_True;
2443 aCurrentFind = Standard_True;
2446 U1 = (extr.Point(IndexMin)).Parameter();
2454 Geom2dInt_GInter Inter (AC1,AC2,TolConf,TolConf);
2456 if (!Inter.IsEmpty() && Inter.NbPoints() > 0) {
2457 YaSol = Standard_True;
2458 aCurrentFind = Standard_True;
2459 U1 = Inter.Point(1).ParamOnFirst();
2460 U2 = Inter.Point(1).ParamOnSecond();
2461 P2d = Inter.Point(1).Value();
2463 else if (!Inter.IsEmpty() && Inter.NbSegments() > 0) {
2464 YaSol = Standard_True;
2465 aCurrentFind = Standard_True;
2466 IntRes2d_IntersectionSegment Seg = Inter.Segment(1);
2467 IntRes2d_IntersectionPoint IntP1 = Seg.FirstPoint();
2468 IntRes2d_IntersectionPoint IntP2 = Seg.LastPoint();
2469 Standard_Real U1on1 = IntP1.ParamOnFirst();
2470 Standard_Real U1on2 = IntP2.ParamOnFirst();
2471 Standard_Real U2on1 = IntP1.ParamOnSecond();
2472 Standard_Real U2on2 = IntP2.ParamOnSecond();
2474 cout << " BRepOffset_Tool::Inter2d SEGMENT d intersection" << endl;
2475 cout << " ===> Parametres sur Curve1 : ";
2476 cout << U1on1 << " " << U1on2 << endl;
2477 cout << " ===> Parametres sur Curve2 : ";
2478 cout << U2on1 << " " << U2on2 << endl;
2480 U1 = (U1on1 + U1on2)/2.;
2481 U2 = (U2on1 + U2on2)/2.;
2482 gp_Pnt2d P2d1 = C1->Value(U1);
2483 gp_Pnt2d P2d2 = C2->Value(U2);
2484 P2d.SetX( (P2d1.X() + P2d2.X()) / 2.);
2485 P2d.SetY( (P2d1.Y() + P2d2.Y()) / 2.);
2489 gp_Pnt P = S->Value(P2d.X(),P2d.Y());
2490 TopoDS_Vertex V = BRepLib_MakeVertex(P);
2491 V.Orientation(TopAbs_INTERNAL);
2492 TopoDS_Shape aLocalEdgeOrientedE1 = E1.Oriented(TopAbs_FORWARD);
2493 B.UpdateVertex(V,U1,TopoDS::Edge(aLocalEdgeOrientedE1),TolConf);
2494 aLocalEdgeOrientedE1 = E2.Oriented(TopAbs_FORWARD);
2495 B.UpdateVertex(V,U2,TopoDS::Edge(aLocalEdgeOrientedE1),TolConf);
2496 // B.UpdateVertex(V,U1,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)),TolConf);
2497 // B.UpdateVertex(V,U2,TopoDS::Edge(E2.Oriented(TopAbs_FORWARD)),TolConf);
2505 if (LV.Extent() > 1) {
2506 //------------------------------------------------
2507 // garde seulement les vertex les plus proches du
2508 //debut et de la fin.
2509 //------------------------------------------------
2510 TopTools_ListIteratorOfListOfShape it(LV);
2511 TopoDS_Vertex VF,VL;
2512 Standard_Real UMin = Precision::Infinite();
2513 Standard_Real UMax = -Precision::Infinite();
2516 for ( ; it.More(); it.Next()) {
2517 TopoDS_Vertex CV = TopoDS::Vertex(it.Value());
2518 TopoDS_Shape aLocalEdge = E1.Oriented(TopAbs_FORWARD);
2519 U = BRep_Tool::Parameter(CV,TopoDS::Edge(aLocalEdge));
2520 // U = BRep_Tool::Parameter(CV,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)));
2528 LV.Clear();LV.Append(VF); LV.Append(VL);
2533 cout <<"Inter2d : Pas de solution"<<endl;
2535 DBRep::Set("E1",E1);
2536 DBRep::Set("E2",E2);
2543 //=======================================================================
2544 //function : SelectEdge
2546 //=======================================================================
2548 static void SelectEdge (const TopoDS_Face& /*F*/,
2549 const TopoDS_Face& /*EF*/,
2550 const TopoDS_Edge& E,
2551 TopTools_ListOfShape& LInt)
2553 //------------------------------------------------------------
2554 // detrompeur sur les intersections sur les faces periodiques
2555 //------------------------------------------------------------
2556 TopTools_ListIteratorOfListOfShape it(LInt);
2557 Standard_Real dU = 1.0e100;
2560 Standard_Real Fst, Lst, tmp;
2561 BRep_Tool::Range(E, Fst, Lst);
2562 BRepAdaptor_Curve Ad1(E);
2564 gp_Pnt PFirst = Ad1.Value( Fst );
2565 gp_Pnt PLast = Ad1.Value( Lst );
2567 //----------------------------------------------------------------------
2568 // Selection de l edge qui couvre le plus le domaine de l edge initiale.
2569 //----------------------------------------------------------------------
2570 for (; it.More(); it.Next()) {
2571 const TopoDS_Edge& EI = TopoDS::Edge(it.Value());
2573 BRep_Tool::Range(EI, Fst, Lst);
2574 BRepAdaptor_Curve Ad2(EI);
2575 gp_Pnt P1 = Ad2.Value(Fst);
2576 gp_Pnt P2 = Ad2.Value(Lst);
2578 tmp = P1.Distance(PFirst) + P2.Distance(PLast);
2590 //=======================================================================
2593 //=======================================================================
2595 static void MakeFace(const Handle(Geom_Surface)& S,
2596 const Standard_Real Um,
2597 const Standard_Real UM,
2598 const Standard_Real Vm,
2599 const Standard_Real VM,
2600 const Standard_Boolean isVminDegen,
2601 const Standard_Boolean isVmaxDegen,
2604 Standard_Real UMin = Um;
2605 Standard_Real UMax = UM;
2606 Standard_Real VMin = Vm;
2607 Standard_Real VMax = VM;
2608 Standard_Real epsilon = Precision::Confusion();
2610 Standard_Real umin,umax,vmin,vmax;
2611 S->Bounds(umin,umax,vmin,vmax);
2614 // compute infinite flags
2615 Standard_Boolean umininf = Precision::IsNegativeInfinite(UMin);
2616 Standard_Boolean umaxinf = Precision::IsPositiveInfinite(UMax);
2617 Standard_Boolean vmininf = Precision::IsNegativeInfinite(VMin);
2618 Standard_Boolean vmaxinf = Precision::IsPositiveInfinite(VMax);
2621 Standard_Boolean IsSuclosed = S->IsUClosed(), IsSvclosed = S->IsVClosed();
2622 if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2624 Handle(Geom_Surface) BasisSurf = Handle(Geom_OffsetSurface)::DownCast (S)->BasisSurface();
2625 IsSuclosed = BasisSurf->IsUClosed();
2626 IsSvclosed = BasisSurf->IsVClosed();
2629 Standard_Boolean uclosed =
2631 Abs(UMin - umin) < epsilon &&
2632 Abs(UMax - umax) < epsilon;
2634 Standard_Boolean vclosed =
2636 Abs(VMin - vmin) < epsilon &&
2637 Abs(VMax - vmax) < epsilon;
2639 // degenerated flags (for cones)
2640 Standard_Boolean vmindegen = isVminDegen, vmaxdegen = isVmaxDegen;
2641 Handle(Geom_Surface) theSurf = S;
2642 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
2643 theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
2644 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
2646 Handle(Geom_ConicalSurface) ConicalS = Handle(Geom_ConicalSurface)::DownCast (theSurf);
2647 gp_Cone theCone = ConicalS->Cone();
2648 gp_Pnt theApex = theCone.Apex();
2649 Standard_Real Uapex, Vapex;
2650 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
2651 if (Abs(VMin - Vapex) <= Precision::Confusion())
2652 vmindegen = Standard_True;
2653 if (Abs(VMax - Vapex) <= Precision::Confusion())
2654 vmaxdegen = Standard_True;
2659 Standard_Real tol = Precision::Confusion();
2661 TopoDS_Vertex V00,V10,V11,V01;
2664 if (!vmininf) B.MakeVertex(V00,S->Value(UMin,VMin),tol);
2665 if (!vmaxinf) B.MakeVertex(V01,S->Value(UMin,VMax),tol);
2668 if (!vmininf) B.MakeVertex(V10,S->Value(UMax,VMin),tol);
2669 if (!vmaxinf) B.MakeVertex(V11,S->Value(UMax,VMax),tol);
2688 Handle(Geom2d_Line) Lumin,Lumax,Lvmin,Lvmax;
2690 Lumin = new Geom2d_Line(gp_Pnt2d(UMin,0),gp_Dir2d(0,1));
2692 Lumax = new Geom2d_Line(gp_Pnt2d(UMax,0),gp_Dir2d(0,1));
2694 Lvmin = new Geom2d_Line(gp_Pnt2d(0,VMin),gp_Dir2d(1,0));
2696 Lvmax = new Geom2d_Line(gp_Pnt2d(0,VMax),gp_Dir2d(1,0));
2698 Handle(Geom_Curve) Cumin,Cumax,Cvmin,Cvmax;
2699 Standard_Real TolApex = 1.e-5;
2700 //Standard_Boolean hasiso = ! S->IsKind(STANDARD_TYPE(Geom_OffsetSurface));
2701 Standard_Boolean hasiso = S->IsKind(STANDARD_TYPE(Geom_ElementarySurface));
2704 Cumin = S->UIso(UMin);
2706 Cumax = S->UIso(UMax);
2709 Cvmin = S->VIso(VMin);
2710 if (BRepOffset_Tool::Gabarit( Cvmin ) <= TolApex)
2711 vmindegen = Standard_True;
2715 Cvmax = S->VIso(VMax);
2716 if (BRepOffset_Tool::Gabarit( Cvmax ) <= TolApex)
2717 vmaxdegen = Standard_True;
2722 B.MakeFace(F,S,tol);
2725 TopoDS_Edge eumin,eumax,evmin,evmax;
2729 B.MakeEdge(eumin,Cumin,tol);
2733 B.UpdateEdge(eumin,Lumax,Lumin,F,tol);
2735 B.UpdateEdge(eumin,Lumin,F,tol);
2737 V00.Orientation(TopAbs_FORWARD);
2741 V01.Orientation(TopAbs_REVERSED);
2744 B.Range(eumin,VMin,VMax);
2752 B.MakeEdge(eumax,Cumax,tol);
2755 B.UpdateEdge(eumax,Lumax,F,tol);
2757 V10.Orientation(TopAbs_FORWARD);
2761 V11.Orientation(TopAbs_REVERSED);
2764 B.Range(eumax,VMin,VMax);
2769 if (hasiso && !vmindegen)
2770 B.MakeEdge(evmin,Cvmin,tol);
2774 B.UpdateEdge(evmin,Lvmin,Lvmax,F,tol);
2776 B.UpdateEdge(evmin,Lvmin,F,tol);
2778 V00.Orientation(TopAbs_FORWARD);
2782 V10.Orientation(TopAbs_REVERSED);
2785 B.Range(evmin,UMin,UMax);
2787 B.Degenerated(evmin, Standard_True);
2794 if (hasiso && !vmaxdegen)
2795 B.MakeEdge(evmax,Cvmax,tol);
2798 B.UpdateEdge(evmax,Lvmax,F,tol);
2800 V01.Orientation(TopAbs_FORWARD);
2804 V11.Orientation(TopAbs_REVERSED);
2807 B.Range(evmax,UMin,UMax);
2809 B.Degenerated(evmax, Standard_True);
2813 // make the wires and add them to the face
2814 eumin.Orientation(TopAbs_REVERSED);
2815 evmax.Orientation(TopAbs_REVERSED);
2819 if (!umininf && !umaxinf && vmininf && vmaxinf) {
2830 else if (umininf && umaxinf && !vmininf && !vmaxinf) {
2841 else if (!umininf || !umaxinf || !vmininf || !vmaxinf) {
2844 if (!umininf) B.Add(W,eumin);
2845 if (!vmininf) B.Add(W,evmin);
2846 if (!umaxinf) B.Add(W,eumax);
2847 if (!vmaxinf) B.Add(W,evmax);
2849 W.Closed(!umininf && !umaxinf && !vmininf && !vmaxinf);
2850 F.Closed(uclosed && vclosed);
2854 //=======================================================================
2855 //function : EnLargeGeometry
2857 //=======================================================================
2859 static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S,
2864 Standard_Boolean& IsV1degen,
2865 Standard_Boolean& IsV2degen,
2866 const Standard_Real uf1,
2867 const Standard_Real uf2,
2868 const Standard_Real vf1,
2869 const Standard_Real vf2,
2870 const Standard_Boolean GlobalEnlargeU,
2871 const Standard_Boolean GlobalEnlargeVfirst,
2872 const Standard_Boolean GlobalEnlargeVlast)
2874 const Standard_Real coeff = 4.;
2875 const Standard_Real TolApex = 1.e-5;
2877 Standard_Boolean SurfaceChange = Standard_False;
2878 if ( S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2879 Handle(Geom_Surface) BS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
2880 EnlargeGeometry(BS,U1,U2,V1,V2,IsV1degen,IsV2degen,
2881 uf1,uf2,vf1,vf2,GlobalEnlargeU,GlobalEnlargeVfirst,GlobalEnlargeVlast);
2882 if (!GlobalEnlargeVfirst)
2884 if (!GlobalEnlargeVlast)
2886 if (!GlobalEnlargeVfirst || !GlobalEnlargeVlast)
2887 //Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->SetTrim( U1, U2, V1, V2 );
2888 S = new Geom_RectangularTrimmedSurface( BS, U1, U2, V1, V2 );
2891 SurfaceChange = Standard_True;
2893 else if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)) {
2894 Handle(Geom_Surface) Surf = Handle(Geom_OffsetSurface)::DownCast (S)->BasisSurface();
2895 SurfaceChange = EnlargeGeometry(Surf,U1,U2,V1,V2,IsV1degen,IsV2degen,
2896 uf1,uf2,vf1,vf2,GlobalEnlargeU,GlobalEnlargeVfirst,GlobalEnlargeVlast);
2897 Handle(Geom_OffsetSurface)::DownCast(S)->SetBasisSurface(Surf);
2899 else if (S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
2900 S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution))
2902 Standard_Real du=0., dv=0.;
2903 Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
2904 Standard_Real u1, u2, v1, v2;
2905 Standard_Boolean enlargeU = GlobalEnlargeU, enlargeV = Standard_True;
2906 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2907 Standard_Boolean enlargeVfirst = GlobalEnlargeVfirst, enlargeVlast = GlobalEnlargeVlast;
2908 S->Bounds( u1, u2, v1, v2 );
2909 if (Precision::IsInfinite(u1) || Precision::IsInfinite(u2))
2914 enlargeU = Standard_False;
2916 else if (S->IsUClosed())
2917 enlargeU = Standard_False;
2920 viso = S->VIso( vf1 );
2921 GeomAdaptor_Curve gac( viso );
2922 du = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2923 uiso1 = S->UIso( uf1 );
2924 uiso2 = S->UIso( uf2 );
2925 if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
2926 enlargeUfirst = Standard_False;
2927 if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
2928 enlargeUlast = Standard_False;
2930 if (Precision::IsInfinite(v1) || Precision::IsInfinite(v2))
2935 enlargeV = Standard_False;
2937 else if (S->IsVClosed())
2938 enlargeV = Standard_False;
2941 uiso = S->UIso( uf1 );
2942 GeomAdaptor_Curve gac( uiso );
2943 dv = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2944 viso1 = S->VIso( vf1 );
2945 viso2 = S->VIso( vf2 );
2946 if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
2948 enlargeVfirst = Standard_False;
2949 IsV1degen = Standard_True;
2951 if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
2953 enlargeVlast = Standard_False;
2954 IsV2degen = Standard_True;
2957 Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface( S, u1, u2, v1, v2 );
2961 GeomLib::ExtendSurfByLength (aSurf, du, 1, Standard_True, Standard_False);
2963 GeomLib::ExtendSurfByLength (aSurf, du, 1, Standard_True, Standard_True);
2968 GeomLib::ExtendSurfByLength (aSurf, dv, 1, Standard_False, Standard_False);
2970 GeomLib::ExtendSurfByLength (aSurf, dv, 1, Standard_False, Standard_True);
2973 S->Bounds( U1, U2, V1, V2 );
2974 SurfaceChange = Standard_True;
2976 else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
2977 S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
2979 Standard_Boolean enlargeU = GlobalEnlargeU, enlargeV = Standard_True;
2980 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2981 Standard_Boolean enlargeVfirst = GlobalEnlargeVfirst, enlargeVlast = GlobalEnlargeVlast;
2983 enlargeU = Standard_False;
2985 enlargeV = Standard_False;
2987 Standard_Real duf = uf2-uf1, dvf = vf2-vf1;
2988 Standard_Real u1, u2, v1, v2;
2989 S->Bounds( u1, u2, v1, v2 );
2991 Standard_Real du=0., dv=0.;
2992 Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
2993 GeomAdaptor_Curve gac;
2996 viso = S->VIso( v1 );
2998 du = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2999 uiso1 = S->UIso( u1 );
3000 uiso2 = S->UIso( u2 );
3001 if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
3002 enlargeUfirst = Standard_False;
3003 if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
3004 enlargeUlast = Standard_False;
3008 uiso = S->UIso( u1 );
3010 dv = GCPnts_AbscissaPoint::Length( gac ) / coeff;
3011 viso1 = S->VIso( v1 );
3012 viso2 = S->VIso( v2 );
3013 if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
3015 enlargeVfirst = Standard_False;
3016 IsV1degen = Standard_True;
3018 if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
3020 enlargeVlast = Standard_False;
3021 IsV2degen = Standard_True;
3025 Handle(Geom_BoundedSurface) aSurf = Handle(Geom_BoundedSurface)::DownCast (S);
3028 if (enlargeUfirst && uf1-u1 < duf)
3029 GeomLib::ExtendSurfByLength (aSurf, du, 1, Standard_True, Standard_False);
3030 if (enlargeUlast && u2-uf2 < duf)
3031 GeomLib::ExtendSurfByLength (aSurf, du, 1, Standard_True, Standard_True);
3035 if (enlargeVfirst && vf1-v1 < dvf)
3036 GeomLib::ExtendSurfByLength (aSurf, dv, 1, Standard_False, Standard_False);
3037 if (enlargeVlast && v2-vf2 < dvf)
3038 GeomLib::ExtendSurfByLength (aSurf, dv, 1, Standard_False, Standard_True);
3042 S->Bounds( U1, U2, V1, V2 );
3043 SurfaceChange = Standard_True;
3045 // else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
3046 // S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface)) {
3047 // S->Bounds(U1,U2,V1,V2);
3050 Standard_Real UU1,UU2,VV1,VV2;
3051 S->Bounds(UU1,UU2,VV1,VV2);
3052 // Pas d extension au dela des bornes de la surface.
3058 return SurfaceChange;
3061 //=======================================================================
3062 //function : UpDatePCurve
3063 //purpose : Mise a jour des pcurves de F sur la surface de de BF.
3064 // F and BF has to be FORWARD,
3065 //=======================================================================
3067 static void UpdatePCurves (const TopoDS_Face& F,
3073 TopTools_IndexedMapOfShape Emap;
3074 Handle(Geom2d_Curve) NullPCurve;
3076 TopExp::MapShapes( F, TopAbs_EDGE, Emap );
3078 for (i = 1; i <= Emap.Extent(); i++)
3080 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
3081 CE.Orientation( TopAbs_FORWARD );
3082 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface( CE, F, f, l );
3085 if (BRep_Tool::IsClosed( CE, F ))
3088 Handle(Geom2d_Curve) C2R = BRep_Tool::CurveOnSurface( CE, F, f, l );
3089 B.UpdateEdge( CE, NullPCurve, NullPCurve, F, BRep_Tool::Tolerance(CE) );
3090 B.UpdateEdge( CE, C2, C2R, BF, BRep_Tool::Tolerance(CE) );
3094 B.UpdateEdge( CE, NullPCurve, F, BRep_Tool::Tolerance(CE) );
3095 B.UpdateEdge( CE, C2, BF, BRep_Tool::Tolerance(CE) );
3103 //=======================================================================
3104 //function :CompactUVBounds
3106 //=======================================================================
3108 static void CompactUVBounds (const TopoDS_Face& F,
3109 Standard_Real& UMin,
3110 Standard_Real& UMax,
3111 Standard_Real& VMin,
3112 Standard_Real& VMax)
3114 // Calcul serre pour que les bornes ne couvrent pas plus d une periode
3115 Standard_Real U1,U2;
3116 Standard_Real N = 33;
3119 TopExp_Explorer exp;
3120 for (exp.Init(F, TopAbs_EDGE); exp.More(); exp.Next()) {
3121 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3122 BRepAdaptor_Curve2d C(E,F);
3123 BRep_Tool::Range(E,U1,U2);
3125 Standard_Real U = U1;
3126 Standard_Real DU = (U2-U1)/(N-1);
3127 for (Standard_Integer j=1;j<N;j++) {
3135 B.Get(UMin,VMin,UMax,VMax);
3138 //=======================================================================
3139 //function : CheckBounds
3141 //=======================================================================
3143 void BRepOffset_Tool::CheckBounds(const TopoDS_Face& F,
3144 const BRepOffset_Analyse& Analyse,
3145 Standard_Boolean& enlargeU,
3146 Standard_Boolean& enlargeVfirst,
3147 Standard_Boolean& enlargeVlast)
3149 enlargeU = Standard_True;
3150 enlargeVfirst = Standard_True; enlargeVlast = Standard_True;
3152 Standard_Integer Ubound = 0, Vbound = 0;
3153 Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
3154 Standard_Real Vfirst = RealLast(), Vlast = RealFirst();
3156 Standard_Real UF1,UF2,VF1,VF2;
3157 CompactUVBounds(F,UF1,UF2,VF1,VF2);
3159 Handle(Geom_Surface) theSurf = BRep_Tool::Surface(F);
3160 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
3161 theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (theSurf)->BasisSurface();
3163 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
3164 theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution) ||
3165 theSurf->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
3166 theSurf->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
3168 TopExp_Explorer Explo(F, TopAbs_EDGE);
3169 for (; Explo.More(); Explo.Next())
3171 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
3172 const BRepOffset_ListOfInterval& L = Analyse.Type(anEdge);
3173 if (!L.IsEmpty() || BRep_Tool::Degenerated(anEdge))
3175 BRepOffset_Type OT = L.First().Type();
3176 if (OT == BRepOffset_Tangent || BRep_Tool::Degenerated(anEdge))
3178 Standard_Real fpar, lpar;
3179 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, F, fpar, lpar);
3180 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
3181 aCurve = Handle(Geom2d_TrimmedCurve)::DownCast (aCurve)->BasisCurve();
3183 Handle(Geom2d_Line) theLine;
3184 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_Line))
3185 theLine = Handle(Geom2d_Line)::DownCast (aCurve);
3186 else if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BezierCurve) ||
3187 aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BSplineCurve))
3189 Standard_Real newFpar, newLpar, deviation;
3190 theLine = ShapeCustom_Curve2d::ConvertToLine2d(aCurve, fpar, lpar, Precision::Confusion(),
3191 newFpar, newLpar, deviation);
3194 if (!theLine.IsNull())
3196 gp_Dir2d theDir = theLine->Direction();
3197 if (theDir.IsParallel( gp::DX2d(), Precision::Angular() ))
3200 if (BRep_Tool::Degenerated(anEdge))
3202 if (Abs(theLine->Location().Y() - VF1) <= Precision::Confusion())
3203 enlargeVfirst = Standard_False;
3204 else //theLine->Location().Y() is near VF2
3205 enlargeVlast = Standard_False;
3209 if (theLine->Location().Y() < Vfirst)
3210 Vfirst = theLine->Location().Y();
3211 if (theLine->Location().Y() > Vlast)
3212 Vlast = theLine->Location().Y();
3215 else if (theDir.IsParallel( gp::DY2d(), Precision::Angular() ))
3218 if (theLine->Location().X() < Ufirst)
3219 Ufirst = theLine->Location().X();
3220 if (theLine->Location().X() > Ulast)
3221 Ulast = theLine->Location().X();
3229 if (Ubound >= 2 || Vbound >= 2)
3232 Abs(UF1-Ufirst) <= Precision::Confusion() &&
3233 Abs(UF2-Ulast) <= Precision::Confusion())
3234 enlargeU = Standard_False;
3236 Abs(VF1-Vfirst) <= Precision::Confusion() &&
3237 Abs(VF2-Vlast) <= Precision::Confusion())
3239 enlargeVfirst = Standard_False;
3240 enlargeVlast = Standard_False;
3245 //=======================================================================
3246 //function : EnLargeFace
3248 //=======================================================================
3250 Standard_Boolean BRepOffset_Tool::EnLargeFace
3251 (const TopoDS_Face& F,
3253 const Standard_Boolean CanExtentSurface,
3254 const Standard_Boolean UpdatePCurve,
3255 const Standard_Boolean enlargeU,
3256 const Standard_Boolean enlargeVfirst,
3257 const Standard_Boolean enlargeVlast)
3259 //---------------------------
3260 // extension de la geometrie.
3261 //---------------------------
3263 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
3264 Standard_Real UU1,VV1,UU2,VV2;
3265 Standard_Boolean isVV1degen = Standard_False, isVV2degen = Standard_False;
3266 Standard_Real US1,VS1,US2,VS2;
3267 Standard_Real UF1,VF1,UF2,VF2;
3268 Standard_Boolean SurfaceChange = Standard_False;
3270 if (S->IsUPeriodic() || S->IsVPeriodic()) {
3271 // Calcul serre pour que les bornes ne couvre pas plus d une periode
3272 CompactUVBounds(F,UF1,UF2,VF1,VF2);
3275 BRepTools::UVBounds(F,UF1,UF2,VF1,VF2);
3278 S->Bounds (US1,US2,VS1,VS2);
3279 UU1 = VV1 = - TheInfini;
3280 UU2 = VV2 = TheInfini;
3282 if (CanExtentSurface) {
3283 SurfaceChange = EnlargeGeometry( S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2,
3284 enlargeU, enlargeVfirst, enlargeVlast );
3287 UU1 = Max(US1,UU1); UU2 = Min(UU2,US2);
3288 VV1 = Max(VS1,VV1); VV2 = Min(VS2,VV2);
3291 if (S->IsUPeriodic()) {
3292 Standard_Real Period = S->UPeriod();
3293 Standard_Real Delta = Period - (UF2 - UF1);
3294 Standard_Real alpha = 0.1;
3295 UU1 = UF1 - alpha*Delta; UU2 = UF2 + alpha*Delta;
3296 if ((UU2 - UU1) > Period) {
3300 if (S->IsVPeriodic()) {
3301 Standard_Real Period = S->VPeriod();
3302 Standard_Real Delta = Period - (VF2 - VF1);
3303 Standard_Real alpha = 0.1;
3304 VV1 = VF1 - alpha*Delta; VV2 = VF2 + alpha*Delta;
3305 if ((VV2 - VV1) > Period) {
3310 //Special treatment for conical surfaces
3311 Handle(Geom_Surface) theSurf = S;
3312 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
3313 theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
3314 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
3316 Handle(Geom_ConicalSurface) ConicalS = Handle(Geom_ConicalSurface)::DownCast (theSurf);
3317 gp_Cone theCone = ConicalS->Cone();
3318 gp_Pnt theApex = theCone.Apex();
3319 Standard_Real Uapex, Vapex;
3320 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
3321 if (VV1 < Vapex && Vapex < VV2)
3323 //consider that VF1 and VF2 are on the same side from apex
3324 Standard_Real TolApex = 1.e-5;
3325 if (Vapex - VF1 >= TolApex ||
3326 Vapex - VF2 >= TolApex) //if (VF1 < Vapex || VF2 < Vapex)
3335 UU1 = UF1; UU2 = UF2;
3342 MakeFace(S,UU1,UU2,VV1,VV2,isVV1degen,isVV2degen,BF);
3345 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
3347 //----------------------------------------------------------------
3348 // utile pour les bouchons on ne doit pas changer leur geometrie.
3349 // (Ce que fait BRepLib_MakeFace si S est restreinte).
3350 // On remet S et on update les pcurves.
3351 //----------------------------------------------------------------
3352 TopExp_Explorer exp;
3353 exp.Init(BF,TopAbs_EDGE);
3354 Standard_Real f=0.,l=0.;
3355 for (; exp.More(); exp.Next()) {
3356 TopoDS_Edge CE = TopoDS::Edge(exp.Current());
3357 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,BF,f,l);
3358 B.UpdateEdge (CE,C2,S,L,BRep_Tool::Tolerance(CE));
3360 B.UpdateFace(BF,S,L,BRep_Tool::Tolerance(F));
3363 if (SurfaceChange && UpdatePCurve) {
3364 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3365 UpdatePCurves(TopoDS::Face(aLocalFace),BF);
3366 //UpdatePCurves(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),BF);
3368 BB.UpdateFace( F, S, L, BRep_Tool::Tolerance(F) );
3371 BF.Orientation(F.Orientation());
3372 return SurfaceChange;
3375 //=======================================================================
3376 //function : TryParameter
3378 //=======================================================================
3380 static Standard_Boolean TryParameter (const TopoDS_Edge& OE,
3382 const TopoDS_Edge& NE,
3383 Standard_Real TolConf)
3385 BRepAdaptor_Curve OC(OE);
3386 BRepAdaptor_Curve NC(NE);
3387 Standard_Real Of = OC.FirstParameter(); Standard_Real Ol = OC.LastParameter();
3388 Standard_Real Nf = NC.FirstParameter(); Standard_Real Nl = NC.LastParameter();
3389 Standard_Real U = 0.;
3390 gp_Pnt P = BRep_Tool::Pnt(V);
3391 Standard_Boolean OK = Standard_False;
3393 if (P.Distance(OC.Value(Of)) < TolConf) {
3394 if (Of > Nf && Of < Nl && P.Distance(NC.Value(Of)) < TolConf) {
3399 if (P.Distance(OC.Value(Ol)) < TolConf) {
3400 if (Ol > Nf && Ol < Nl && P.Distance(NC.Value(Ol)) < TolConf) {
3407 TopoDS_Shape aLocalShape = NE.Oriented(TopAbs_FORWARD);
3408 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
3409 // TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD));
3410 aLocalShape = V.Oriented(TopAbs_INTERNAL);
3411 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
3412 U,NE,BRep_Tool::Tolerance(NE));
3413 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
3414 // U,NE,BRep_Tool::Tolerance(NE));
3419 //=======================================================================
3422 //=======================================================================
3424 void BRepOffset_Tool::MapVertexEdges (const TopoDS_Shape& S,
3425 TopTools_DataMapOfShapeListOfShape& MEV)
3427 TopExp_Explorer exp;
3428 exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3429 TopTools_MapOfShape DejaVu;
3430 for ( ; exp.More(); exp.Next()) {
3431 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3432 if (DejaVu.Add(E)) {
3433 TopoDS_Vertex V1,V2;
3434 TopExp::Vertices (E,V1,V2);
3435 if (!MEV.IsBound(V1)) {
3436 TopTools_ListOfShape empty;
3440 if (!V1.IsSame(V2)) {
3441 if (!MEV.IsBound(V2)) {
3442 TopTools_ListOfShape empty;
3451 //=======================================================================
3454 //=======================================================================
3456 void BRepOffset_Tool::BuildNeighbour (const TopoDS_Wire& W,
3457 const TopoDS_Face& F,
3458 TopTools_DataMapOfShapeShape& NOnV1,
3459 TopTools_DataMapOfShapeShape& NOnV2)
3461 TopoDS_Vertex V1,V2,VP1,VP2,FV1,FV2;
3462 TopoDS_Edge CurE,FirstE,PrecE;
3463 BRepTools_WireExplorer wexp;
3465 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3466 TopoDS_Shape aLocalWire = W.Oriented(TopAbs_FORWARD);
3467 wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
3468 // wexp.Init(TopoDS::Wire(W.Oriented(TopAbs_FORWARD)),
3469 // TopoDS::Face(F.Oriented(TopAbs_FORWARD)));
3470 CurE = FirstE = PrecE = wexp.Current();
3471 TopExp::Vertices(CurE,V1,V2);
3472 FV1 = VP1 = V1; FV2 = VP2 = V2;
3474 while (wexp.More()) {
3475 CurE = wexp.Current();
3476 TopExp::Vertices(CurE,V1,V2);
3477 if (V1.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3478 if (V1.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3479 if (V2.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3480 if (V2.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3485 if (V1.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3486 if (V1.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3487 if (V2.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3488 if (V2.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3491 //=======================================================================
3492 //function : ExtentFace
3494 //=======================================================================
3496 void BRepOffset_Tool::ExtentFace (const TopoDS_Face& F,
3497 TopTools_DataMapOfShapeShape& ConstShapes,
3498 TopTools_DataMapOfShapeShape& ToBuild,
3499 const TopAbs_State Side,
3500 const Standard_Real TolConf,
3506 sprintf(name,"FTE_%d",NbFTE++);
3511 TopExp_Explorer exp,exp2;
3512 TopTools_DataMapOfShapeShape Build;
3513 TopTools_DataMapOfShapeShape Extent;
3514 TopoDS_Edge FirstE,PrecE,CurE,NE;
3518 // Construction de la boite englobante de la face a etendre et des bouchons pour
3519 // limiter les extensions.
3520 //Bnd_Box ContextBox;
3521 //BRepBndLib::Add(F,B);
3522 //TopTools_DataMapIteratorOfDataMapOfShape itTB(ToBuild);
3523 //for (; itTB.More(); itTB.Next()) {
3524 //BRepBndLib::Add(TopBuild.Value(), ContextBox);
3528 Standard_Boolean SurfaceChange;
3529 SurfaceChange = EnLargeFace (F,EF,Standard_True);
3531 TopoDS_Shape aLocalShape = EF.EmptyCopied();
3532 NF = TopoDS::Face(aLocalShape);
3533 // NF = TopoDS::Face(EF.EmptyCopied());
3534 NF.Orientation(TopAbs_FORWARD);
3536 if (SurfaceChange) {
3537 //------------------------------------------------
3538 // Mise a jour des pcurves sur la surface de base.
3539 //------------------------------------------------
3540 TopoDS_Face Fforward = F;
3541 Fforward.Orientation(TopAbs_FORWARD);
3542 TopTools_IndexedMapOfShape Emap;
3543 TopExp::MapShapes( Fforward, TopAbs_EDGE, Emap );
3545 for (Standard_Integer i = 1; i <= Emap.Extent(); i++) {
3546 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
3547 CE.Orientation(TopAbs_FORWARD);
3548 TopoDS_Edge Ecs; //patch
3549 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,Fforward,f,l);
3551 if (ConstShapes.IsBound(CE)) {
3552 Ecs = TopoDS::Edge(ConstShapes(CE));
3553 BRep_Tool::Range(Ecs,f,l);
3555 if (BRep_Tool::IsClosed(CE,Fforward)) {
3556 TopoDS_Shape aLocalShapeReversedCE = CE.Reversed();
3557 Handle(Geom2d_Curve) C2R =
3558 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShapeReversedCE),Fforward,f,l);
3559 // Handle(Geom2d_Curve) C2R =
3560 // BRep_Tool::CurveOnSurface(TopoDS::Edge(CE.Reversed()),F,f,l);
3561 B.UpdateEdge (CE,C2,C2R,EF,BRep_Tool::Tolerance(CE));
3563 B.UpdateEdge (Ecs,C2,C2R,EF,BRep_Tool::Tolerance(CE));
3566 B.UpdateEdge (CE,C2,EF,BRep_Tool::Tolerance(CE));
3568 B.UpdateEdge (Ecs,C2,EF,BRep_Tool::Tolerance(CE));
3577 for (exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
3580 const TopoDS_Wire& W = TopoDS::Wire(exp.Current());
3581 TopTools_DataMapOfShapeListOfShape MVE; // Vertex -> Edges incidentes.
3582 TopTools_DataMapOfShapeShape NOnV1;
3583 TopTools_DataMapOfShapeShape NOnV2;
3585 MapVertexEdges (W,MVE);
3586 BuildNeighbour (W,F,NOnV1,NOnV2);
3588 TopTools_ListOfShape LInt1,LInt2;
3589 TopoDS_Face StopFace;
3590 //------------------------------------------------
3591 // Construction edges
3592 //------------------------------------------------
3593 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3594 exp2.More(); exp2.Next()) {
3595 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3596 if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
3597 if (ToBuild.IsBound(E)) {
3598 TopTools_ListOfShape LOE;
3600 BRepOffset_Tool::TryProject (TopoDS::Face(ToBuild(E)),
3601 EF,LOE,LInt2,LInt1,Side,TolConf);
3602 if (!LInt1.IsEmpty())
3607 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3608 exp2.More(); exp2.Next()) {
3609 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3610 if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
3611 if (ToBuild.IsBound(E)) {
3612 EnLargeFace(TopoDS::Face(ToBuild(E)),StopFace,Standard_False);
3613 BRepOffset_Tool::Inter3D (EF,StopFace,LInt1,LInt2,Side,E,Standard_True);
3614 // No intersection, it may happen for example for a chosen (non-offseted) planar face and
3615 // its neighbour offseted cylindrical face, if the offset is directed so that
3616 // the radius of the cylinder becomes smaller.
3617 if (LInt1.IsEmpty())
3619 if (LInt1.Extent() > 1) {
3620 // l intersection est en plusieurs edges (franchissement de couture)
3621 SelectEdge (F,EF,E,LInt1);
3623 NE = TopoDS::Edge(LInt1.First());
3624 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &NE.TShape());
3625 TE->Tolerance( TE->Tolerance()*10. ); //????
3626 if (NE.Orientation() == E.Orientation()) {
3627 Build.Bind(E,NE.Oriented(TopAbs_FORWARD));
3630 Build.Bind(E,NE.Oriented(TopAbs_REVERSED));
3632 const TopoDS_Edge& EOnV1 = TopoDS::Edge(NOnV1(E));
3633 if (!ToBuild .IsBound(EOnV1) &&
3634 !ConstShapes.IsBound(EOnV1) &&
3635 !Build .IsBound(EOnV1)) {
3636 ExtentEdge (F,EF,EOnV1,NE);
3637 Build.Bind (EOnV1,NE.Oriented(TopAbs_FORWARD));
3639 const TopoDS_Edge& EOnV2 = TopoDS::Edge(NOnV2(E));
3640 if (!ToBuild .IsBound(EOnV2) &&
3641 !ConstShapes.IsBound(EOnV2) &&
3642 !Build .IsBound(EOnV2)) {
3643 ExtentEdge (F,EF,EOnV2,NE);
3644 Build.Bind (EOnV2,NE.Oriented (TopAbs_FORWARD));
3649 //------------------------------------------------
3650 // Construction Vertex.
3651 //------------------------------------------------
3652 TopTools_ListOfShape LV;
3655 TopoDS_Vertex V1,V2;
3657 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE); exp2.More(); exp2.Next())
3659 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3660 TopExp::Vertices (E,V1,V2);
3661 BRep_Tool::Range (E,f,l);
3663 if (Build.IsBound(E))
3665 const TopoDS_Edge& NEOnV1 = TopoDS::Edge(NOnV1(E));
3666 if (Build.IsBound(NEOnV1) && (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV1)))
3668 if (E.IsSame(NEOnV1))
3669 V = TopExp::FirstVertex(TopoDS::Edge(Build(E)));
3675 if (!Build.IsBound(V1))
3677 Inter2d (EF,TopoDS::Edge(Build(E)), TopoDS::Edge(Build(NEOnV1)),LV,/*TolConf*/Precision::Confusion());
3681 if (Build(E).Orientation() == TopAbs_FORWARD)
3683 V = TopoDS::Vertex(LV.First());
3687 V = TopoDS::Vertex(LV.Last());
3697 V = TopoDS::Vertex(Build(V1));
3698 if (MVE (V1).Extent() > 2)
3700 V.Orientation(TopAbs_FORWARD);
3701 if (Build(E).Orientation() == TopAbs_REVERSED)
3702 V.Orientation(TopAbs_REVERSED);
3704 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3715 if (ConstShapes.IsBound(V1)) V = TopoDS::Vertex(ConstShapes(V1));
3716 V.Orientation(TopAbs_FORWARD);
3717 if (Build(E).Orientation() == TopAbs_REVERSED)
3718 V.Orientation(TopAbs_REVERSED);
3719 if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
3720 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3723 ConstShapes.Bind(V1,V);
3725 const TopoDS_Edge& NEOnV2 = TopoDS::Edge(NOnV2(E));
3726 if (Build.IsBound(NEOnV2) && (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV2)))
3728 if (E.IsSame(NEOnV2))
3729 V = TopExp::LastVertex(TopoDS::Edge(Build(E)));
3736 if (!Build.IsBound(V2))
3738 Inter2d (EF,TopoDS::Edge(Build(E)), TopoDS::Edge(Build(NEOnV2)),LV,/*TolConf*/Precision::Confusion());
3742 if (Build(E).Orientation() == TopAbs_FORWARD)
3744 V = TopoDS::Vertex(LV.Last());
3748 V = TopoDS::Vertex(LV.First());
3758 V = TopoDS::Vertex(Build(V2));
3759 if (MVE (V2).Extent() > 2)
3761 V.Orientation(TopAbs_REVERSED);
3762 if (Build(E).Orientation() == TopAbs_REVERSED)
3763 V.Orientation(TopAbs_FORWARD);
3765 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3776 if (ConstShapes.IsBound(V2))
3777 V = TopoDS::Vertex(ConstShapes(V2));
3778 V.Orientation(TopAbs_REVERSED);
3779 if (Build(E).Orientation() == TopAbs_REVERSED)
3780 V.Orientation(TopAbs_FORWARD);
3781 if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
3782 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3784 ConstShapes.Bind(V2,V);
3790 TopoDS_Vertex NV1,NV2;
3791 TopAbs_Orientation Or;
3792 Standard_Real U1,U2;
3793 Standard_Real eps = Precision::Confusion();
3803 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3804 exp2.More(); exp2.Next()) {
3805 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3806 TopExp::Vertices (E,V1,V2);
3807 if (Build.IsBound(E)) {
3808 NE = TopoDS::Edge(Build(E));
3809 BRep_Tool::Range(NE,f,l);
3810 Or = NE.Orientation();
3811 //-----------------------------------------------------
3812 // Copy pour virer les vertex deja sur la nouvelle edge.
3813 //-----------------------------------------------------
3814 NV1 = TopoDS::Vertex(ConstShapes(V1));
3815 NV2 = TopoDS::Vertex(ConstShapes(V2));
3817 TopoDS_Shape aLocalVertexOrientedNV1 = NV1.Oriented(TopAbs_INTERNAL);
3818 TopoDS_Shape aLocalEdge = NE.Oriented(TopAbs_INTERNAL);
3820 U1 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalVertexOrientedNV1),
3821 TopoDS::Edge (aLocalEdge));
3822 aLocalVertexOrientedNV1 = NV2.Oriented(TopAbs_INTERNAL);
3823 aLocalEdge = NE.Oriented(TopAbs_FORWARD);
3824 U2 = BRep_Tool::Parameter (TopoDS::Vertex(aLocalVertexOrientedNV1),TopoDS::Edge (aLocalEdge));
3825 // U1 = BRep_Tool::Parameter
3826 // (TopoDS::Vertex(NV1.Oriented(TopAbs_INTERNAL)),
3827 // TopoDS::Edge (NE .Oriented(TopAbs_FORWARD)));
3828 // U2 = BRep_Tool::Parameter
3829 // (TopoDS::Vertex(NV2.Oriented(TopAbs_INTERNAL)),
3830 // TopoDS::Edge (NE.Oriented(TopAbs_FORWARD)));
3831 aLocalEdge = NE.EmptyCopied();
3832 NE = TopoDS::Edge(aLocalEdge);
3833 NE.Orientation(TopAbs_FORWARD);
3834 if (NV1.IsSame(NV2))
3839 if (Or == TopAbs_FORWARD) {U1 = f; U2 = l;}
3840 else {U1 = l; U2 = f;}
3841 if (Or == TopAbs_FORWARD)
3845 if (Abs(U1-l) < eps) U1 = f;
3846 if (Abs(U2-f) < eps) U2 = l;
3848 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3849 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3850 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3851 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3852 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3853 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3855 ConstShapes.Bind(E,NE);
3856 NE.Orientation(E.Orientation());
3862 if (Abs(U2-l) < eps) U2 = f;
3863 if (Abs(U1-f) < eps) U1 = l;
3865 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3866 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3867 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3868 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3869 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3870 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3872 ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
3873 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3878 //-------------------
3879 // edge is not ferme.
3880 //-------------------
3881 if (Or == TopAbs_FORWARD) {
3883 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3884 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3885 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3886 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3887 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3888 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3893 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3894 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3895 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3896 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3897 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3898 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3901 ConstShapes.Bind(E,NE);
3902 NE.Orientation(E.Orientation());
3906 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3907 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3908 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3909 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3910 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3911 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3913 ConstShapes.Bind(E,NE);
3914 NE.Orientation(E.Orientation());
3918 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3919 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3920 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3921 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3922 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3923 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3925 ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
3926 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3931 } // Build.IsBound(E)
3932 else if (ConstShapes.IsBound(E)) { // !Build.IsBound(E)
3933 NE = TopoDS::Edge(ConstShapes(E));
3934 BuildPCurves(NE,NF);
3935 Or = NE.Orientation();
3936 if (Or == TopAbs_REVERSED) {
3937 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3940 NE.Orientation(E.Orientation());
3945 ConstShapes.Bind(E,NE.Oriented(TopAbs_FORWARD));
3949 B.Add(NF,NW.Oriented(W.Orientation()));
3951 NF.Orientation(F.Orientation());
3952 BRepTools::Update(NF); // Maj des UVPoints
3957 sprintf(name,"FOB_%d",NbFOB++);
3958 DBRep::Set(name,NF);
3964 //=======================================================================
3965 //function : Deboucle3D
3967 //=======================================================================
3969 TopoDS_Shape BRepOffset_Tool::Deboucle3D(const TopoDS_Shape& S,
3970 const TopTools_MapOfShape& Boundary)
3972 return BRepAlgo_Tool::Deboucle3D(S,Boundary);
3975 //=======================================================================
3976 //function : IsInOut
3978 //=======================================================================
3980 static Standard_Boolean IsInOut (BRepTopAdaptor_FClass2d& FC,
3981 Geom2dAdaptor_Curve AC,
3982 const TopAbs_State& S )
3984 Standard_Real Def = 100*Precision::Confusion();
3985 GCPnts_QuasiUniformDeflection QU(AC,Def);
3987 for (Standard_Integer i = 1; i <= QU.NbPoints(); i++) {
3988 gp_Pnt2d P = AC.Value(QU.Parameter(i));
3989 if (FC.Perform(P) != S) {
3990 return Standard_False;
3993 return Standard_True;
3996 //=======================================================================
3997 //function : CorrectOrientation
3999 //=======================================================================
4001 void BRepOffset_Tool::CorrectOrientation(const TopoDS_Shape& SI,
4002 const TopTools_IndexedMapOfShape& NewEdges,
4003 Handle(BRepAlgo_AsDes)& AsDes,
4004 BRepAlgo_Image& InitOffset,
4005 const Standard_Real Offset)
4008 TopExp_Explorer exp;
4009 exp.Init(SI,TopAbs_FACE);
4010 Standard_Real f=0.,l=0.;
4012 for (; exp.More(); exp.Next()) {
4014 const TopoDS_Face& FI = TopoDS::Face(exp.Current());
4015 const TopTools_ListOfShape& LOF = InitOffset.Image(FI);
4016 TopTools_ListIteratorOfListOfShape it(LOF);
4017 for (; it.More(); it.Next()) {
4018 const TopoDS_Face& OF = TopoDS::Face(it.Value());
4019 TopTools_ListOfShape& LOE = AsDes->ChangeDescendant(OF);
4020 TopTools_ListIteratorOfListOfShape itE(LOE);
4022 Standard_Boolean YaInt = Standard_False;
4023 for (; itE.More(); itE.Next()) {
4024 const TopoDS_Edge& OE = TopoDS::Edge(itE.Value());
4025 if (NewEdges.Contains(OE)) {YaInt = Standard_True; break;}
4028 TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
4029 BRepTopAdaptor_FClass2d FC (TopoDS::Face(aLocalFace),
4030 Precision::Confusion());
4031 // BRepTopAdaptor_FClass2d FC (TopoDS::Face(FI.Oriented(TopAbs_FORWARD)),
4032 // Precision::Confusion());
4033 for (itE.Initialize(LOE); itE.More(); itE.Next()) {
4034 TopoDS_Shape& OE = itE.Value();
4035 if (NewEdges.Contains(OE)) {
4036 Handle(Geom2d_Curve) CO2d =
4037 BRep_Tool::CurveOnSurface(TopoDS::Edge(OE),OF,f,l);
4038 Geom2dAdaptor_Curve AC(CO2d,f,l);
4041 if (IsInOut(FC,AC,TopAbs_OUT)) OE.Reverse();
4044 // if (IsInOut(FC,AC,TopAbs_IN)) OE.Reverse();
4054 //=======================================================================
4055 //function : CheckNormals
4057 //=======================================================================
4058 Standard_Boolean BRepOffset_Tool::CheckPlanesNormals(const TopoDS_Face& theFace1,
4059 const TopoDS_Face& theFace2,
4060 const Standard_Real theTolAng)
4062 BRepAdaptor_Surface aBAS1(theFace1, Standard_False), aBAS2(theFace2, Standard_False);
4063 if (aBAS1.GetType() != GeomAbs_Plane ||
4064 aBAS2.GetType() != GeomAbs_Plane) {
4065 return Standard_False;
4068 gp_Dir aDN1 = aBAS1.Plane().Position().Direction();
4069 if (theFace1.Orientation() == TopAbs_REVERSED) {
4073 gp_Dir aDN2 = aBAS2.Plane().Position().Direction();
4074 if (theFace2.Orientation() == TopAbs_REVERSED) {
4078 Standard_Real anAngle = aDN1.Angle(aDN2);
4079 return (anAngle < theTolAng);
4082 //=======================================================================
4083 //function : PerformPlanes
4085 //=======================================================================
4086 void PerformPlanes(const TopoDS_Face& theFace1,
4087 const TopoDS_Face& theFace2,
4088 const TopAbs_State theSide,
4089 TopTools_ListOfShape& theL1,
4090 TopTools_ListOfShape& theL2)
4094 // Intersect the planes using IntTools_FaceFace directly
4095 IntTools_FaceFace aFF;
4096 aFF.SetParameters(Standard_True, Standard_True, Standard_True, Precision::Confusion());
4097 aFF.Perform(theFace1, theFace2);
4099 if (!aFF.IsDone()) {
4103 const IntTools_SequenceOfCurves& aSC = aFF.Lines();
4104 if (aSC.IsEmpty()) {
4108 // In Plane/Plane intersection only one curve is always produced.
4109 // Make the edge from this section curve.
4113 const IntTools_Curve& aIC = aSC(1);
4114 const Handle(Geom_Curve)& aC3D = aIC.Curve();
4115 aBB.MakeEdge(aE, aC3D, aIC.Tolerance());
4116 // Get bounds of the curve
4117 Standard_Real aTF, aTL;
4119 aIC.Bounds(aTF, aTL, aPF, aPL);
4120 // Make the bounding vertices
4121 TopoDS_Vertex aVF, aVL;
4122 aBB.MakeVertex(aVF, aPF, aIC.Tolerance());
4123 aBB.MakeVertex(aVL, aPL, aIC.Tolerance());
4124 aVL.Orientation(TopAbs_REVERSED);
4125 // Add vertices to the edge
4128 // Add 2D curves to the edge
4129 aBB.UpdateEdge(aE, aIC.FirstCurve2d(), theFace1, aIC.Tolerance());
4130 aBB.UpdateEdge(aE, aIC.SecondCurve2d(), theFace2, aIC.Tolerance());
4131 // Update range of the new edge
4132 aBB.Range(aE, aTF, aTL);
4136 TopAbs_Orientation O1, O2;
4137 BRepOffset_Tool::OrientSection(aE, theFace1, theFace2, O1, O2);
4138 if (theSide == TopAbs_OUT) {
4139 O1 = TopAbs::Reverse(O1);
4140 O2 = TopAbs::Reverse(O2);
4143 BRepLib::SameParameter(aE, Precision::Confusion(), Standard_True);
4145 // Add edge to result
4146 theL1.Append(aE.Oriented(O1));
4147 theL2.Append(aE.Oriented(O2));
4150 //=======================================================================
4152 //purpose : Checks if the given value is close to infinite (TheInfini)
4153 //=======================================================================
4154 Standard_Boolean IsInf(const Standard_Real theVal)
4156 return (theVal > TheInfini*0.9);