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_AlgoTools.hxx>
23 #include <BOPTools_AlgoTools2D.hxx>
24 #include <BRep_CurveRepresentation.hxx>
25 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
26 #include <BRep_TEdge.hxx>
27 #include <BRep_Tool.hxx>
28 #include <BRep_Builder.hxx>
29 #include <BRepAdaptor_Curve.hxx>
30 #include <BRepAdaptor_Curve2d.hxx>
31 #include <BRepAdaptor_HCurve.hxx>
32 #include <BRepAdaptor_HSurface.hxx>
33 #include <BRepAdaptor_Surface.hxx>
34 #include <BRepAlgo_AsDes.hxx>
35 #include <BRepAlgo_Image.hxx>
36 #include <BRepAlgo_Tool.hxx>
37 #include <BRepBndLib.hxx>
38 #include <BRepLib.hxx>
39 #include <BRepLib_MakeEdge.hxx>
40 #include <BRepLib_MakeFace.hxx>
41 #include <BRepLib_MakePolygon.hxx>
42 #include <BRepLib_MakeVertex.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 <BRepExtrema_DistShapeShape.hxx>
57 #include <GCPnts_AbscissaPoint.hxx>
58 #include <GCPnts_QuasiUniformDeflection.hxx>
59 #include <GCPnts_UniformAbscissa.hxx>
60 #include <Geom2d_BezierCurve.hxx>
61 #include <Geom2d_BSplineCurve.hxx>
62 #include <Geom2d_Circle.hxx>
63 #include <Geom2d_Curve.hxx>
64 #include <Geom2d_Ellipse.hxx>
65 #include <Geom2d_Hyperbola.hxx>
66 #include <Geom2d_Line.hxx>
67 #include <Geom2d_Parabola.hxx>
68 #include <Geom2d_TrimmedCurve.hxx>
69 #include <Geom2dAdaptor_Curve.hxx>
70 #include <Geom2dConvert_ApproxCurve.hxx>
71 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
72 #include <Geom2dInt_GInter.hxx>
73 #include <Geom_BezierSurface.hxx>
74 #include <Geom_BSplineCurve.hxx>
75 #include <Geom_BSplineSurface.hxx>
76 #include <Geom_Conic.hxx>
77 #include <Geom_ConicalSurface.hxx>
78 #include <Geom_Curve.hxx>
79 #include <Geom_Line.hxx>
80 #include <Geom_OffsetSurface.hxx>
81 #include <Geom_Plane.hxx>
82 #include <Geom_RectangularTrimmedSurface.hxx>
83 #include <Geom_Surface.hxx>
84 #include <Geom_SurfaceOfLinearExtrusion.hxx>
85 #include <Geom_SurfaceOfRevolution.hxx>
86 #include <Geom_TrimmedCurve.hxx>
87 #include <GeomAdaptor_Surface.hxx>
88 #include <GeomAPI.hxx>
89 #include <GeomAPI_ExtremaCurveCurve.hxx>
90 #include <GeomAPI_ProjectPointOnCurve.hxx>
91 #include <GeomConvert_ApproxCurve.hxx>
92 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
93 #include <GeomInt_IntSS.hxx>
94 #include <GeomLib.hxx>
95 #include <GeomProjLib.hxx>
99 #include <IntRes2d_IntersectionPoint.hxx>
100 #include <IntRes2d_IntersectionSegment.hxx>
101 #include <IntTools_FaceFace.hxx>
102 #include <Precision.hxx>
103 #include <ProjLib_HProjectedCurve.hxx>
104 #include <ProjLib_ProjectedCurve.hxx>
105 #include <ShapeCustom_Curve2d.hxx>
106 #include <Standard_ConstructionError.hxx>
107 #include <TColgp_Array1OfPnt2d.hxx>
108 #include <TopAbs.hxx>
109 #include <TopExp.hxx>
110 #include <TopExp_Explorer.hxx>
111 #include <TopoDS.hxx>
112 #include <TopoDS_Compound.hxx>
113 #include <TopoDS_Edge.hxx>
114 #include <TopoDS_Face.hxx>
115 #include <TopoDS_Iterator.hxx>
116 #include <TopoDS_Shape.hxx>
117 #include <TopoDS_Vertex.hxx>
118 #include <TopoDS_Wire.hxx>
119 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
120 #include <TopTools_ListIteratorOfListOfShape.hxx>
121 #include <TopTools_SequenceOfShape.hxx>
125 // The constant defines the maximal value to enlarge surfaces.
126 // It is limited to 1.e+7. This limitation is justified by the
127 // floating point format. As we can have only 15
128 // valuable decimal numbers, then during intersection of surfaces with
129 // bounds of 1.e+8 the possible inaccuracy might appear already in seventh
130 // decimal place which will be more than Precision::Confusion value -
131 // 1.e-7, default tolerance value for the section curves.
132 // By decreasing the max enlarge value to 1.e+7 the inaccuracy will be
133 // shifted to eighth decimal place, i.e. the inaccuracy will be
134 // decreased to values less than 1.e-7.
135 const Standard_Real TheInfini = 1.e+7;
137 //tma: for new boolean operation
140 #include <Geom2d_Conic.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);
161 static void UpdateVertexTolerances(const TopoDS_Face& theFace);
164 Standard_Boolean IsInf(const Standard_Real theVal);
166 //=======================================================================
167 //function : EdgeVertices
169 //=======================================================================
171 void BRepOffset_Tool::EdgeVertices (const TopoDS_Edge& E,
175 if (E.Orientation() == TopAbs_REVERSED) {
176 TopExp::Vertices(E,V2,V1);
179 TopExp::Vertices(E,V1,V2);
183 //=======================================================================
184 //function : OriEdgeInFace
186 //=======================================================================
188 TopAbs_Orientation BRepOffset_Tool::OriEdgeInFace (const TopoDS_Edge& E,
189 const TopoDS_Face& F )
193 Exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
195 for (; Exp.More() ;Exp.Next()) {
196 if (Exp.Current().IsSame(E)) {
197 return Exp.Current().Orientation();
200 throw Standard_ConstructionError("BRepOffset_Tool::OriEdgeInFace");
203 //=======================================================================
204 //function : FindPeriod
206 //=======================================================================
208 static void FindPeriod (const TopoDS_Face& F,
217 for (exp.Init(F,TopAbs_EDGE); exp.More(); exp.Next()) {
218 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
221 const Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,pf,pl);
222 if (C.IsNull()) return;
223 Geom2dAdaptor_Curve PC(C,pf,pl);
224 Standard_Real i, nbp = 20;
225 if (PC.GetType() == GeomAbs_Line) nbp = 2;
226 Standard_Real step = (pl - pf) / nbp;
230 for (i = 2; i < nbp; i++) {
237 B.Get(umin,vmin,umax,vmax);
241 //=======================================================================
242 //function : PutInBounds
243 //purpose : Recadre la courbe 2d dans les bounds de la face
244 //=======================================================================
246 static void PutInBounds (const TopoDS_Face& F,
247 const TopoDS_Edge& E,
248 Handle(Geom2d_Curve)& C2d)
250 Standard_Real umin,umax,vmin,vmax;
252 BRep_Tool::Range(E,f,l);
254 TopLoc_Location L; // Recup S avec la location pour eviter la copie.
255 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
257 if (S->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
258 S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
263 if (!S->IsUPeriodic() && !S->IsVPeriodic()) return;
265 FindPeriod (F,umin,umax,vmin,vmax);
267 if (S->IsUPeriodic()) {
268 Standard_Real period = S->UPeriod();
269 Standard_Real eps = period*1.e-6;
270 gp_Pnt2d Pf = C2d->Value(f);
271 gp_Pnt2d Pl = C2d->Value(l);
272 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
273 Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
274 Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
275 Standard_Real du = 0.;
276 if (minC< umin - eps) {
277 du = (int((umin - minC)/period) + 1)*period;
279 if (minC > umax + eps) {
280 du = -(int((minC - umax)/period) + 1)*period;
285 minC += du; maxC += du;
287 // Ajuste au mieux la courbe dans le domaine.
288 if (maxC > umax +100*eps) {
289 Standard_Real d1 = maxC - umax;
290 Standard_Real d2 = umin - minC + period;
291 if (d2 < d1) du =-period;
301 if (S->IsVPeriodic()) {
302 Standard_Real period = S->VPeriod();
303 Standard_Real eps = period*1.e-6;
304 gp_Pnt2d Pf = C2d->Value(f);
305 gp_Pnt2d Pl = C2d->Value(l);
306 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
307 Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
308 Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
309 Standard_Real dv = 0.;
310 if (minC< vmin - eps) {
311 dv = (int((vmin - minC)/period) + 1)*period;
313 if (minC > vmax + eps) {
314 dv = -(int((minC - vmax)/period) + 1)*period;
319 minC += dv; maxC += dv;
321 // Ajuste au mieux la courbe dans le domaine.
322 if (maxC > vmax +100*eps) {
323 Standard_Real d1 = maxC - vmax;
324 Standard_Real d2 = vmin - minC + period;
325 if (d2 < d1) dv =-period;
334 //=======================================================================
337 //=======================================================================
339 Standard_Real BRepOffset_Tool::Gabarit(const Handle(Geom_Curve)& aCurve)
341 GeomAdaptor_Curve GC( aCurve );
343 BndLib_Add3dCurve::Add( GC, Precision::Confusion(), aBox );
344 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dist;
345 aBox.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
346 dist = Max( (aXmax-aXmin), (aYmax-aYmin) );
347 dist = Max( dist, (aZmax-aZmin) );
351 //=======================================================================
352 //function : BuildPCurves
354 //=======================================================================
356 static void BuildPCurves (const TopoDS_Edge& E,
357 const TopoDS_Face& F)
360 Handle (Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E,F,ff,ll);
361 if (!C2d.IsNull()) return;
363 //Standard_Real Tolerance = Max(Precision::Confusion(),BRep_Tool::Tolerance(E));
364 Standard_Real Tolerance = Precision::Confusion();
366 BRepAdaptor_Surface AS(F,0);
367 BRepAdaptor_Curve AC(E);
369 //Try to find pcurve on a bound of BSpline or Bezier surface
370 Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( F );
371 Handle( Standard_Type ) typS = theSurf->DynamicType();
372 if (typS == STANDARD_TYPE(Geom_OffsetSurface))
373 typS = Handle(Geom_OffsetSurface)::DownCast (theSurf)->BasisSurface()->DynamicType();
374 if (typS == STANDARD_TYPE(Geom_BezierSurface) || typS == STANDARD_TYPE(Geom_BSplineSurface))
376 gp_Pnt fpoint = AC.Value( AC.FirstParameter() );
377 gp_Pnt lpoint = AC.Value( AC.LastParameter() );
378 TopoDS_Face theFace = BRepLib_MakeFace( theSurf, Precision::Confusion() );
379 Standard_Real U1 = 0., U2 = 0., TolProj = 1.e-4; //1.e-5;
381 TopExp_Explorer Explo;
382 Explo.Init( theFace, TopAbs_EDGE );
383 for (; Explo.More(); Explo.Next())
385 TopoDS_Edge anEdge = TopoDS::Edge( Explo.Current() );
386 BRepAdaptor_Curve aCurve( anEdge );
387 Extrema_ExtPC fextr( fpoint, aCurve );
388 if (!fextr.IsDone() || fextr.NbExt() < 1)
390 Standard_Real dist2, dist2min = RealLast();
392 for (i = 1; i <= fextr.NbExt(); i++)
394 dist2 = fextr.SquareDistance(i);
395 if (dist2 < dist2min)
398 U1 = fextr.Point(i).Parameter();
401 if (dist2min > TolProj * TolProj)
403 Extrema_ExtPC lextr( lpoint, aCurve );
404 if (!lextr.IsDone() || lextr.NbExt() <1)
406 dist2min = RealLast();
407 for (i = 1; i <= lextr.NbExt(); i++)
409 dist2 = lextr.SquareDistance(i);
410 if (dist2 < dist2min)
413 U2 = lextr.Point(i).Parameter();
416 if (dist2min <= TolProj * TolProj)
421 } // for (; Explo.More(); Explo.Current())
423 if (! theEdge.IsNull())
425 //Construction of pcurve
428 Standard_Real temp = U1;
433 C2d = BRep_Tool::CurveOnSurface( theEdge, theFace, f, l );
434 C2d = new Geom2d_TrimmedCurve( C2d, U1, U2 );
436 if (theSurf->IsUPeriodic() || theSurf->IsVPeriodic())
437 PutInBounds( F, E, C2d );
440 B.UpdateEdge( E, C2d, F, BRep_Tool::Tolerance(E) );
441 BRepLib::SameRange( E );
447 Handle(BRepAdaptor_HSurface) HS = new BRepAdaptor_HSurface(AS);
448 Handle(BRepAdaptor_HCurve) HC = new BRepAdaptor_HCurve(AC);
450 ProjLib_ProjectedCurve Proj(HS,HC,Tolerance);
452 switch ( Proj.GetType()) {
455 C2d = new Geom2d_Line(Proj.Line());
459 C2d = new Geom2d_Circle(Proj.Circle());
462 case GeomAbs_Ellipse:
463 C2d = new Geom2d_Ellipse(Proj.Ellipse());
466 case GeomAbs_Parabola:
467 C2d = new Geom2d_Parabola(Proj.Parabola());
470 case GeomAbs_Hyperbola:
471 C2d = new Geom2d_Hyperbola(Proj.Hyperbola());
474 case GeomAbs_BezierCurve:
478 case GeomAbs_BSplineCurve:
479 C2d = Proj.BSpline();
485 if (AS.IsUPeriodic() || AS.IsVPeriodic()) {
486 PutInBounds(F,E,C2d);
490 B.UpdateEdge (E,C2d,F,BRep_Tool::Tolerance(E));
493 throw Standard_ConstructionError("BRepOffset_Tool::BuildPCurves");
497 //=======================================================================
500 //=======================================================================
502 void BRepOffset_Tool::OrientSection (const TopoDS_Edge& E,
503 const TopoDS_Face& F1,
504 const TopoDS_Face& F2,
505 TopAbs_Orientation& O1,
506 TopAbs_Orientation& O2)
512 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
513 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
514 Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l);
515 Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l);
516 Handle (Geom_Curve) C = BRep_Tool::Curve(E,L,f,l);
518 BRepAdaptor_Curve BAcurve( E );
520 GCPnts_AbscissaPoint AP(BAcurve,GCPnts_AbscissaPoint::Length(BAcurve)/2.0,f);
521 Standard_Real ParOnC;
524 ParOnC = AP.Parameter();
526 ParOnC = BOPTools_AlgoTools2D::IntermediatePoint(f, l);
528 gp_Vec T1 = C->DN(ParOnC,1).Transformed(L.Transformation());
529 if (T1.SquareMagnitude() > gp::Resolution()) {
533 gp_Pnt2d P = C1->Value(ParOnC);
537 S1->D1(P.X(),P.Y(),P3,D1U,D1V);
539 if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse();
541 P = C2->Value(ParOnC);
542 S2->D1(P.X(),P.Y(),P3,D1U,D1V);
544 if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse();
546 gp_Vec ProVec = DN2^T1;
547 Standard_Real Prod = DN1.Dot(ProVec);
552 O1 = TopAbs_REVERSED;
555 Prod = DN2.Dot(ProVec);
560 O2 = TopAbs_REVERSED;
562 if (F1.Orientation() == TopAbs_REVERSED) O1 = TopAbs::Reverse(O1);
563 if (F2.Orientation() == TopAbs_REVERSED) O2 = TopAbs::Reverse(O2);
566 //=======================================================================
567 //function : FindCommonShapes
569 //=======================================================================
570 Standard_Boolean BRepOffset_Tool::FindCommonShapes(const TopoDS_Face& theF1,
571 const TopoDS_Face& theF2,
572 TopTools_ListOfShape& theLE,
573 TopTools_ListOfShape& theLV)
575 Standard_Boolean bFoundEdges =
576 FindCommonShapes(theF1, theF2, TopAbs_EDGE, theLE);
577 Standard_Boolean bFoundVerts =
578 FindCommonShapes(theF1, theF2, TopAbs_VERTEX, theLV);
579 return bFoundEdges || bFoundVerts;
582 //=======================================================================
583 //function : FindCommonShapes
585 //=======================================================================
586 Standard_Boolean BRepOffset_Tool::FindCommonShapes(const TopoDS_Shape& theS1,
587 const TopoDS_Shape& theS2,
588 const TopAbs_ShapeEnum theType,
589 TopTools_ListOfShape& theLSC)
593 TopTools_MapOfShape aMS;
594 TopExp_Explorer aExp(theS1, theType);
595 for (; aExp.More(); aExp.Next()) {
596 aMS.Add(aExp.Current());
600 return Standard_False;
603 TopTools_MapOfShape aMFence;
604 aExp.Init(theS2, theType);
605 for (; aExp.More(); aExp.Next()) {
606 const TopoDS_Shape& aS2 = aExp.Current();
607 if (aMS.Contains(aS2)) {
608 if (aMFence.Add(aS2)) {
614 return !theLSC.IsEmpty();
617 //=======================================================================
620 //=======================================================================
622 static Standard_Boolean ToSmall (const Handle(Geom_Curve)& C)
624 Standard_Real Tol = 10*Precision::Confusion();
625 Standard_Real m = (C->FirstParameter()*0.668 + C->LastParameter()*0.332);
626 gp_Pnt P1 = C->Value(C->FirstParameter());
627 gp_Pnt P2 = C->Value(C->LastParameter());
628 gp_Pnt P3 = C->Value(m);
629 if (P1.Distance(P2) > Tol) return Standard_False;
630 if (P2.Distance(P3) > Tol) return Standard_False;
631 return Standard_True;
635 //=======================================================================
636 //function : IsOnSurface
638 //=======================================================================
640 static Standard_Boolean IsOnSurface(const Handle(Geom_Curve)& C,
641 const Handle(Geom_Surface)& S,
642 Standard_Real TolConf,
643 Standard_Real& TolReached)
645 Standard_Real f = C->FirstParameter();
646 Standard_Real l = C->LastParameter();
647 Standard_Integer n = 5;
648 Standard_Real du = (f-l)/(n-1);
654 GeomAdaptor_Surface AS(S);
656 switch ( AS.GetType()) {
659 gp_Ax3 Ax = AS.Plane().Position();
660 for ( Standard_Integer i = 0; i < n; i++) {
661 P = C->Value(f+i*du);
662 ElSLib::PlaneParameters(Ax,P,U,V);
663 TolReached = P.Distance(ElSLib::PlaneValue(U,V,Ax));
664 if ( TolReached > TolConf)
665 return Standard_False;
669 case GeomAbs_Cylinder:
671 gp_Ax3 Ax = AS.Cylinder().Position();
672 Standard_Real Rad = AS.Cylinder().Radius();
673 for ( Standard_Integer i = 0; i < n; i++) {
674 P = C->Value(f+i*du);
675 ElSLib::CylinderParameters(Ax,Rad,P,U,V);
676 TolReached = P.Distance(ElSLib::CylinderValue(U,V,Ax,Rad));
677 if ( TolReached > TolConf)
678 return Standard_False;
684 gp_Ax3 Ax = AS.Cone().Position();
685 Standard_Real Rad = AS.Cone().RefRadius();
686 Standard_Real Alp = AS.Cone().SemiAngle();
687 for ( Standard_Integer i = 0; i < n; i++) {
688 P = C->Value(f+i*du);
689 ElSLib::ConeParameters(Ax,Rad,Alp,P,U,V);
690 TolReached = P.Distance(ElSLib::ConeValue(U,V,Ax,Rad,Alp));
691 if ( TolReached > TolConf)
692 return Standard_False;
698 gp_Ax3 Ax = AS.Sphere().Position();
699 Standard_Real Rad = AS.Sphere().Radius();
700 for ( Standard_Integer i = 0; i < n; i++) {
701 P = C->Value(f+i*du);
702 ElSLib::SphereParameters(Ax,Rad,P,U,V);
703 TolReached = P.Distance(ElSLib::SphereValue(U,V,Ax,Rad));
704 if ( TolReached > TolConf)
705 return Standard_False;
711 gp_Ax3 Ax = AS.Torus().Position();
712 Standard_Real R1 = AS.Torus().MajorRadius();
713 Standard_Real R2 = AS.Torus().MinorRadius();
714 for ( Standard_Integer i = 0; i < n; i++) {
715 P = C->Value(f+i*du);
716 ElSLib::TorusParameters(Ax,R1,R2,P,U,V);
717 TolReached = P.Distance(ElSLib::TorusValue(U,V,Ax,R1,R2));
718 if ( TolReached > TolConf)
719 return Standard_False;
726 return Standard_False;
730 return Standard_True;
734 //=======================================================================
735 //function : PipeInter
737 //=======================================================================
739 void BRepOffset_Tool::PipeInter(const TopoDS_Face& F1,
740 const TopoDS_Face& F2,
741 TopTools_ListOfShape& L1,
742 TopTools_ListOfShape& L2,
743 const TopAbs_State Side)
748 sprintf(name,"FF_%d",NbFaces++);
750 sprintf(name,"FF_%d",NbFaces++);
755 Handle (Geom_Curve) CI;
756 TopAbs_Orientation O1,O2;
757 L1.Clear(); L2.Clear();
759 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
760 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
762 GeomInt_IntSS Inter (S1,S2, Precision::Confusion(),1,1,1);
764 if (Inter.IsDone()) {
765 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
767 if (ToSmall(CI)) continue;
768 TopoDS_Edge E = BRepLib_MakeEdge(CI);
769 if (Inter.HasLineOnS1(i)) {
770 Handle(Geom2d_Curve) C2 = Inter.LineOnS1(i);
771 PutInBounds (F1,E,C2);
772 B.UpdateEdge (E,C2,F1,BRep_Tool::Tolerance(E));
777 if (Inter.HasLineOnS2(i)) {
778 Handle(Geom2d_Curve) C2 = Inter.LineOnS2(i);
779 PutInBounds (F2,E,C2);
780 B.UpdateEdge (E,C2,F2,BRep_Tool::Tolerance(E));
785 OrientSection (E,F1,F2,O1,O2);
786 if (Side == TopAbs_OUT) {
787 O1 = TopAbs::Reverse(O1);
788 O2 = TopAbs::Reverse(O2);
790 L1.Append (E.Oriented(O1));
791 L2.Append (E.Oriented(O2));
795 sprintf(name,"EI_%d",NbNewEdges++);
796 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& theVertex,
809 const BOPDS_PDS& thePDS,
810 const TopoDS_Face& theFace1,
811 const TopoDS_Face& theFace2)
813 Standard_Integer nV = thePDS->Index(theVertex);
814 Standard_Integer nF [2];
815 nF[0] = thePDS->Index(theFace1);
816 nF[1] = thePDS->Index(theFace2);
818 for (Standard_Integer i = 0; i < 2; i++)
820 const BOPDS_FaceInfo& aFaceInfo = thePDS->FaceInfo(nF[i]);
821 const TColStd_MapOfInteger& IndMap = aFaceInfo.VerticesOn();
822 if (IndMap.Contains(nV))
823 return Standard_False;
826 return Standard_True;
829 //=======================================================================
830 //function : IsAutonomVertex
831 //purpose : Checks wether a vertex is "autonom" or not
832 //=======================================================================
834 static Standard_Boolean IsAutonomVertex(const TopoDS_Shape& aVertex,
835 const BOPDS_PDS& pDS)
837 Standard_Integer index;
838 Standard_Integer aNbVVs, aNbEEs, aNbEFs, aInt;
840 index = pDS->Index(aVertex);
842 Standard_Integer i, i1, i2;
843 i1=pDS->NbSourceShapes();
845 for (i=i1; i<i2; ++i) {
846 const TopoDS_Shape& aSx=pDS->Shape(i);
847 if(aSx.IsSame(aVertex)) {
854 if (!pDS->IsNewShape(index)) {
855 return Standard_False;
857 //check if vertex with index "index" is not created in VV or EE or EF interference
859 BOPDS_VectorOfInterfVV& aVVs=pDS->InterfVV();
860 aNbVVs = aVVs.Length();
861 for(aInt = 0; aInt < aNbVVs; aInt++) {
862 const BOPDS_InterfVV& aVV = aVVs(aInt);
863 if (aVV.HasIndexNew()) {
864 if (aVV.IndexNew() == index) {
865 return Standard_False;
870 BOPDS_VectorOfInterfEE& aEEs=pDS->InterfEE();
871 aNbEEs = aEEs.Length();
872 for(aInt = 0; aInt < aNbEEs; aInt++) {
873 const BOPDS_InterfEE& aEE = aEEs(aInt);
874 IntTools_CommonPrt aCP = aEE.CommonPart();
875 if(aCP.Type() == TopAbs_VERTEX) {
876 if (aEE.IndexNew() == index) {
877 return Standard_False;
882 BOPDS_VectorOfInterfEF& aEFs=pDS->InterfEF();
883 aNbEFs = aEFs.Length();
884 for(aInt = 0; aInt < aNbEFs; aInt++) {
885 const BOPDS_InterfEF& aEF = aEFs(aInt);
886 IntTools_CommonPrt aCP = aEF.CommonPart();
887 if(aCP.Type() == TopAbs_VERTEX) {
888 if (aEF.IndexNew() == index) {
889 return Standard_False;
893 return Standard_True;
897 //=======================================================================
898 //function : AreConnex
899 //purpose : define if two shapes are connex by a vertex (vertices)
900 //=======================================================================
902 static Standard_Boolean AreConnex(const TopoDS_Wire& W1,
903 const TopoDS_Wire& W2)
905 TopoDS_Vertex V11, V12, V21, V22;
906 TopExp::Vertices( W1, V11, V12 );
907 TopExp::Vertices( W2, V21, V22 );
909 if (V11.IsSame(V21) || V11.IsSame(V22) ||
910 V12.IsSame(V21) || V12.IsSame(V22))
911 return Standard_True;
913 return Standard_False;
916 //=======================================================================
917 //function : AreClosed
918 //purpose : define if two edges are connex by two vertices
919 //=======================================================================
921 static Standard_Boolean AreClosed(const TopoDS_Edge& E1,
922 const TopoDS_Edge& E2)
924 TopoDS_Vertex V11, V12, V21, V22;
925 TopExp::Vertices( E1, V11, V12 );
926 TopExp::Vertices( E2, V21, V22 );
928 if ((V11.IsSame(V21) && V12.IsSame(V22)) ||
929 (V11.IsSame(V22) && V12.IsSame(V21)))
930 return Standard_True;
932 return Standard_False;
935 //=======================================================================
936 //function : BSplineEdges
938 //=======================================================================
940 static Standard_Boolean BSplineEdges(const TopoDS_Edge& E1,
941 const TopoDS_Edge& E2,
942 const Standard_Integer par1,
943 const Standard_Integer par2,
944 Standard_Real& angle)
946 Standard_Real first1, last1, first2, last2, Param1, Param2;
948 Handle(Geom_Curve) C1 = BRep_Tool::Curve( E1, first1, last1 );
949 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
950 C1 = Handle(Geom_TrimmedCurve)::DownCast (C1)->BasisCurve();
952 Handle(Geom_Curve) C2 = BRep_Tool::Curve( E2, first2, last2 );
953 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
954 C2 = Handle(Geom_TrimmedCurve)::DownCast (C2)->BasisCurve();
956 if (!C1->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)) ||
957 !C2->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)))
958 return Standard_False;
960 Param1 = (par1 == 0)? first1 : last1;
961 Param2 = (par2 == 0)? first2 : last2;
965 C1->D1( Param1, Pnt1, Der1 );
966 C2->D1( Param2, Pnt2, Der2 );
968 if (Der1.Magnitude() <= gp::Resolution() ||
969 Der2.Magnitude() <= gp::Resolution())
972 angle = Der1.Angle(Der2);
974 return Standard_True;
977 //=======================================================================
978 //function : AngleWireEdge
980 //=======================================================================
982 static Standard_Real AngleWireEdge(const TopoDS_Wire& aWire,
983 const TopoDS_Edge& anEdge)
985 TopoDS_Vertex V11, V12, V21, V22, CV;
986 TopExp::Vertices( aWire, V11, V12 );
987 TopExp::Vertices( anEdge, V21, V22 );
988 CV = (V11.IsSame(V21) || V11.IsSame(V22))? V11 : V12;
989 TopoDS_Edge FirstEdge;
990 TopoDS_Iterator itw(aWire);
991 for (; itw.More(); itw.Next())
993 FirstEdge = TopoDS::Edge(itw.Value());
994 TopoDS_Vertex v1, v2;
995 TopExp::Vertices( FirstEdge, v1, v2 );
996 if (v1.IsSame(CV) || v2.IsSame(CV))
1003 Standard_Real Angle;
1004 if (V11.IsSame(CV) && V21.IsSame(CV))
1006 BSplineEdges( FirstEdge, anEdge, 0, 0, Angle );
1007 Angle = M_PI - Angle;
1009 else if (V11.IsSame(CV) && V22.IsSame(CV))
1010 BSplineEdges( FirstEdge, anEdge, 0, 1, Angle );
1011 else if (V12.IsSame(CV) && V21.IsSame(CV))
1012 BSplineEdges( FirstEdge, anEdge, 1, 0, Angle );
1015 BSplineEdges( FirstEdge, anEdge, 1, 1, Angle );
1016 Angle = M_PI - Angle;
1022 //=======================================================================
1023 //function : ReconstructPCurves
1025 //=======================================================================
1027 static void ReconstructPCurves(const TopoDS_Edge& anEdge)
1030 Handle(Geom_Curve) C3d = BRep_Tool::Curve(anEdge, f, l);
1032 BRep_ListIteratorOfListOfCurveRepresentation
1033 itcr( (Handle(BRep_TEdge)::DownCast(anEdge.TShape()))->ChangeCurves() );
1034 for (; itcr.More(); itcr.Next())
1036 Handle( BRep_CurveRepresentation ) CurveRep = itcr.Value();
1037 if (CurveRep->IsCurveOnSurface())
1039 Handle(Geom_Surface) theSurf = CurveRep->Surface();
1040 TopLoc_Location theLoc = CurveRep->Location();
1041 theLoc = anEdge.Location() * theLoc;
1042 theSurf = Handle(Geom_Surface)::DownCast
1043 (theSurf->Transformed(theLoc.Transformation()));
1044 Handle(Geom2d_Curve) ProjPCurve =
1045 GeomProjLib::Curve2d( C3d, f, l, theSurf );
1046 if(!ProjPCurve.IsNull())
1048 CurveRep->PCurve( ProjPCurve );
1054 //=======================================================================
1055 //function : ConcatPCurves
1057 //=======================================================================
1059 static Handle(Geom2d_Curve) ConcatPCurves(const TopoDS_Edge& E1,
1060 const TopoDS_Edge& E2,
1061 const TopoDS_Face& F,
1062 const Standard_Boolean After,
1063 Standard_Real& newFirst,
1064 Standard_Real& newLast)
1066 Standard_Real Tol = 1.e-7;
1067 GeomAbs_Shape Continuity = GeomAbs_C1;
1068 Standard_Integer MaxDeg = 14;
1069 Standard_Integer MaxSeg = 16;
1071 Standard_Real first1, last1, first2, last2;
1072 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1074 PCurve1 = BRep_Tool::CurveOnSurface( E1, F, first1, last1 );
1075 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
1076 PCurve1 = Handle(Geom2d_TrimmedCurve)::DownCast (PCurve1)->BasisCurve();
1078 PCurve2 = BRep_Tool::CurveOnSurface( E2, F, first2, last2 );
1079 if (PCurve2->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
1080 PCurve2 = Handle(Geom2d_TrimmedCurve)::DownCast (PCurve2)->BasisCurve();
1082 if (PCurve1 == PCurve2)
1084 newPCurve = PCurve1;
1085 newFirst = Min( first1, first2 );
1086 newLast = Max( last1, last2 );
1088 else if (PCurve1->DynamicType() == PCurve2->DynamicType() &&
1089 (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)) ||
1090 PCurve1->IsKind(STANDARD_TYPE(Geom2d_Conic))))
1092 newPCurve = PCurve1;
1094 P1 = PCurve2->Value( first2 );
1095 P2 = PCurve2->Value( last2 );
1096 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)))
1098 Handle(Geom2d_Line) Lin1 = Handle(Geom2d_Line)::DownCast (PCurve1);
1099 gp_Lin2d theLin = Lin1->Lin2d();
1100 first2 = ElCLib::Parameter( theLin, P1 );
1101 last2 = ElCLib::Parameter( theLin, P2 );
1103 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Circle)))
1105 Handle(Geom2d_Circle) Circ1 = Handle(Geom2d_Circle)::DownCast (PCurve1);
1106 gp_Circ2d theCirc = Circ1->Circ2d();
1107 first2 = ElCLib::Parameter( theCirc, P1 );
1108 last2 = ElCLib::Parameter( theCirc, P2 );
1110 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Ellipse)))
1112 Handle(Geom2d_Ellipse) Ell1 = Handle(Geom2d_Ellipse)::DownCast (PCurve1);
1113 gp_Elips2d theElips = Ell1->Elips2d();
1114 first2 = ElCLib::Parameter( theElips, P1 );
1115 last2 = ElCLib::Parameter( theElips, P2 );
1117 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Parabola)))
1119 Handle(Geom2d_Parabola) Parab1 = Handle(Geom2d_Parabola)::DownCast (PCurve1);
1120 gp_Parab2d theParab = Parab1->Parab2d();
1121 first2 = ElCLib::Parameter( theParab, P1 );
1122 last2 = ElCLib::Parameter( theParab, P2 );
1124 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Hyperbola)))
1126 Handle(Geom2d_Hyperbola) Hypr1 = Handle(Geom2d_Hyperbola)::DownCast (PCurve1);
1127 gp_Hypr2d theHypr = Hypr1->Hypr2d();
1128 first2 = ElCLib::Parameter( theHypr, P1 );
1129 last2 = ElCLib::Parameter( theHypr, P2 );
1131 newFirst = Min( first1, first2 );
1132 newLast = Max( last1, last2 );
1136 Handle(Geom2d_TrimmedCurve) TC1 = new Geom2d_TrimmedCurve( PCurve1, first1, last1 );
1137 Handle(Geom2d_TrimmedCurve) TC2 = new Geom2d_TrimmedCurve( PCurve2, first2, last2 );
1138 Geom2dConvert_CompCurveToBSplineCurve Concat2d( TC1 );
1139 Concat2d.Add( TC2, Precision::Confusion(), After );
1140 newPCurve = Concat2d.BSplineCurve();
1141 if (newPCurve->Continuity() < GeomAbs_C1)
1143 Geom2dConvert_ApproxCurve Approx2d( newPCurve, Tol, Continuity, MaxSeg, MaxDeg );
1144 if (Approx2d.HasResult())
1145 newPCurve = Approx2d.Curve();
1147 newFirst = newPCurve->FirstParameter();
1148 newLast = newPCurve->LastParameter();
1154 //=======================================================================
1156 //purpose : glue two edges.
1157 //=======================================================================
1159 static TopoDS_Edge Glue(const TopoDS_Edge& E1,
1160 const TopoDS_Edge& E2,
1161 const TopoDS_Vertex& Vfirst,
1162 const TopoDS_Vertex& Vlast,
1163 const Standard_Boolean After,
1164 const TopoDS_Face& F1,
1165 const Standard_Boolean addPCurve1,
1166 const TopoDS_Face& F2,
1167 const Standard_Boolean addPCurve2,
1168 const Standard_Real theGlueTol)
1170 TopoDS_Edge newEdge;
1172 Standard_Real Tol = 1.e-7;
1173 GeomAbs_Shape Continuity = GeomAbs_C1;
1174 Standard_Integer MaxDeg = 14;
1175 Standard_Integer MaxSeg = 16;
1177 Handle(Geom_Curve) C1, C2, newCurve;
1178 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1179 Standard_Real first1, last1, first2, last2, fparam=0., lparam=0.;
1180 Standard_Boolean IsCanonic = Standard_False;
1182 C1 = BRep_Tool::Curve( E1, first1, last1 );
1183 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
1184 C1 = Handle(Geom_TrimmedCurve)::DownCast (C1)->BasisCurve();
1186 C2 = BRep_Tool::Curve( E2, first2, last2 );
1187 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
1188 C2 = Handle(Geom_TrimmedCurve)::DownCast (C2)->BasisCurve();
1193 fparam = Min( first1, first2 );
1194 lparam = Max( last1, last2 );
1196 else if (C1->DynamicType() == C2->DynamicType() &&
1197 (C1->IsInstance(STANDARD_TYPE(Geom_Line)) ||
1198 C1->IsKind(STANDARD_TYPE(Geom_Conic))))
1200 IsCanonic = Standard_True;
1205 Handle(Geom_TrimmedCurve) TC1 = new Geom_TrimmedCurve( C1, first1, last1 );
1206 Handle(Geom_TrimmedCurve) TC2 = new Geom_TrimmedCurve( C2, first2, last2 );
1207 GeomConvert_CompCurveToBSplineCurve Concat( TC1 );
1208 if (!Concat.Add( TC2, theGlueTol, After ))
1210 newCurve = Concat.BSplineCurve();
1211 if (newCurve->Continuity() < GeomAbs_C1)
1213 GeomConvert_ApproxCurve Approx3d( newCurve, Tol, Continuity, MaxSeg, MaxDeg );
1214 if (Approx3d.HasResult())
1215 newCurve = Approx3d.Curve();
1217 fparam = newCurve->FirstParameter();
1218 lparam = newCurve->LastParameter();
1224 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast );
1226 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast, fparam, lparam );
1228 Standard_Real newFirst, newLast;
1231 newPCurve = ConcatPCurves( E1, E2, F1, After, newFirst, newLast );
1232 BB.UpdateEdge( newEdge, newPCurve, F1, 0. );
1233 BB.Range( newEdge, F1, newFirst, newLast );
1237 newPCurve = ConcatPCurves( E1, E2, F2, After, newFirst, newLast );
1238 BB.UpdateEdge( newEdge, newPCurve, F2, 0. );
1239 BB.Range( newEdge, F2, newFirst, newLast );
1245 //=======================================================================
1246 //function : CheckIntersFF
1248 //=======================================================================
1250 static void CheckIntersFF(const BOPDS_PDS& pDS,
1251 const TopoDS_Edge& RefEdge,
1252 TopTools_IndexedMapOfShape& TrueEdges)
1254 BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF();
1255 Standard_Integer aNb = aFFs.Length();
1256 Standard_Integer i, j, nbe = 0;
1258 TopoDS_Compound Edges;
1260 BB.MakeCompound(Edges);
1262 for (i = 0; i < aNb; ++i)
1264 BOPDS_InterfFF& aFFi=aFFs(i);
1265 const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
1266 Standard_Integer aNbCurves = aBCurves.Length();
1268 for (j = 0; j < aNbCurves; ++j)
1270 const BOPDS_Curve& aBC=aBCurves(j);
1271 const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
1273 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1274 aPBIt.Initialize(aSectEdges);
1276 for (; aPBIt.More(); aPBIt.Next())
1278 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
1279 Standard_Integer nSect = aPB->Edge();
1280 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
1281 BB.Add(Edges, anEdge);
1290 TopTools_ListOfShape CompList;
1291 BOPTools_AlgoTools::MakeConnexityBlocks(Edges, TopAbs_VERTEX, TopAbs_EDGE, CompList);
1293 TopoDS_Shape NearestCompound;
1294 if (CompList.Extent() == 1)
1295 NearestCompound = CompList.First();
1298 BRepAdaptor_Curve BAcurve(RefEdge);
1299 gp_Pnt Pref = BAcurve.Value((BAcurve.FirstParameter()+BAcurve.LastParameter())/2);
1300 TopoDS_Vertex Vref = BRepLib_MakeVertex(Pref);
1301 Standard_Real MinDist = RealLast();
1302 TopTools_ListIteratorOfListOfShape itl(CompList);
1303 for (; itl.More(); itl.Next())
1305 const TopoDS_Shape& aCompound = itl.Value();
1307 BRepExtrema_DistShapeShape Projector(Vref, aCompound);
1308 if (!Projector.IsDone() || Projector.NbSolution() == 0)
1311 Standard_Real aDist = Projector.Value();
1312 if (aDist < MinDist)
1315 NearestCompound = aCompound;
1320 TopExp::MapShapes(NearestCompound, TopAbs_EDGE, TrueEdges);
1323 //=======================================================================
1324 //function : AssembleEdge
1326 //=======================================================================
1328 static TopoDS_Edge AssembleEdge(const BOPDS_PDS& pDS,
1329 const TopoDS_Face& F1,
1330 const TopoDS_Face& F2,
1331 const Standard_Boolean addPCurve1,
1332 const Standard_Boolean addPCurve2,
1333 const TopTools_SequenceOfShape& EdgesForConcat)
1335 TopoDS_Edge NullEdge;
1336 TopoDS_Edge CurEdge = TopoDS::Edge( EdgesForConcat(1) );
1337 Standard_Real aGlueTol = Precision::Confusion();
1339 for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
1341 TopoDS_Edge anEdge = TopoDS::Edge( EdgesForConcat(j) );
1342 Standard_Boolean After = Standard_False;
1343 TopoDS_Vertex Vfirst, Vlast;
1344 Standard_Boolean AreClosedWire = AreClosed( CurEdge, anEdge );
1347 TopoDS_Vertex V1, V2;
1348 TopExp::Vertices( CurEdge, V1, V2 );
1349 Standard_Boolean IsAutonomV1 = IsAutonomVertex( V1, pDS, F1, F2 );
1350 Standard_Boolean IsAutonomV2 = IsAutonomVertex( V2, pDS, F1, F2 );
1353 After = Standard_False;
1354 Vfirst = Vlast = V2;
1356 else if (IsAutonomV2)
1358 After = Standard_True;
1359 Vfirst = Vlast = V1;
1366 TopoDS_Vertex CV, V11, V12, V21, V22;
1367 TopExp::CommonVertex( CurEdge, anEdge, CV );
1368 Standard_Boolean IsAutonomCV = IsAutonomVertex( CV, pDS, F1, F2 );
1371 aGlueTol = BRep_Tool::Tolerance(CV);
1372 TopExp::Vertices( CurEdge, V11, V12 );
1373 TopExp::Vertices( anEdge, V21, V22 );
1374 if (V11.IsSame(CV) && V21.IsSame(CV))
1379 else if (V11.IsSame(CV) && V22.IsSame(CV))
1384 else if (V12.IsSame(CV) && V21.IsSame(CV))
1397 } //end of else (open wire)
1399 TopoDS_Edge NewEdge = Glue(CurEdge, anEdge, Vfirst, Vlast, After,
1400 F1, addPCurve1, F2, addPCurve2, aGlueTol);
1401 if (NewEdge.IsNull())
1405 } //end of for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
1410 //=======================================================================
1411 //function : Inter3D
1413 //=======================================================================
1415 void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1,
1416 const TopoDS_Face& F2,
1417 TopTools_ListOfShape& L1,
1418 TopTools_ListOfShape& L2,
1419 const TopAbs_State Side,
1420 const TopoDS_Edge& RefEdge,
1421 const Standard_Boolean IsRefEdgeDefined)
1426 sprintf(name,"FF_%d",NbFaces++);
1427 DBRep::Set(name,F1);
1428 sprintf(name,"FF_%d",NbFaces++);
1429 DBRep::Set(name,F2);
1433 // Check if the faces are planar and not trimmed - in this case
1434 // the IntTools_FaceFace intersection algorithm will be used directly.
1435 BRepAdaptor_Surface aBAS1(F1, Standard_False), aBAS2(F2, Standard_False);
1436 if (aBAS1.GetType() == GeomAbs_Plane &&
1437 aBAS2.GetType() == GeomAbs_Plane) {
1438 aBAS1.Initialize(F1, Standard_True);
1439 if (IsInf(aBAS1.LastUParameter()) && IsInf(aBAS1.LastVParameter())) {
1440 aBAS2.Initialize(F2, Standard_True);
1441 if (IsInf(aBAS2.LastUParameter()) && IsInf(aBAS2.LastVParameter())) {
1442 // Intersect the planes without pave filler
1443 PerformPlanes(F1, F2, Side, L1, L2);
1449 // create 3D curves on faces
1450 BRepLib::BuildCurves3d(F1);
1451 BRepLib::BuildCurves3d(F2);
1452 UpdateVertexTolerances(F1);
1453 UpdateVertexTolerances(F2);
1455 BOPAlgo_PaveFiller aPF;
1456 TopTools_ListOfShape aLS;
1459 aPF.SetArguments(aLS);
1463 TopTools_IndexedMapOfShape TrueEdges;
1464 if (IsRefEdgeDefined)
1465 CheckIntersFF( aPF.PDS(), RefEdge, TrueEdges );
1467 Standard_Boolean addPCurve1 = 1;
1468 Standard_Boolean addPCurve2 = 1;
1470 const BOPDS_PDS& pDS = aPF.PDS();
1471 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
1472 Standard_Integer aNb = aFFs.Length();
1473 Standard_Integer i = 0, j = 0, k;
1475 L1.Clear(); L2.Clear();
1476 TopAbs_Orientation O1,O2;
1479 const Handle(IntTools_Context)& aContext = aPF.Context();
1481 for (i = 0; i < aNb; i++) {
1482 BOPDS_InterfFF& aFFi=aFFs(i);
1483 const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
1485 Standard_Integer aNbCurves = aBCurves.Length();
1487 for (j = 0; j < aNbCurves; j++) {
1488 const BOPDS_Curve& aBC=aBCurves(j);
1489 const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
1491 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1492 aPBIt.Initialize(aSectEdges);
1494 for (; aPBIt.More(); aPBIt.Next()) {
1495 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
1496 Standard_Integer nSect = aPB->Edge();
1497 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
1498 if (!TrueEdges.IsEmpty() && !TrueEdges.Contains(anEdge))
1502 const Handle(Geom_Curve)& aC3DE = BRep_Tool::Curve(anEdge, f, l);
1503 Handle(Geom_TrimmedCurve) aC3DETrim;
1506 aC3DETrim = new Geom_TrimmedCurve(aC3DE, f, l);
1508 Standard_Real aTolEdge = BRep_Tool::Tolerance(anEdge);
1510 if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F1)) {
1511 Handle(Geom2d_Curve) aC2d = aBC.Curve().FirstCurve2d();
1512 if(!aC3DETrim.IsNull()) {
1513 Handle(Geom2d_Curve) aC2dNew;
1515 if(aC3DE->IsPeriodic()) {
1516 BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, f, l, aC2d, aC2dNew, aContext);
1519 BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, aC3DETrim, aC2d, aC2dNew, aContext);
1523 BB.UpdateEdge(anEdge, aC2d, F1, aTolEdge);
1526 if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F2)) {
1527 Handle(Geom2d_Curve) aC2d = aBC.Curve().SecondCurve2d();
1528 if(!aC3DETrim.IsNull()) {
1529 Handle(Geom2d_Curve) aC2dNew;
1531 if(aC3DE->IsPeriodic()) {
1532 BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, f, l, aC2d, aC2dNew, aContext);
1535 BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, aC3DETrim, aC2d, aC2dNew, aContext);
1539 BB.UpdateEdge(anEdge, aC2d, F2, aTolEdge);
1542 OrientSection (anEdge, F1, F2, O1, O2);
1543 if (Side == TopAbs_OUT) {
1544 O1 = TopAbs::Reverse(O1);
1545 O2 = TopAbs::Reverse(O2);
1548 L1.Append (anEdge.Oriented(O1));
1549 L2.Append (anEdge.Oriented(O2));
1554 sprintf(name,"EI_%d",NbNewEdges++);
1555 DBRep::Set(name,anEdge.Oriented(O1));
1563 Standard_Real aSameParTol = Precision::Confusion();
1564 Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
1566 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F1);
1567 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1568 aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
1569 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1570 addPCurve1 = Standard_False;
1571 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1572 isEl1 = Standard_True;
1574 aSurf = BRep_Tool::Surface(F2);
1575 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1576 aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
1577 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1578 addPCurve2 = Standard_False;
1579 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1580 isEl2 = Standard_True;
1582 if (L1.Extent() > 1 && (!isEl1 || !isEl2)) {
1583 TopTools_SequenceOfShape eseq;
1584 TopTools_SequenceOfShape EdgesForConcat;
1586 if (!TrueEdges.IsEmpty())
1588 for (i = TrueEdges.Extent(); i >= 1; i--)
1589 EdgesForConcat.Append( TrueEdges(i) );
1590 TopoDS_Edge AssembledEdge =
1591 AssembleEdge( pDS, F1, F2, addPCurve1, addPCurve2, EdgesForConcat );
1592 if (AssembledEdge.IsNull())
1593 for (i = TrueEdges.Extent(); i >= 1; i--)
1594 eseq.Append( TrueEdges(i) );
1596 eseq.Append(AssembledEdge);
1600 TopTools_SequenceOfShape wseq;
1601 TopTools_SequenceOfShape edges;
1602 TopTools_ListIteratorOfListOfShape itl(L1);
1603 for (; itl.More(); itl.Next())
1604 edges.Append( itl.Value() );
1605 while (!edges.IsEmpty())
1607 TopoDS_Edge anEdge = TopoDS::Edge( edges.First() );
1608 TopoDS_Wire aWire, resWire;
1610 BB.Add( aWire, anEdge );
1611 TColStd_SequenceOfInteger Candidates;
1612 for (k = 1; k <= wseq.Length(); k++)
1614 resWire = TopoDS::Wire(wseq(k));
1615 if (AreConnex( resWire, aWire ))
1617 Candidates.Append( 1 );
1621 if (Candidates.IsEmpty())
1623 wseq.Append( aWire );
1628 for (j = 2; j <= edges.Length(); j++)
1630 anEdge = TopoDS::Edge( edges(j) );
1633 BB.Add( aWire, anEdge );
1634 if (AreConnex( resWire, aWire ))
1635 Candidates.Append( j );
1637 Standard_Integer minind = 1;
1638 if (Candidates.Length() > 1)
1640 Standard_Real MinAngle = RealLast();
1641 for (j = 1; j <= Candidates.Length(); j++)
1643 anEdge = TopoDS::Edge( edges(Candidates(j)) );
1644 Standard_Real anAngle = AngleWireEdge( resWire, anEdge );
1645 if (anAngle < MinAngle)
1652 BB.Add( resWire, TopoDS::Edge(edges(Candidates(minind))) );
1654 edges.Remove(Candidates(minind));
1656 } //end of while (!edges.IsEmpty())
1658 for (i = 1; i <= wseq.Length(); i++)
1660 TopoDS_Wire aWire = TopoDS::Wire(wseq(i));
1661 TopTools_SequenceOfShape aLocalEdgesForConcat;
1664 TopoDS_Vertex StartVertex;
1665 TopoDS_Edge StartEdge;
1666 Standard_Boolean StartFound = Standard_False;
1667 TopTools_ListOfShape Elist;
1669 TopoDS_Iterator itw(aWire);
1670 for (; itw.More(); itw.Next())
1672 TopoDS_Edge anEdge = TopoDS::Edge(itw.Value());
1674 Elist.Append(anEdge);
1677 TopoDS_Vertex V1, V2;
1678 TopExp::Vertices( anEdge, V1, V2 );
1679 if (!IsAutonomVertex( V1, pDS ))
1683 StartFound = Standard_True;
1685 else if (!IsAutonomVertex( V2, pDS ))
1689 StartFound = Standard_True;
1692 Elist.Append(anEdge);
1694 } //end of for (; itw.More(); itw.Next())
1697 itl.Initialize(Elist);
1698 StartEdge = TopoDS::Edge(itl.Value());
1700 TopoDS_Vertex V1, V2;
1701 TopExp::Vertices( StartEdge, V1, V2 );
1704 aLocalEdgesForConcat.Append( StartEdge );
1705 while (!Elist.IsEmpty())
1707 for (itl.Initialize(Elist); itl.More(); itl.Next())
1709 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
1710 TopoDS_Vertex V1, V2;
1711 TopExp::Vertices( anEdge, V1, V2 );
1712 if (V1.IsSame(StartVertex))
1715 aLocalEdgesForConcat.Append( anEdge );
1719 else if (V2.IsSame(StartVertex))
1722 aLocalEdgesForConcat.Append( anEdge );
1727 } //end of while (!Elist.IsEmpty())
1728 } //end of if (aWire.Closed())
1731 BRepTools_WireExplorer Wexp( aWire );
1732 for (; Wexp.More(); Wexp.Next())
1733 aLocalEdgesForConcat.Append( Wexp.Current() );
1736 TopoDS_Edge AssembledEdge =
1737 AssembleEdge( pDS, F1, F2, addPCurve1, addPCurve2, aLocalEdgesForConcat );
1738 if (AssembledEdge.IsNull())
1739 for (j = aLocalEdgesForConcat.Length(); j >= 1; j--)
1740 eseq.Append( aLocalEdgesForConcat(j) );
1742 eseq.Append( AssembledEdge );
1744 } //end of else (when TrueEdges is empty)
1746 if (eseq.Length() < L1.Extent())
1750 for (i = 1; i <= eseq.Length(); i++)
1752 TopoDS_Shape aShape = eseq(i);
1753 TopoDS_Edge anEdge = TopoDS::Edge(eseq(i));
1754 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1755 Standard_Real EdgeTol = BRep_Tool::Tolerance(anEdge);
1757 cout<<"Tolerance of glued E = "<<EdgeTol<<endl;
1759 if (EdgeTol > 1.e-2)
1762 if (EdgeTol >= 1.e-4)
1764 ReconstructPCurves(anEdge);
1765 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1767 cout<<"After projection tol of E = "<<BRep_Tool::Tolerance(anEdge)<<endl;
1771 OrientSection( anEdge, F1, F2, O1, O2 );
1772 if (Side == TopAbs_OUT)
1774 O1 = TopAbs::Reverse(O1);
1775 O2 = TopAbs::Reverse(O2);
1778 L1.Append( anEdge.Oriented(O1) );
1779 L2.Append( anEdge.Oriented(O2) );
1782 } //end of if (L1.Extent() > 1)
1786 TopTools_ListIteratorOfListOfShape itl(L1);
1787 for (; itl.More(); itl.Next())
1789 const TopoDS_Edge& anEdge = TopoDS::Edge( itl.Value() );
1790 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1795 //=======================================================================
1796 //function : TryProject
1798 //=======================================================================
1800 Standard_Boolean BRepOffset_Tool::TryProject
1801 (const TopoDS_Face& F1,
1802 const TopoDS_Face& F2,
1803 const TopTools_ListOfShape& Edges,
1804 TopTools_ListOfShape& LInt1,
1805 TopTools_ListOfShape& LInt2,
1806 const TopAbs_State Side,
1807 const Standard_Real TolConf)
1812 sprintf(name,"FF_%d",NbFaces++);
1813 DBRep::Set(name,F1);
1814 sprintf(name,"FF_%d",NbFaces++);
1815 DBRep::Set(name,F2);
1819 // try to find if the edges <Edges> are laying on the face F1.
1820 LInt1.Clear(); LInt2.Clear();
1821 TopTools_ListIteratorOfListOfShape it(Edges);
1822 Standard_Boolean isOk = Standard_True;
1823 Standard_Boolean Ok = Standard_True;
1824 TopAbs_Orientation O1,O2;
1825 Handle(Geom_Surface) Bouchon = BRep_Tool::Surface(F1);
1828 for ( ; it.More(); it.Next()) {
1831 TopoDS_Edge CurE = TopoDS::Edge(it.Value());
1832 Handle(Geom_Curve) C = BRep_Tool::Curve(CurE,L,f,l);
1834 BRepLib::BuildCurve3d(CurE,BRep_Tool::Tolerance(CurE));
1835 C = BRep_Tool::Curve(CurE,L,f,l);
1837 C = new Geom_TrimmedCurve(C,f,l);
1838 if ( !L.IsIdentity()) C->Transform(L);
1839 Standard_Real TolReached;
1840 isOk = IsOnSurface(C,Bouchon,TolConf,TolReached);
1843 B.UpdateEdge(CurE,TolReached);
1844 BuildPCurves(CurE,F1);
1845 OrientSection (CurE,F1,F2,O1,O2);
1846 if (Side == TopAbs_OUT) {
1847 O1 = TopAbs::Reverse(O1);
1848 O2 = TopAbs::Reverse(O2);
1850 LInt1.Append (CurE.Oriented(O1));
1851 LInt2.Append (CurE.Oriented(O2));
1855 sprintf(name,"EI_%d",NbNewEdges++);
1856 DBRep::Set(name,CurE.Oriented(O1));
1861 Ok = Standard_False;
1867 //=======================================================================
1868 //function : InterOrExtent
1870 //=======================================================================
1872 void BRepOffset_Tool::InterOrExtent(const TopoDS_Face& F1,
1873 const TopoDS_Face& F2,
1874 TopTools_ListOfShape& L1,
1875 TopTools_ListOfShape& L2,
1876 const TopAbs_State Side)
1881 sprintf(name,"FF_%d",NbFaces++);
1882 DBRep::Set(name,F1);
1883 sprintf(name,"FF_%d",NbFaces++);
1884 DBRep::Set(name,F2);
1888 Handle (Geom_Curve) CI;
1889 TopAbs_Orientation O1,O2;
1890 L1.Clear(); L2.Clear();
1891 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
1892 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
1894 if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1895 Handle(Geom_RectangularTrimmedSurface) RTS ;
1896 RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S1);
1897 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
1898 S1 = RTS->BasisSurface();
1901 if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1902 Handle(Geom_RectangularTrimmedSurface) RTS ;
1903 RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S2);
1904 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
1905 S2 = RTS->BasisSurface();
1909 GeomInt_IntSS Inter (S1,S2, Precision::Confusion());
1911 if (Inter.IsDone()) {
1912 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
1915 if (ToSmall(CI)) continue;
1916 TopoDS_Edge E = BRepLib_MakeEdge(CI);
1917 BuildPCurves (E,F1);
1918 BuildPCurves (E,F2);
1919 OrientSection (E,F1,F2,O1,O2);
1920 if (Side == TopAbs_OUT) {
1921 O1 = TopAbs::Reverse(O1);
1922 O2 = TopAbs::Reverse(O2);
1924 L1.Append (E.Oriented(O1));
1925 L2.Append (E.Oriented(O2));
1929 sprintf(name,"EI_%d",NbNewEdges++);
1930 DBRep::Set(name,E.Oriented(O1));
1937 //=======================================================================
1938 //function : ExtentEdge
1940 //=======================================================================
1942 static void ExtentEdge(const TopoDS_Face& F,
1943 const TopoDS_Face& EF,
1944 const TopoDS_Edge& E,
1947 BRepAdaptor_Curve CE(E);
1948 GeomAbs_CurveType Type = CE.GetType();
1949 TopoDS_Shape aLocalEdge = E.EmptyCopied();
1950 NE = TopoDS::Edge(aLocalEdge);
1951 // NE = TopoDS::Edge(E.EmptyCopied());
1953 if (Type == GeomAbs_Line || Type == GeomAbs_Circle || Type == GeomAbs_Ellipse ||
1954 Type == GeomAbs_Hyperbola || Type == GeomAbs_Parabola) {
1957 // Extension en tangence jusqu'au bord de la surface.
1958 Standard_Real PMax = 1.e2;
1960 Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
1961 Standard_Real umin,umax,vmin,vmax;
1963 S->Bounds(umin,umax,vmin,vmax);
1964 umin = Max(umin,-PMax);vmin = Max(vmin,-PMax);
1965 umax = Min(umax, PMax);vmax = Min(vmax, PMax);
1969 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f,l);
1971 //calcul point cible . ie point d'intersection du prolongement tangent et des bords.
1974 C2d->D1(CE.FirstParameter(),P,Tang);
1975 Standard_Real tx,ty,tmin;
1976 tx = ty = Precision::Infinite();
1977 if (Abs(Tang.X()) > Precision::Confusion())
1978 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
1979 if (Abs(Tang.Y()) > Precision::Confusion())
1980 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
1983 gp_Pnt2d PF2d (P.X() - Tang.X(),P.Y() - Tang.Y());
1985 C2d->D1(CE.LastParameter(),P,Tang);
1986 tx = ty = Precision::Infinite();
1987 if (Abs(Tang.X()) > Precision::Confusion())
1988 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
1989 if (Abs(Tang.Y()) > Precision::Confusion())
1990 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
1993 gp_Pnt2d PL2d (P.X() + Tang.X(),P.Y() + Tang.Y());
1995 Handle(Geom_Curve) CC = GeomAPI::To3d(C2d,gp_Pln(gp::XOY()));
1996 gp_Pnt PF(PF2d.X(),PF2d.Y(),0.);
1997 gp_Pnt PL(PL2d.X(),PL2d.Y(),0.);
1999 Handle(Geom_BoundedCurve) ExtC = Handle(Geom_BoundedCurve)::DownCast(CC);
2000 if (ExtC.IsNull()) return;
2002 GeomLib::ExtendCurveToPoint(ExtC,PF,1,0);
2003 GeomLib::ExtendCurveToPoint(ExtC,PL,1,1);
2005 Handle(Geom2d_Curve) CNE2d = GeomAPI::To2d(ExtC,gp_Pln(gp::XOY()));
2007 //Construction de la nouvelle arrete;
2010 // B.UpdateEdge (NE,CNE2d,F,BRep_Tool::Tolerance(E));
2011 B.UpdateEdge (NE,CNE2d,EF,BRep_Tool::Tolerance(E));
2012 B.Range (NE,CNE2d->FirstParameter(), CNE2d->LastParameter());
2013 NE.Orientation(E.Orientation());
2017 sprintf (name,"F_%d",NbExtE);
2018 DBRep::Set(name,EF);
2019 sprintf (name,"OE_%d",NbExtE);
2020 DBRep::Set (name,E);
2021 sprintf (name,"ExtE_%d",NbExtE++);
2022 DBRep::Set(name,NE);
2027 //=======================================================================
2028 //function : ProjectVertexOnEdge
2030 //=======================================================================
2032 static Standard_Boolean ProjectVertexOnEdge(TopoDS_Vertex& V,
2033 const TopoDS_Edge& E,
2034 Standard_Real TolConf)
2044 Standard_Real U = 0.;
2046 Standard_Boolean found = Standard_False;
2048 gp_Pnt P = BRep_Tool::Pnt (V);
2049 BRepAdaptor_Curve C = BRepAdaptor_Curve(E);
2050 f = C.FirstParameter(); l = C.LastParameter();
2052 if (V.Orientation() == TopAbs_FORWARD) {
2053 if (Abs(f) < Precision::Infinite()) {
2054 gp_Pnt PF = C.Value (f);
2055 if (PF.IsEqual(P,TolConf)) {
2057 found = Standard_True;
2061 if (V.Orientation() == TopAbs_REVERSED) {
2062 if (!found && Abs(l) < Precision::Infinite()) {
2063 gp_Pnt PL = C.Value (l);
2064 if (PL.IsEqual(P,TolConf)) {
2066 found = Standard_True;
2071 Extrema_ExtPC Proj(P,C);
2072 if (Proj.IsDone() && Proj.NbExt() > 0) {
2073 Standard_Real Dist2,Dist2Min = Proj.SquareDistance(1);
2074 U = Proj.Point(1).Parameter();
2075 for (Standard_Integer i = 2; i <= Proj.NbExt(); i++) {
2076 Dist2 = Proj.SquareDistance(i);
2077 if (Dist2 < Dist2Min) {
2079 U = Proj.Point(i).Parameter();
2082 found = Standard_True;
2088 Standard_Real Dist = P.Distance(C.Value(U));
2089 if (Dist > TolConf) {
2090 cout << " ProjectVertexOnEdge :distance vertex edge :"<<Dist<<endl;
2092 if (U < f - Precision::Confusion() ||
2093 U > l + Precision::Confusion()) {
2094 cout << " ProjectVertexOnEdge : hors borne :"<<endl;
2095 cout << " f = "<<f<<" l ="<<l<< " U ="<<U<<endl;
2099 cout <<"BRepOffset_Tool::ProjectVertexOnEdge Parameter no found"<<endl;
2100 if (Abs(f) < Precision::Infinite() &&
2101 Abs(l) < Precision::Infinite()) {
2109 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
2110 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
2111 aLocalShape = V.Oriented(TopAbs_INTERNAL);
2112 // TopoDS_Edge EE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
2113 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
2114 U,EE,BRep_Tool::Tolerance(E));
2120 //=======================================================================
2121 //function : Inter2d
2123 //=======================================================================
2125 void BRepOffset_Tool::Inter2d (const TopoDS_Face& F,
2126 const TopoDS_Edge& E1,
2127 const TopoDS_Edge& E2,
2128 TopTools_ListOfShape& LV,
2129 const Standard_Real TolConf)
2133 DBRep::Set("E1",E1);
2134 DBRep::Set("E2",E2);
2139 Standard_Real fl1[2],fl2[2];
2142 // Si l edge a ete etendu les pcurves ne sont pas forcement
2148 // Construction des curves 3d si elles n existent pas
2149 // utile pour coder correctement les parametres des vertex
2150 // d intersection sur les edges.
2151 //TopLoc_Location L;
2152 //Standard_Real f,l;
2153 //Handle(Geom_Curve) C3d1 = BRep_Tool::Curve(E1,L,f,l);
2154 //if (C3d1.IsNull()) {
2155 // BRepLib::BuildCurve3d(E1,BRep_Tool::Tolerance(E1));
2157 //Handle(Geom_Curve) C3d2 = BRep_Tool::Curve(E2,L,f,l);
2158 //if (C3d2.IsNull()) {
2159 // BRepLib::BuildCurve3d(E2,BRep_Tool::Tolerance(E2));
2162 Standard_Integer NbPC1 = 1, NbPC2 = 1;
2163 if (BRep_Tool::IsClosed(E1,F)) NbPC1++;
2164 if (BRep_Tool::IsClosed(E2,F)) NbPC2++;
2166 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
2167 Handle(Geom2d_Curve) C1, C2;
2168 Standard_Boolean YaSol = Standard_False;
2169 Standard_Integer itry = 0;
2171 while (!YaSol && itry < 2) {
2172 for ( Standard_Integer i = 1; i <= NbPC1 ; i++) {
2173 TopoDS_Shape aLocalEdgeReversedE1 = E1.Reversed();
2174 if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
2175 else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdgeReversedE1),
2177 // if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
2178 // else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E1.Reversed()),
2179 // F,fl1[0],fl1[1]);
2180 for ( Standard_Integer j = 1; j <= NbPC2; j++ ) {
2181 TopoDS_Shape aLocalEdge = E2.Reversed();
2182 if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2183 else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdge),
2185 // if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2186 // else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E2.Reversed()),
2187 // F,fl2[0],fl2[1]);
2189 if (C1.IsNull() || C2.IsNull()) {
2190 cout <<"Inter2d : Pas de pcurve"<<endl;
2192 DBRep::Set("E1",E1);
2193 DBRep::Set("E2",E2);
2199 Standard_Real U1 = 0.,U2 = 0.;
2201 Standard_Boolean aCurrentFind = Standard_False;
2203 fl1[0] = C1->FirstParameter(); fl1[1] = C1->LastParameter();
2204 fl2[0] = C2->FirstParameter(); fl2[1] = C2->LastParameter();
2206 Geom2dAdaptor_Curve AC1(C1,fl1[0],fl1[1]);
2207 Geom2dAdaptor_Curve AC2(C2,fl2[0],fl2[1]);
2210 gp_Pnt2d P1[2],P2[2];
2211 P1[0] = C1->Value(fl1[0]); P1[1] = C1->Value(fl1[1]);
2212 P2[0] = C2->Value(fl2[0]); P2[1] = C2->Value(fl2[1]);
2214 Standard_Integer i1 ;
2215 for ( i1 = 0; i1 < 2; i1++) {
2216 for (Standard_Integer i2 = 0; i2 < 2; i2++) {
2217 if (Abs(fl1[i1]) < Precision::Infinite() &&
2218 Abs(fl2[i2]) < Precision::Infinite() ) {
2219 if (P1[i1].IsEqual(P2[i2],TolConf)) {
2220 YaSol = Standard_True;
2221 aCurrentFind = Standard_True;
2222 U1 = fl1[i1]; U2 = fl2[i2];
2223 P2d = C1->Value(U1);
2229 for (i1 = 0; i1 < 2; i1++)
2231 Extrema_ExtPC2d extr( P1[i1], AC2 );
2232 if (extr.IsDone() && extr.NbExt() > 0)
2234 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2235 Standard_Integer IndexMin = 1;
2236 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2238 Dist2 = extr.SquareDistance(ind);
2239 if (Dist2 < Dist2Min)
2245 if (Dist2Min <= Precision::SquareConfusion())
2247 YaSol = Standard_True;
2248 aCurrentFind = Standard_True;
2251 U2 = (extr.Point(IndexMin)).Parameter();
2257 for (Standard_Integer i2 = 0; i2 < 2; i2++)
2259 Extrema_ExtPC2d extr( P2[i2], AC1 );
2260 if (extr.IsDone() && extr.NbExt() > 0)
2262 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2263 Standard_Integer IndexMin = 1;
2264 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2266 Dist2 = extr.SquareDistance(ind);
2267 if (Dist2 < Dist2Min)
2273 if (Dist2Min <= Precision::SquareConfusion())
2275 YaSol = Standard_True;
2276 aCurrentFind = Standard_True;
2279 U1 = (extr.Point(IndexMin)).Parameter();
2287 Geom2dInt_GInter Inter (AC1,AC2,TolConf,TolConf);
2289 if (!Inter.IsEmpty() && Inter.NbPoints() > 0) {
2290 YaSol = Standard_True;
2291 aCurrentFind = Standard_True;
2292 U1 = Inter.Point(1).ParamOnFirst();
2293 U2 = Inter.Point(1).ParamOnSecond();
2294 P2d = Inter.Point(1).Value();
2296 else if (!Inter.IsEmpty() && Inter.NbSegments() > 0) {
2297 YaSol = Standard_True;
2298 aCurrentFind = Standard_True;
2299 IntRes2d_IntersectionSegment Seg = Inter.Segment(1);
2300 IntRes2d_IntersectionPoint IntP1 = Seg.FirstPoint();
2301 IntRes2d_IntersectionPoint IntP2 = Seg.LastPoint();
2302 Standard_Real U1on1 = IntP1.ParamOnFirst();
2303 Standard_Real U1on2 = IntP2.ParamOnFirst();
2304 Standard_Real U2on1 = IntP1.ParamOnSecond();
2305 Standard_Real U2on2 = IntP2.ParamOnSecond();
2307 cout << " BRepOffset_Tool::Inter2d SEGMENT d intersection" << endl;
2308 cout << " ===> Parametres sur Curve1 : ";
2309 cout << U1on1 << " " << U1on2 << endl;
2310 cout << " ===> Parametres sur Curve2 : ";
2311 cout << U2on1 << " " << U2on2 << endl;
2313 U1 = (U1on1 + U1on2)/2.;
2314 U2 = (U2on1 + U2on2)/2.;
2315 gp_Pnt2d P2d1 = C1->Value(U1);
2316 gp_Pnt2d P2d2 = C2->Value(U2);
2317 P2d.SetX( (P2d1.X() + P2d2.X()) / 2.);
2318 P2d.SetY( (P2d1.Y() + P2d2.Y()) / 2.);
2322 gp_Pnt P = S->Value(P2d.X(),P2d.Y());
2323 TopoDS_Vertex V = BRepLib_MakeVertex(P);
2324 V.Orientation(TopAbs_INTERNAL);
2325 TopoDS_Shape aLocalEdgeOrientedE1 = E1.Oriented(TopAbs_FORWARD);
2326 B.UpdateVertex(V,U1,TopoDS::Edge(aLocalEdgeOrientedE1),TolConf);
2327 aLocalEdgeOrientedE1 = E2.Oriented(TopAbs_FORWARD);
2328 B.UpdateVertex(V,U2,TopoDS::Edge(aLocalEdgeOrientedE1),TolConf);
2329 // B.UpdateVertex(V,U1,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)),TolConf);
2330 // B.UpdateVertex(V,U2,TopoDS::Edge(E2.Oriented(TopAbs_FORWARD)),TolConf);
2338 if (LV.Extent() > 1) {
2339 //------------------------------------------------
2340 // garde seulement les vertex les plus proches du
2341 //debut et de la fin.
2342 //------------------------------------------------
2343 TopTools_ListIteratorOfListOfShape it(LV);
2344 TopoDS_Vertex VF,VL;
2345 Standard_Real UMin = Precision::Infinite();
2346 Standard_Real UMax = -Precision::Infinite();
2349 for ( ; it.More(); it.Next()) {
2350 TopoDS_Vertex CV = TopoDS::Vertex(it.Value());
2351 TopoDS_Shape aLocalEdge = E1.Oriented(TopAbs_FORWARD);
2352 U = BRep_Tool::Parameter(CV,TopoDS::Edge(aLocalEdge));
2353 // U = BRep_Tool::Parameter(CV,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)));
2361 LV.Clear();LV.Append(VF); LV.Append(VL);
2366 cout <<"Inter2d : Pas de solution"<<endl;
2368 DBRep::Set("E1",E1);
2369 DBRep::Set("E2",E2);
2376 //=======================================================================
2377 //function : SelectEdge
2379 //=======================================================================
2381 static void SelectEdge (const TopoDS_Face& /*F*/,
2382 const TopoDS_Face& /*EF*/,
2383 const TopoDS_Edge& E,
2384 TopTools_ListOfShape& LInt)
2386 //------------------------------------------------------------
2387 // detrompeur sur les intersections sur les faces periodiques
2388 //------------------------------------------------------------
2389 TopTools_ListIteratorOfListOfShape it(LInt);
2390 Standard_Real dU = 1.0e100;
2393 Standard_Real Fst, Lst, tmp;
2394 BRep_Tool::Range(E, Fst, Lst);
2395 BRepAdaptor_Curve Ad1(E);
2397 gp_Pnt PFirst = Ad1.Value( Fst );
2398 gp_Pnt PLast = Ad1.Value( Lst );
2400 //----------------------------------------------------------------------
2401 // Selection de l edge qui couvre le plus le domaine de l edge initiale.
2402 //----------------------------------------------------------------------
2403 for (; it.More(); it.Next()) {
2404 const TopoDS_Edge& EI = TopoDS::Edge(it.Value());
2406 BRep_Tool::Range(EI, Fst, Lst);
2407 BRepAdaptor_Curve Ad2(EI);
2408 gp_Pnt P1 = Ad2.Value(Fst);
2409 gp_Pnt P2 = Ad2.Value(Lst);
2411 tmp = P1.Distance(PFirst) + P2.Distance(PLast);
2423 //=======================================================================
2426 //=======================================================================
2428 static void MakeFace(const Handle(Geom_Surface)& S,
2429 const Standard_Real Um,
2430 const Standard_Real UM,
2431 const Standard_Real Vm,
2432 const Standard_Real VM,
2433 const Standard_Boolean uclosed,
2434 const Standard_Boolean vclosed,
2435 const Standard_Boolean isVminDegen,
2436 const Standard_Boolean isVmaxDegen,
2439 Standard_Real UMin = Um;
2440 Standard_Real UMax = UM;
2441 Standard_Real VMin = Vm;
2442 Standard_Real VMax = VM;
2444 // compute infinite flags
2445 Standard_Boolean umininf = Precision::IsNegativeInfinite(UMin);
2446 Standard_Boolean umaxinf = Precision::IsPositiveInfinite(UMax);
2447 Standard_Boolean vmininf = Precision::IsNegativeInfinite(VMin);
2448 Standard_Boolean vmaxinf = Precision::IsPositiveInfinite(VMax);
2450 // degenerated flags (for cones)
2451 Standard_Boolean vmindegen = isVminDegen, vmaxdegen = isVmaxDegen;
2452 Handle(Geom_Surface) theSurf = S;
2453 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
2454 theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
2455 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
2457 Handle(Geom_ConicalSurface) ConicalS = Handle(Geom_ConicalSurface)::DownCast (theSurf);
2458 gp_Cone theCone = ConicalS->Cone();
2459 gp_Pnt theApex = theCone.Apex();
2460 Standard_Real Uapex, Vapex;
2461 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
2462 if (Abs(VMin - Vapex) <= Precision::Confusion())
2463 vmindegen = Standard_True;
2464 if (Abs(VMax - Vapex) <= Precision::Confusion())
2465 vmaxdegen = Standard_True;
2470 Standard_Real tol = Precision::Confusion();
2472 TopoDS_Vertex V00,V10,V11,V01;
2475 if (!vmininf) B.MakeVertex(V00,S->Value(UMin,VMin),tol);
2476 if (!vmaxinf) B.MakeVertex(V01,S->Value(UMin,VMax),tol);
2479 if (!vmininf) B.MakeVertex(V10,S->Value(UMax,VMin),tol);
2480 if (!vmaxinf) B.MakeVertex(V11,S->Value(UMax,VMax),tol);
2499 Handle(Geom2d_Line) Lumin,Lumax,Lvmin,Lvmax;
2501 Lumin = new Geom2d_Line(gp_Pnt2d(UMin,0),gp_Dir2d(0,1));
2503 Lumax = new Geom2d_Line(gp_Pnt2d(UMax,0),gp_Dir2d(0,1));
2505 Lvmin = new Geom2d_Line(gp_Pnt2d(0,VMin),gp_Dir2d(1,0));
2507 Lvmax = new Geom2d_Line(gp_Pnt2d(0,VMax),gp_Dir2d(1,0));
2509 Handle(Geom_Curve) Cumin,Cumax,Cvmin,Cvmax;
2510 Standard_Real TolApex = 1.e-5;
2511 //Standard_Boolean hasiso = ! S->IsKind(STANDARD_TYPE(Geom_OffsetSurface));
2512 Standard_Boolean hasiso = S->IsKind(STANDARD_TYPE(Geom_ElementarySurface));
2515 Cumin = S->UIso(UMin);
2517 Cumax = S->UIso(UMax);
2520 Cvmin = S->VIso(VMin);
2521 if (BRepOffset_Tool::Gabarit( Cvmin ) <= TolApex)
2522 vmindegen = Standard_True;
2526 Cvmax = S->VIso(VMax);
2527 if (BRepOffset_Tool::Gabarit( Cvmax ) <= TolApex)
2528 vmaxdegen = Standard_True;
2533 B.MakeFace(F,S,tol);
2536 TopoDS_Edge eumin,eumax,evmin,evmax;
2540 B.MakeEdge(eumin,Cumin,tol);
2544 B.UpdateEdge(eumin,Lumax,Lumin,F,tol);
2546 B.UpdateEdge(eumin,Lumin,F,tol);
2548 V00.Orientation(TopAbs_FORWARD);
2552 V01.Orientation(TopAbs_REVERSED);
2555 B.Range(eumin,VMin,VMax);
2563 B.MakeEdge(eumax,Cumax,tol);
2566 B.UpdateEdge(eumax,Lumax,F,tol);
2568 V10.Orientation(TopAbs_FORWARD);
2572 V11.Orientation(TopAbs_REVERSED);
2575 B.Range(eumax,VMin,VMax);
2580 if (hasiso && !vmindegen)
2581 B.MakeEdge(evmin,Cvmin,tol);
2585 B.UpdateEdge(evmin,Lvmin,Lvmax,F,tol);
2587 B.UpdateEdge(evmin,Lvmin,F,tol);
2589 V00.Orientation(TopAbs_FORWARD);
2593 V10.Orientation(TopAbs_REVERSED);
2596 B.Range(evmin,UMin,UMax);
2598 B.Degenerated(evmin, Standard_True);
2605 if (hasiso && !vmaxdegen)
2606 B.MakeEdge(evmax,Cvmax,tol);
2609 B.UpdateEdge(evmax,Lvmax,F,tol);
2611 V01.Orientation(TopAbs_FORWARD);
2615 V11.Orientation(TopAbs_REVERSED);
2618 B.Range(evmax,UMin,UMax);
2620 B.Degenerated(evmax, Standard_True);
2624 // make the wires and add them to the face
2625 eumin.Orientation(TopAbs_REVERSED);
2626 evmax.Orientation(TopAbs_REVERSED);
2630 if (!umininf && !umaxinf && vmininf && vmaxinf) {
2641 else if (umininf && umaxinf && !vmininf && !vmaxinf) {
2652 else if (!umininf || !umaxinf || !vmininf || !vmaxinf) {
2655 if (!umininf) B.Add(W,eumin);
2656 if (!vmininf) B.Add(W,evmin);
2657 if (!umaxinf) B.Add(W,eumax);
2658 if (!vmaxinf) B.Add(W,evmax);
2660 W.Closed(!umininf && !umaxinf && !vmininf && !vmaxinf);
2661 F.Closed(uclosed && vclosed);
2665 //=======================================================================
2666 //function : EnLargeGeometry
2668 //=======================================================================
2670 static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S,
2675 Standard_Boolean& IsV1degen,
2676 Standard_Boolean& IsV2degen,
2677 const Standard_Real uf1,
2678 const Standard_Real uf2,
2679 const Standard_Real vf1,
2680 const Standard_Real vf2,
2681 const Standard_Real coeff,
2682 const Standard_Boolean theGlobalEnlargeU,
2683 const Standard_Boolean theGlobalEnlargeVfirst,
2684 const Standard_Boolean theGlobalEnlargeVlast,
2685 const Standard_Real theLenBeforeUfirst,
2686 const Standard_Real theLenAfterUlast,
2687 const Standard_Real theLenBeforeVfirst,
2688 const Standard_Real theLenAfterVlast)
2690 const Standard_Real TolApex = 1.e-5;
2692 Standard_Boolean SurfaceChange = Standard_False;
2693 if ( S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2694 Handle(Geom_Surface) BS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
2695 EnlargeGeometry(BS,U1,U2,V1,V2,IsV1degen,IsV2degen,
2696 uf1,uf2,vf1,vf2,coeff,
2697 theGlobalEnlargeU, theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
2698 theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
2699 if (!theGlobalEnlargeVfirst)
2701 if (!theGlobalEnlargeVlast)
2703 if (!theGlobalEnlargeVfirst || !theGlobalEnlargeVlast)
2704 //Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->SetTrim( U1, U2, V1, V2 );
2705 S = new Geom_RectangularTrimmedSurface( BS, U1, U2, V1, V2 );
2708 SurfaceChange = Standard_True;
2710 else if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)) {
2711 Handle(Geom_Surface) Surf = Handle(Geom_OffsetSurface)::DownCast (S)->BasisSurface();
2712 SurfaceChange = EnlargeGeometry(Surf,U1,U2,V1,V2,IsV1degen,IsV2degen,
2713 uf1,uf2,vf1,vf2,coeff,
2714 theGlobalEnlargeU, theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
2715 theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
2716 Handle(Geom_OffsetSurface)::DownCast(S)->SetBasisSurface(Surf);
2718 else if (S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
2719 S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution))
2721 Standard_Real du_first = 0., du_last = 0.,
2722 dv_first = 0., dv_last = 0.;
2723 Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
2724 Standard_Real u1, u2, v1, v2;
2725 Standard_Boolean enlargeU = theGlobalEnlargeU, enlargeV = Standard_True;
2726 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2727 Standard_Boolean enlargeVfirst = theGlobalEnlargeVfirst, enlargeVlast = theGlobalEnlargeVlast;
2728 S->Bounds( u1, u2, v1, v2 );
2729 if (Precision::IsInfinite(u1) || Precision::IsInfinite(u2))
2731 du_first = du_last = uf2-uf1;
2732 u1 = uf1 - du_first;
2734 enlargeU = Standard_False;
2736 else if (S->IsUClosed())
2737 enlargeU = Standard_False;
2740 viso = S->VIso( vf1 );
2741 GeomAdaptor_Curve gac( viso );
2742 Standard_Real du_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
2743 du_first = (theLenBeforeUfirst == -1)? du_default : theLenBeforeUfirst;
2744 du_last = (theLenAfterUlast == -1)? du_default : theLenAfterUlast;
2745 uiso1 = S->UIso( uf1 );
2746 uiso2 = S->UIso( uf2 );
2747 if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
2748 enlargeUfirst = Standard_False;
2749 if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
2750 enlargeUlast = Standard_False;
2752 if (Precision::IsInfinite(v1) || Precision::IsInfinite(v2))
2754 dv_first = dv_last = vf2-vf1;
2755 v1 = vf1 - dv_first;
2757 enlargeV = Standard_False;
2759 else if (S->IsVClosed())
2760 enlargeV = Standard_False;
2763 uiso = S->UIso( uf1 );
2764 GeomAdaptor_Curve gac( uiso );
2765 Standard_Real dv_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
2766 dv_first = (theLenBeforeVfirst == -1)? dv_default : theLenBeforeVfirst;
2767 dv_last = (theLenAfterVlast == -1)? dv_default : theLenAfterVlast;
2768 viso1 = S->VIso( vf1 );
2769 viso2 = S->VIso( vf2 );
2770 if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
2772 enlargeVfirst = Standard_False;
2773 IsV1degen = Standard_True;
2775 if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
2777 enlargeVlast = Standard_False;
2778 IsV2degen = Standard_True;
2781 Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface( S, u1, u2, v1, v2 );
2784 if (enlargeUfirst && du_first != 0.)
2785 GeomLib::ExtendSurfByLength (aSurf, du_first, 1, Standard_True, Standard_False);
2786 if (enlargeUlast && du_last != 0.)
2787 GeomLib::ExtendSurfByLength (aSurf, du_last, 1, Standard_True, Standard_True);
2791 if (enlargeVfirst && dv_first != 0.)
2792 GeomLib::ExtendSurfByLength (aSurf, dv_first, 1, Standard_False, Standard_False);
2793 if (enlargeVlast && dv_last != 0.)
2794 GeomLib::ExtendSurfByLength (aSurf, dv_last, 1, Standard_False, Standard_True);
2797 S->Bounds( U1, U2, V1, V2 );
2798 SurfaceChange = Standard_True;
2800 else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
2801 S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
2803 Standard_Boolean enlargeU = theGlobalEnlargeU, enlargeV = Standard_True;
2804 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2805 Standard_Boolean enlargeVfirst = theGlobalEnlargeVfirst, enlargeVlast = theGlobalEnlargeVlast;
2807 enlargeU = Standard_False;
2809 enlargeV = Standard_False;
2811 Standard_Real duf = uf2-uf1, dvf = vf2-vf1;
2812 Standard_Real u1, u2, v1, v2;
2813 S->Bounds( u1, u2, v1, v2 );
2815 Standard_Real du_first = 0., du_last = 0.,
2816 dv_first = 0., dv_last = 0.;
2817 Handle( Geom_Curve ) uiso1, uiso2, viso1, viso2;
2818 Standard_Real gabarit_uiso1, gabarit_uiso2, gabarit_viso1, gabarit_viso2;
2820 uiso1 = S->UIso( u1 );
2821 uiso2 = S->UIso( u2 );
2822 viso1 = S->VIso( v1 );
2823 viso2 = S->VIso( v2 );
2824 gabarit_uiso1 = BRepOffset_Tool::Gabarit( uiso1 );
2825 gabarit_uiso2 = BRepOffset_Tool::Gabarit( uiso2 );
2826 gabarit_viso1 = BRepOffset_Tool::Gabarit( viso1 );
2827 gabarit_viso2 = BRepOffset_Tool::Gabarit( viso2 );
2828 if (gabarit_viso1 <= TolApex ||
2829 gabarit_viso2 <= TolApex)
2830 enlargeU = Standard_False;
2831 if (gabarit_uiso1 <= TolApex ||
2832 gabarit_uiso2 <= TolApex)
2833 enlargeV = Standard_False;
2835 GeomAdaptor_Curve gac;
2839 Standard_Real du_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
2840 du_first = (theLenBeforeUfirst == -1)? du_default : theLenBeforeUfirst;
2841 du_last = (theLenAfterUlast == -1)? du_default : theLenAfterUlast;
2842 if (gabarit_uiso1 <= TolApex)
2843 enlargeUfirst = Standard_False;
2844 if (gabarit_uiso2 <= TolApex)
2845 enlargeUlast = Standard_False;
2850 Standard_Real dv_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
2851 dv_first = (theLenBeforeVfirst == -1)? dv_default : theLenBeforeVfirst;
2852 dv_last = (theLenAfterVlast == -1)? dv_default : theLenAfterVlast;
2853 if (gabarit_viso1 <= TolApex)
2855 enlargeVfirst = Standard_False;
2856 IsV1degen = Standard_True;
2858 if (gabarit_viso2 <= TolApex)
2860 enlargeVlast = Standard_False;
2861 IsV2degen = Standard_True;
2865 Handle(Geom_BoundedSurface) aSurf = Handle(Geom_BoundedSurface)::DownCast (S);
2868 if (enlargeUfirst && uf1-u1 < duf && du_first != 0.)
2869 GeomLib::ExtendSurfByLength (aSurf, du_first, 1, Standard_True, Standard_False);
2870 if (enlargeUlast && u2-uf2 < duf && du_last != 0.)
2871 GeomLib::ExtendSurfByLength (aSurf, du_last, 1, Standard_True, Standard_True);
2875 if (enlargeVfirst && vf1-v1 < dvf && dv_first != 0.)
2876 GeomLib::ExtendSurfByLength (aSurf, dv_first, 1, Standard_False, Standard_False);
2877 if (enlargeVlast && v2-vf2 < dvf && dv_last != 0.)
2878 GeomLib::ExtendSurfByLength (aSurf, dv_last, 1, Standard_False, Standard_True);
2882 S->Bounds( U1, U2, V1, V2 );
2883 SurfaceChange = Standard_True;
2886 Standard_Real UU1,UU2,VV1,VV2;
2887 S->Bounds(UU1,UU2,VV1,VV2);
2888 // Pas d extension au dela des bornes de la surface.
2894 return SurfaceChange;
2897 //=======================================================================
2898 //function : UpDatePCurve
2899 //purpose : Mise a jour des pcurves de F sur la surface de de BF.
2900 // F and BF has to be FORWARD,
2901 //=======================================================================
2903 static void UpdatePCurves (const TopoDS_Face& F,
2909 TopTools_IndexedMapOfShape Emap;
2910 Handle(Geom2d_Curve) NullPCurve;
2912 TopExp::MapShapes( F, TopAbs_EDGE, Emap );
2914 for (i = 1; i <= Emap.Extent(); i++)
2916 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
2917 CE.Orientation( TopAbs_FORWARD );
2918 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface( CE, F, f, l );
2921 if (BRep_Tool::IsClosed( CE, F ))
2924 Handle(Geom2d_Curve) C2R = BRep_Tool::CurveOnSurface( CE, F, f, l );
2925 B.UpdateEdge( CE, NullPCurve, NullPCurve, F, BRep_Tool::Tolerance(CE) );
2926 B.UpdateEdge( CE, C2, C2R, BF, BRep_Tool::Tolerance(CE) );
2930 B.UpdateEdge( CE, NullPCurve, F, BRep_Tool::Tolerance(CE) );
2931 B.UpdateEdge( CE, C2, BF, BRep_Tool::Tolerance(CE) );
2939 //=======================================================================
2940 //function :CompactUVBounds
2942 //=======================================================================
2944 static void CompactUVBounds (const TopoDS_Face& F,
2945 Standard_Real& UMin,
2946 Standard_Real& UMax,
2947 Standard_Real& VMin,
2948 Standard_Real& VMax)
2950 // Calcul serre pour que les bornes ne couvrent pas plus d une periode
2951 Standard_Real U1,U2;
2952 Standard_Real N = 33;
2955 TopExp_Explorer exp;
2956 for (exp.Init(F, TopAbs_EDGE); exp.More(); exp.Next()) {
2957 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
2958 BRepAdaptor_Curve2d C(E,F);
2959 BRep_Tool::Range(E,U1,U2);
2961 Standard_Real U = U1;
2962 Standard_Real DU = (U2-U1)/(N-1);
2963 for (Standard_Integer j=1;j<N;j++) {
2971 B.Get(UMin,VMin,UMax,VMax);
2974 //=======================================================================
2975 //function : CheckBounds
2977 //=======================================================================
2979 void BRepOffset_Tool::CheckBounds(const TopoDS_Face& F,
2980 const BRepOffset_Analyse& Analyse,
2981 Standard_Boolean& enlargeU,
2982 Standard_Boolean& enlargeVfirst,
2983 Standard_Boolean& enlargeVlast)
2985 enlargeU = Standard_True;
2986 enlargeVfirst = Standard_True; enlargeVlast = Standard_True;
2988 Standard_Integer Ubound = 0, Vbound = 0;
2989 Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
2990 Standard_Real Vfirst = RealLast(), Vlast = RealFirst();
2992 Standard_Real UF1,UF2,VF1,VF2;
2993 CompactUVBounds(F,UF1,UF2,VF1,VF2);
2995 Handle(Geom_Surface) theSurf = BRep_Tool::Surface(F);
2996 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
2997 theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (theSurf)->BasisSurface();
2999 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
3000 theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution) ||
3001 theSurf->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
3002 theSurf->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
3004 TopExp_Explorer Explo(F, TopAbs_EDGE);
3005 for (; Explo.More(); Explo.Next())
3007 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
3008 const BRepOffset_ListOfInterval& L = Analyse.Type(anEdge);
3009 if (!L.IsEmpty() || BRep_Tool::Degenerated(anEdge))
3011 BRepOffset_Type OT = L.First().Type();
3012 if (OT == BRepOffset_Tangent || BRep_Tool::Degenerated(anEdge))
3014 Standard_Real fpar, lpar;
3015 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, F, fpar, lpar);
3016 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
3017 aCurve = Handle(Geom2d_TrimmedCurve)::DownCast (aCurve)->BasisCurve();
3019 Handle(Geom2d_Line) theLine;
3020 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_Line))
3021 theLine = Handle(Geom2d_Line)::DownCast (aCurve);
3022 else if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BezierCurve) ||
3023 aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BSplineCurve))
3025 Standard_Real newFpar, newLpar, deviation;
3026 theLine = ShapeCustom_Curve2d::ConvertToLine2d(aCurve, fpar, lpar, Precision::Confusion(),
3027 newFpar, newLpar, deviation);
3030 if (!theLine.IsNull())
3032 gp_Dir2d theDir = theLine->Direction();
3033 if (theDir.IsParallel( gp::DX2d(), Precision::Angular() ))
3036 if (BRep_Tool::Degenerated(anEdge))
3038 if (Abs(theLine->Location().Y() - VF1) <= Precision::Confusion())
3039 enlargeVfirst = Standard_False;
3040 else //theLine->Location().Y() is near VF2
3041 enlargeVlast = Standard_False;
3045 if (theLine->Location().Y() < Vfirst)
3046 Vfirst = theLine->Location().Y();
3047 if (theLine->Location().Y() > Vlast)
3048 Vlast = theLine->Location().Y();
3051 else if (theDir.IsParallel( gp::DY2d(), Precision::Angular() ))
3054 if (theLine->Location().X() < Ufirst)
3055 Ufirst = theLine->Location().X();
3056 if (theLine->Location().X() > Ulast)
3057 Ulast = theLine->Location().X();
3065 if (Ubound >= 2 || Vbound >= 2)
3068 Abs(UF1-Ufirst) <= Precision::Confusion() &&
3069 Abs(UF2-Ulast) <= Precision::Confusion())
3070 enlargeU = Standard_False;
3072 Abs(VF1-Vfirst) <= Precision::Confusion() &&
3073 Abs(VF2-Vlast) <= Precision::Confusion())
3075 enlargeVfirst = Standard_False;
3076 enlargeVlast = Standard_False;
3081 //=======================================================================
3082 //function : EnLargeFace
3084 //=======================================================================
3086 Standard_Boolean BRepOffset_Tool::EnLargeFace
3087 (const TopoDS_Face& F,
3089 const Standard_Boolean CanExtentSurface,
3090 const Standard_Boolean UpdatePCurve,
3091 const Standard_Boolean theEnlargeU,
3092 const Standard_Boolean theEnlargeVfirst,
3093 const Standard_Boolean theEnlargeVlast,
3094 const Standard_Integer theExtensionMode,
3095 const Standard_Real theLenBeforeUfirst,
3096 const Standard_Real theLenAfterUlast,
3097 const Standard_Real theLenBeforeVfirst,
3098 const Standard_Real theLenAfterVlast)
3100 //---------------------------
3101 // extension de la geometrie.
3102 //---------------------------
3104 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
3105 Standard_Real UU1,VV1,UU2,VV2;
3106 Standard_Boolean uperiodic = Standard_False, vperiodic = Standard_False;
3107 Standard_Boolean isVV1degen = Standard_False, isVV2degen = Standard_False;
3108 Standard_Real US1,VS1,US2,VS2;
3109 Standard_Real UF1,VF1,UF2,VF2;
3110 Standard_Boolean SurfaceChange = Standard_False;
3112 if (S->IsUPeriodic() || S->IsVPeriodic()) {
3113 // Calcul serre pour que les bornes ne couvre pas plus d une periode
3114 CompactUVBounds(F,UF1,UF2,VF1,VF2);
3117 BRepTools::UVBounds(F,UF1,UF2,VF1,VF2);
3120 S->Bounds (US1,US2,VS1,VS2);
3121 Standard_Real coeff;
3122 if (theExtensionMode == 1)
3124 UU1 = VV1 = - TheInfini;
3125 UU2 = VV2 = TheInfini;
3130 Standard_Real FaceDU = UF2 - UF1;
3131 Standard_Real FaceDV = VF2 - VF1;
3132 UU1 = UF1 - 10*FaceDU;
3133 UU2 = UF2 + 10*FaceDU;
3134 VV1 = VF1 - 10*FaceDV;
3135 VV2 = VF2 + 10*FaceDV;
3139 if (CanExtentSurface) {
3140 SurfaceChange = EnlargeGeometry(S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2, coeff,
3141 theEnlargeU, theEnlargeVfirst, theEnlargeVlast,
3142 theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
3145 UU1 = Max(US1,UU1); UU2 = Min(UU2,US2);
3146 VV1 = Max(VS1,VV1); VV2 = Min(VS2,VV2);
3149 if (S->IsUPeriodic()) {
3150 uperiodic = Standard_True;
3151 Standard_Real Period = S->UPeriod();
3152 Standard_Real Delta = Period - (UF2 - UF1);
3153 Standard_Real alpha = 0.1;
3154 UU1 = UF1 - alpha*Delta; UU2 = UF2 + alpha*Delta;
3155 if ((UU2 - UU1) > Period) {
3159 if (S->IsVPeriodic()) {
3160 vperiodic = Standard_True;
3161 Standard_Real Period = S->VPeriod();
3162 Standard_Real Delta = Period - (VF2 - VF1);
3163 Standard_Real alpha = 0.1;
3164 VV1 = VF1 - alpha*Delta; VV2 = VF2 + alpha*Delta;
3165 if ((VV2 - VV1) > Period) {
3170 //Special treatment for conical surfaces
3171 Handle(Geom_Surface) theSurf = S;
3172 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
3173 theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
3174 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
3176 Handle(Geom_ConicalSurface) ConicalS = Handle(Geom_ConicalSurface)::DownCast (theSurf);
3177 gp_Cone theCone = ConicalS->Cone();
3178 gp_Pnt theApex = theCone.Apex();
3179 Standard_Real Uapex, Vapex;
3180 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
3181 if (VV1 < Vapex && Vapex < VV2)
3183 //consider that VF1 and VF2 are on the same side from apex
3184 Standard_Real TolApex = 1.e-5;
3185 if (Vapex - VF1 >= TolApex ||
3186 Vapex - VF2 >= TolApex) //if (VF1 < Vapex || VF2 < Vapex)
3195 UU1 = UF1; UU2 = UF2;
3197 if (!theEnlargeVfirst)
3199 if (!theEnlargeVlast)
3202 //Detect closedness in U and V directions
3203 Standard_Boolean uclosed = Standard_False, vclosed = Standard_False;
3204 BRepTools::DetectClosedness(F, uclosed, vclosed);
3205 if (uclosed && !uperiodic &&
3206 (theLenBeforeUfirst != 0. || theLenAfterUlast != 0.))
3207 uclosed = Standard_False;
3208 if (vclosed && !vperiodic &&
3209 (theLenBeforeVfirst != 0. && theLenAfterVlast != 0.))
3210 vclosed = Standard_False;
3212 MakeFace(S,UU1,UU2,VV1,VV2,uclosed,vclosed,isVV1degen,isVV2degen,BF);
3215 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
3217 //----------------------------------------------------------------
3218 // utile pour les bouchons on ne doit pas changer leur geometrie.
3219 // (Ce que fait BRepLib_MakeFace si S est restreinte).
3220 // On remet S et on update les pcurves.
3221 //----------------------------------------------------------------
3222 TopExp_Explorer exp;
3223 exp.Init(BF,TopAbs_EDGE);
3224 Standard_Real f=0.,l=0.;
3225 for (; exp.More(); exp.Next()) {
3226 TopoDS_Edge CE = TopoDS::Edge(exp.Current());
3227 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,BF,f,l);
3228 B.UpdateEdge (CE,C2,S,L,BRep_Tool::Tolerance(CE));
3230 B.UpdateFace(BF,S,L,BRep_Tool::Tolerance(F));
3233 if (SurfaceChange && UpdatePCurve) {
3234 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3235 UpdatePCurves(TopoDS::Face(aLocalFace),BF);
3236 //UpdatePCurves(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),BF);
3238 BB.UpdateFace( F, S, L, BRep_Tool::Tolerance(F) );
3241 BF.Orientation(F.Orientation());
3242 return SurfaceChange;
3245 //=======================================================================
3246 //function : TryParameter
3248 //=======================================================================
3250 static Standard_Boolean TryParameter (const TopoDS_Edge& OE,
3252 const TopoDS_Edge& NE,
3253 Standard_Real TolConf)
3255 BRepAdaptor_Curve OC(OE);
3256 BRepAdaptor_Curve NC(NE);
3257 Standard_Real Of = OC.FirstParameter(); Standard_Real Ol = OC.LastParameter();
3258 Standard_Real Nf = NC.FirstParameter(); Standard_Real Nl = NC.LastParameter();
3259 Standard_Real U = 0.;
3260 gp_Pnt P = BRep_Tool::Pnt(V);
3261 Standard_Boolean OK = Standard_False;
3263 if (P.Distance(OC.Value(Of)) < TolConf) {
3264 if (Of > Nf && Of < Nl && P.Distance(NC.Value(Of)) < TolConf) {
3269 if (P.Distance(OC.Value(Ol)) < TolConf) {
3270 if (Ol > Nf && Ol < Nl && P.Distance(NC.Value(Ol)) < TolConf) {
3277 TopoDS_Shape aLocalShape = NE.Oriented(TopAbs_FORWARD);
3278 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
3279 // TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD));
3280 aLocalShape = V.Oriented(TopAbs_INTERNAL);
3281 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
3282 U,NE,BRep_Tool::Tolerance(NE));
3283 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
3284 // U,NE,BRep_Tool::Tolerance(NE));
3289 //=======================================================================
3292 //=======================================================================
3294 void BRepOffset_Tool::MapVertexEdges (const TopoDS_Shape& S,
3295 TopTools_DataMapOfShapeListOfShape& MEV)
3297 TopExp_Explorer exp;
3298 exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3299 TopTools_MapOfShape DejaVu;
3300 for ( ; exp.More(); exp.Next()) {
3301 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3302 if (DejaVu.Add(E)) {
3303 TopoDS_Vertex V1,V2;
3304 TopExp::Vertices (E,V1,V2);
3305 if (!MEV.IsBound(V1)) {
3306 TopTools_ListOfShape empty;
3310 if (!V1.IsSame(V2)) {
3311 if (!MEV.IsBound(V2)) {
3312 TopTools_ListOfShape empty;
3321 //=======================================================================
3324 //=======================================================================
3326 void BRepOffset_Tool::BuildNeighbour (const TopoDS_Wire& W,
3327 const TopoDS_Face& F,
3328 TopTools_DataMapOfShapeShape& NOnV1,
3329 TopTools_DataMapOfShapeShape& NOnV2)
3331 TopoDS_Vertex V1,V2,VP1,VP2,FV1,FV2;
3332 TopoDS_Edge CurE,FirstE,PrecE;
3333 BRepTools_WireExplorer wexp;
3335 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3336 TopoDS_Shape aLocalWire = W.Oriented(TopAbs_FORWARD);
3337 wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
3338 // wexp.Init(TopoDS::Wire(W.Oriented(TopAbs_FORWARD)),
3339 // TopoDS::Face(F.Oriented(TopAbs_FORWARD)));
3340 CurE = FirstE = PrecE = wexp.Current();
3341 TopExp::Vertices(CurE,V1,V2);
3342 FV1 = VP1 = V1; FV2 = VP2 = V2;
3344 while (wexp.More()) {
3345 CurE = wexp.Current();
3346 TopExp::Vertices(CurE,V1,V2);
3347 if (V1.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3348 if (V1.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3349 if (V2.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3350 if (V2.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3355 if (V1.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3356 if (V1.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3357 if (V2.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3358 if (V2.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3361 //=======================================================================
3362 //function : ExtentFace
3364 //=======================================================================
3366 void BRepOffset_Tool::ExtentFace (const TopoDS_Face& F,
3367 TopTools_DataMapOfShapeShape& ConstShapes,
3368 TopTools_DataMapOfShapeShape& ToBuild,
3369 const TopAbs_State Side,
3370 const Standard_Real TolConf,
3376 sprintf(name,"FTE_%d",NbFTE++);
3381 TopExp_Explorer exp,exp2;
3382 TopTools_DataMapOfShapeShape Build;
3383 TopTools_DataMapOfShapeShape Extent;
3384 TopoDS_Edge FirstE,PrecE,CurE,NE;
3388 // Construction de la boite englobante de la face a etendre et des bouchons pour
3389 // limiter les extensions.
3390 //Bnd_Box ContextBox;
3391 //BRepBndLib::Add(F,B);
3392 //TopTools_DataMapIteratorOfDataMapOfShape itTB(ToBuild);
3393 //for (; itTB.More(); itTB.Next()) {
3394 //BRepBndLib::Add(TopBuild.Value(), ContextBox);
3398 Standard_Boolean SurfaceChange;
3399 SurfaceChange = EnLargeFace (F,EF,Standard_True);
3401 TopoDS_Shape aLocalShape = EF.EmptyCopied();
3402 NF = TopoDS::Face(aLocalShape);
3403 // NF = TopoDS::Face(EF.EmptyCopied());
3404 NF.Orientation(TopAbs_FORWARD);
3406 if (SurfaceChange) {
3407 //------------------------------------------------
3408 // Mise a jour des pcurves sur la surface de base.
3409 //------------------------------------------------
3410 TopoDS_Face Fforward = F;
3411 Fforward.Orientation(TopAbs_FORWARD);
3412 TopTools_IndexedMapOfShape Emap;
3413 TopExp::MapShapes( Fforward, TopAbs_EDGE, Emap );
3415 for (Standard_Integer i = 1; i <= Emap.Extent(); i++) {
3416 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
3417 CE.Orientation(TopAbs_FORWARD);
3418 TopoDS_Edge Ecs; //patch
3419 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,Fforward,f,l);
3421 if (ConstShapes.IsBound(CE)) {
3422 Ecs = TopoDS::Edge(ConstShapes(CE));
3423 BRep_Tool::Range(Ecs,f,l);
3425 if (BRep_Tool::IsClosed(CE,Fforward)) {
3426 TopoDS_Shape aLocalShapeReversedCE = CE.Reversed();
3427 Handle(Geom2d_Curve) C2R =
3428 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShapeReversedCE),Fforward,f,l);
3429 // Handle(Geom2d_Curve) C2R =
3430 // BRep_Tool::CurveOnSurface(TopoDS::Edge(CE.Reversed()),F,f,l);
3431 B.UpdateEdge (CE,C2,C2R,EF,BRep_Tool::Tolerance(CE));
3433 B.UpdateEdge (Ecs,C2,C2R,EF,BRep_Tool::Tolerance(CE));
3436 B.UpdateEdge (CE,C2,EF,BRep_Tool::Tolerance(CE));
3438 B.UpdateEdge (Ecs,C2,EF,BRep_Tool::Tolerance(CE));
3447 for (exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
3450 const TopoDS_Wire& W = TopoDS::Wire(exp.Current());
3451 TopTools_DataMapOfShapeListOfShape MVE; // Vertex -> Edges incidentes.
3452 TopTools_DataMapOfShapeShape NOnV1;
3453 TopTools_DataMapOfShapeShape NOnV2;
3455 MapVertexEdges (W,MVE);
3456 BuildNeighbour (W,F,NOnV1,NOnV2);
3458 TopTools_ListOfShape LInt1,LInt2;
3459 TopoDS_Face StopFace;
3460 //------------------------------------------------
3461 // Construction edges
3462 //------------------------------------------------
3463 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3464 exp2.More(); exp2.Next()) {
3465 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3466 if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
3467 if (ToBuild.IsBound(E)) {
3468 TopTools_ListOfShape LOE;
3470 BRepOffset_Tool::TryProject (TopoDS::Face(ToBuild(E)),
3471 EF,LOE,LInt2,LInt1,Side,TolConf);
3472 if (!LInt1.IsEmpty())
3477 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3478 exp2.More(); exp2.Next()) {
3479 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3480 if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
3481 if (ToBuild.IsBound(E)) {
3482 EnLargeFace(TopoDS::Face(ToBuild(E)),StopFace,Standard_False);
3483 BRepOffset_Tool::Inter3D (EF,StopFace,LInt1,LInt2,Side,E,Standard_True);
3484 // No intersection, it may happen for example for a chosen (non-offseted) planar face and
3485 // its neighbour offseted cylindrical face, if the offset is directed so that
3486 // the radius of the cylinder becomes smaller.
3487 if (LInt1.IsEmpty())
3489 if (LInt1.Extent() > 1) {
3490 // l intersection est en plusieurs edges (franchissement de couture)
3491 SelectEdge (F,EF,E,LInt1);
3493 NE = TopoDS::Edge(LInt1.First());
3494 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &NE.TShape());
3495 TE->Tolerance( TE->Tolerance()*10. ); //????
3496 if (NE.Orientation() == E.Orientation()) {
3497 Build.Bind(E,NE.Oriented(TopAbs_FORWARD));
3500 Build.Bind(E,NE.Oriented(TopAbs_REVERSED));
3502 const TopoDS_Edge& EOnV1 = TopoDS::Edge(NOnV1(E));
3503 if (!ToBuild .IsBound(EOnV1) &&
3504 !ConstShapes.IsBound(EOnV1) &&
3505 !Build .IsBound(EOnV1)) {
3506 ExtentEdge (F,EF,EOnV1,NE);
3507 Build.Bind (EOnV1,NE.Oriented(TopAbs_FORWARD));
3509 const TopoDS_Edge& EOnV2 = TopoDS::Edge(NOnV2(E));
3510 if (!ToBuild .IsBound(EOnV2) &&
3511 !ConstShapes.IsBound(EOnV2) &&
3512 !Build .IsBound(EOnV2)) {
3513 ExtentEdge (F,EF,EOnV2,NE);
3514 Build.Bind (EOnV2,NE.Oriented (TopAbs_FORWARD));
3519 //------------------------------------------------
3520 // Construction Vertex.
3521 //------------------------------------------------
3522 TopTools_ListOfShape LV;
3525 TopoDS_Vertex V1,V2;
3527 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE); exp2.More(); exp2.Next())
3529 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3530 TopExp::Vertices (E,V1,V2);
3531 BRep_Tool::Range (E,f,l);
3533 if (Build.IsBound(E))
3535 const TopoDS_Edge& NEOnV1 = TopoDS::Edge(NOnV1(E));
3536 if (Build.IsBound(NEOnV1) && (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV1)))
3538 if (E.IsSame(NEOnV1))
3539 V = TopExp::FirstVertex(TopoDS::Edge(Build(E)));
3545 if (!Build.IsBound(V1))
3547 Inter2d (EF,TopoDS::Edge(Build(E)), TopoDS::Edge(Build(NEOnV1)),LV,/*TolConf*/Precision::Confusion());
3551 if (Build(E).Orientation() == TopAbs_FORWARD)
3553 V = TopoDS::Vertex(LV.First());
3557 V = TopoDS::Vertex(LV.Last());
3567 V = TopoDS::Vertex(Build(V1));
3568 if (MVE (V1).Extent() > 2)
3570 V.Orientation(TopAbs_FORWARD);
3571 if (Build(E).Orientation() == TopAbs_REVERSED)
3572 V.Orientation(TopAbs_REVERSED);
3574 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3585 if (ConstShapes.IsBound(V1)) V = TopoDS::Vertex(ConstShapes(V1));
3586 V.Orientation(TopAbs_FORWARD);
3587 if (Build(E).Orientation() == TopAbs_REVERSED)
3588 V.Orientation(TopAbs_REVERSED);
3589 if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
3590 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3593 ConstShapes.Bind(V1,V);
3595 const TopoDS_Edge& NEOnV2 = TopoDS::Edge(NOnV2(E));
3596 if (Build.IsBound(NEOnV2) && (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV2)))
3598 if (E.IsSame(NEOnV2))
3599 V = TopExp::LastVertex(TopoDS::Edge(Build(E)));
3606 if (!Build.IsBound(V2))
3608 Inter2d (EF,TopoDS::Edge(Build(E)), TopoDS::Edge(Build(NEOnV2)),LV,/*TolConf*/Precision::Confusion());
3612 if (Build(E).Orientation() == TopAbs_FORWARD)
3614 V = TopoDS::Vertex(LV.Last());
3618 V = TopoDS::Vertex(LV.First());
3628 V = TopoDS::Vertex(Build(V2));
3629 if (MVE (V2).Extent() > 2)
3631 V.Orientation(TopAbs_REVERSED);
3632 if (Build(E).Orientation() == TopAbs_REVERSED)
3633 V.Orientation(TopAbs_FORWARD);
3635 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3646 if (ConstShapes.IsBound(V2))
3647 V = TopoDS::Vertex(ConstShapes(V2));
3648 V.Orientation(TopAbs_REVERSED);
3649 if (Build(E).Orientation() == TopAbs_REVERSED)
3650 V.Orientation(TopAbs_FORWARD);
3651 if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
3652 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3654 ConstShapes.Bind(V2,V);
3660 TopoDS_Vertex NV1,NV2;
3661 TopAbs_Orientation Or;
3662 Standard_Real U1,U2;
3663 Standard_Real eps = Precision::Confusion();
3673 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3674 exp2.More(); exp2.Next()) {
3675 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3676 TopExp::Vertices (E,V1,V2);
3677 if (Build.IsBound(E)) {
3678 NE = TopoDS::Edge(Build(E));
3679 BRep_Tool::Range(NE,f,l);
3680 Or = NE.Orientation();
3681 //-----------------------------------------------------
3682 // Copy pour virer les vertex deja sur la nouvelle edge.
3683 //-----------------------------------------------------
3684 NV1 = TopoDS::Vertex(ConstShapes(V1));
3685 NV2 = TopoDS::Vertex(ConstShapes(V2));
3687 TopoDS_Shape aLocalVertexOrientedNV1 = NV1.Oriented(TopAbs_INTERNAL);
3688 TopoDS_Shape aLocalEdge = NE.Oriented(TopAbs_INTERNAL);
3690 U1 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalVertexOrientedNV1),
3691 TopoDS::Edge (aLocalEdge));
3692 aLocalVertexOrientedNV1 = NV2.Oriented(TopAbs_INTERNAL);
3693 aLocalEdge = NE.Oriented(TopAbs_FORWARD);
3694 U2 = BRep_Tool::Parameter (TopoDS::Vertex(aLocalVertexOrientedNV1),TopoDS::Edge (aLocalEdge));
3695 // U1 = BRep_Tool::Parameter
3696 // (TopoDS::Vertex(NV1.Oriented(TopAbs_INTERNAL)),
3697 // TopoDS::Edge (NE .Oriented(TopAbs_FORWARD)));
3698 // U2 = BRep_Tool::Parameter
3699 // (TopoDS::Vertex(NV2.Oriented(TopAbs_INTERNAL)),
3700 // TopoDS::Edge (NE.Oriented(TopAbs_FORWARD)));
3701 aLocalEdge = NE.EmptyCopied();
3702 NE = TopoDS::Edge(aLocalEdge);
3703 NE.Orientation(TopAbs_FORWARD);
3704 if (NV1.IsSame(NV2))
3709 if (Or == TopAbs_FORWARD) {U1 = f; U2 = l;}
3710 else {U1 = l; U2 = f;}
3711 if (Or == TopAbs_FORWARD)
3715 if (Abs(U1-l) < eps) U1 = f;
3716 if (Abs(U2-f) < eps) U2 = l;
3718 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3719 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3720 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3721 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3722 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3723 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3725 ConstShapes.Bind(E,NE);
3726 NE.Orientation(E.Orientation());
3732 if (Abs(U2-l) < eps) U2 = f;
3733 if (Abs(U1-f) < eps) U1 = l;
3735 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3736 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3737 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3738 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3739 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3740 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3742 ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
3743 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3748 //-------------------
3749 // edge is not ferme.
3750 //-------------------
3751 if (Or == TopAbs_FORWARD) {
3753 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3754 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3755 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3756 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3757 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3758 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3763 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3764 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3765 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3766 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3767 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3768 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3771 ConstShapes.Bind(E,NE);
3772 NE.Orientation(E.Orientation());
3776 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3777 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3778 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3779 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3780 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3781 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3783 ConstShapes.Bind(E,NE);
3784 NE.Orientation(E.Orientation());
3788 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3789 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3790 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3791 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3792 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3793 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3795 ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
3796 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3801 } // Build.IsBound(E)
3802 else if (ConstShapes.IsBound(E)) { // !Build.IsBound(E)
3803 NE = TopoDS::Edge(ConstShapes(E));
3804 BuildPCurves(NE,NF);
3805 Or = NE.Orientation();
3806 if (Or == TopAbs_REVERSED) {
3807 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3810 NE.Orientation(E.Orientation());
3815 ConstShapes.Bind(E,NE.Oriented(TopAbs_FORWARD));
3819 B.Add(NF,NW.Oriented(W.Orientation()));
3821 NF.Orientation(F.Orientation());
3822 BRepTools::Update(NF); // Maj des UVPoints
3827 sprintf(name,"FOB_%d",NbFOB++);
3828 DBRep::Set(name,NF);
3834 //=======================================================================
3835 //function : Deboucle3D
3837 //=======================================================================
3839 TopoDS_Shape BRepOffset_Tool::Deboucle3D(const TopoDS_Shape& S,
3840 const TopTools_MapOfShape& Boundary)
3842 return BRepAlgo_Tool::Deboucle3D(S,Boundary);
3845 //=======================================================================
3846 //function : IsInOut
3848 //=======================================================================
3850 static Standard_Boolean IsInOut (BRepTopAdaptor_FClass2d& FC,
3851 Geom2dAdaptor_Curve AC,
3852 const TopAbs_State& S )
3854 Standard_Real Def = 100*Precision::Confusion();
3855 GCPnts_QuasiUniformDeflection QU(AC,Def);
3857 for (Standard_Integer i = 1; i <= QU.NbPoints(); i++) {
3858 gp_Pnt2d P = AC.Value(QU.Parameter(i));
3859 if (FC.Perform(P) != S) {
3860 return Standard_False;
3863 return Standard_True;
3866 //=======================================================================
3867 //function : CorrectOrientation
3869 //=======================================================================
3871 void BRepOffset_Tool::CorrectOrientation(const TopoDS_Shape& SI,
3872 const TopTools_IndexedMapOfShape& NewEdges,
3873 Handle(BRepAlgo_AsDes)& AsDes,
3874 BRepAlgo_Image& InitOffset,
3875 const Standard_Real Offset)
3878 TopExp_Explorer exp;
3879 exp.Init(SI,TopAbs_FACE);
3880 Standard_Real f=0.,l=0.;
3882 for (; exp.More(); exp.Next()) {
3884 const TopoDS_Face& FI = TopoDS::Face(exp.Current());
3885 const TopTools_ListOfShape& LOF = InitOffset.Image(FI);
3886 TopTools_ListIteratorOfListOfShape it(LOF);
3887 for (; it.More(); it.Next()) {
3888 const TopoDS_Face& OF = TopoDS::Face(it.Value());
3889 TopTools_ListOfShape& LOE = AsDes->ChangeDescendant(OF);
3890 TopTools_ListIteratorOfListOfShape itE(LOE);
3892 Standard_Boolean YaInt = Standard_False;
3893 for (; itE.More(); itE.Next()) {
3894 const TopoDS_Edge& OE = TopoDS::Edge(itE.Value());
3895 if (NewEdges.Contains(OE)) {YaInt = Standard_True; break;}
3898 TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
3899 BRepTopAdaptor_FClass2d FC (TopoDS::Face(aLocalFace),
3900 Precision::Confusion());
3901 // BRepTopAdaptor_FClass2d FC (TopoDS::Face(FI.Oriented(TopAbs_FORWARD)),
3902 // Precision::Confusion());
3903 for (itE.Initialize(LOE); itE.More(); itE.Next()) {
3904 TopoDS_Shape& OE = itE.Value();
3905 if (NewEdges.Contains(OE)) {
3906 Handle(Geom2d_Curve) CO2d =
3907 BRep_Tool::CurveOnSurface(TopoDS::Edge(OE),OF,f,l);
3908 Geom2dAdaptor_Curve AC(CO2d,f,l);
3911 if (IsInOut(FC,AC,TopAbs_OUT)) OE.Reverse();
3914 // if (IsInOut(FC,AC,TopAbs_IN)) OE.Reverse();
3924 //=======================================================================
3925 //function : CheckNormals
3927 //=======================================================================
3928 Standard_Boolean BRepOffset_Tool::CheckPlanesNormals(const TopoDS_Face& theFace1,
3929 const TopoDS_Face& theFace2,
3930 const Standard_Real theTolAng)
3932 BRepAdaptor_Surface aBAS1(theFace1, Standard_False), aBAS2(theFace2, Standard_False);
3933 if (aBAS1.GetType() != GeomAbs_Plane ||
3934 aBAS2.GetType() != GeomAbs_Plane) {
3935 return Standard_False;
3938 gp_Dir aDN1 = aBAS1.Plane().Position().Direction();
3939 if (theFace1.Orientation() == TopAbs_REVERSED) {
3943 gp_Dir aDN2 = aBAS2.Plane().Position().Direction();
3944 if (theFace2.Orientation() == TopAbs_REVERSED) {
3948 Standard_Real anAngle = aDN1.Angle(aDN2);
3949 return (anAngle < theTolAng);
3952 //=======================================================================
3953 //function : PerformPlanes
3955 //=======================================================================
3956 void PerformPlanes(const TopoDS_Face& theFace1,
3957 const TopoDS_Face& theFace2,
3958 const TopAbs_State theSide,
3959 TopTools_ListOfShape& theL1,
3960 TopTools_ListOfShape& theL2)
3964 // Intersect the planes using IntTools_FaceFace directly
3965 IntTools_FaceFace aFF;
3966 aFF.SetParameters(Standard_True, Standard_True, Standard_True, Precision::Confusion());
3967 aFF.Perform(theFace1, theFace2);
3969 if (!aFF.IsDone()) {
3973 const IntTools_SequenceOfCurves& aSC = aFF.Lines();
3974 if (aSC.IsEmpty()) {
3978 // In Plane/Plane intersection only one curve is always produced.
3979 // Make the edge from this section curve.
3983 const IntTools_Curve& aIC = aSC(1);
3984 const Handle(Geom_Curve)& aC3D = aIC.Curve();
3985 aBB.MakeEdge(aE, aC3D, aIC.Tolerance());
3986 // Get bounds of the curve
3987 Standard_Real aTF, aTL;
3989 aIC.Bounds(aTF, aTL, aPF, aPL);
3990 // Make the bounding vertices
3991 TopoDS_Vertex aVF, aVL;
3992 aBB.MakeVertex(aVF, aPF, aIC.Tolerance());
3993 aBB.MakeVertex(aVL, aPL, aIC.Tolerance());
3994 aVL.Orientation(TopAbs_REVERSED);
3995 // Add vertices to the edge
3998 // Add 2D curves to the edge
3999 aBB.UpdateEdge(aE, aIC.FirstCurve2d(), theFace1, aIC.Tolerance());
4000 aBB.UpdateEdge(aE, aIC.SecondCurve2d(), theFace2, aIC.Tolerance());
4001 // Update range of the new edge
4002 aBB.Range(aE, aTF, aTL);
4006 TopAbs_Orientation O1, O2;
4007 BRepOffset_Tool::OrientSection(aE, theFace1, theFace2, O1, O2);
4008 if (theSide == TopAbs_OUT) {
4009 O1 = TopAbs::Reverse(O1);
4010 O2 = TopAbs::Reverse(O2);
4013 BRepLib::SameParameter(aE, Precision::Confusion(), Standard_True);
4015 // Add edge to result
4016 theL1.Append(aE.Oriented(O1));
4017 theL2.Append(aE.Oriented(O2));
4020 //=======================================================================
4022 //purpose : Checks if the given value is close to infinite (TheInfini)
4023 //=======================================================================
4024 Standard_Boolean IsInf(const Standard_Real theVal)
4026 return (theVal > TheInfini*0.9);
4029 static void UpdateVertexTolerances(const TopoDS_Face& theFace)
4032 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
4033 TopExp::MapShapesAndAncestors(theFace, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
4035 for (Standard_Integer i = 1; i <= VEmap.Extent(); i++)
4037 const TopoDS_Vertex& aVertex = TopoDS::Vertex(VEmap.FindKey(i));
4038 const TopTools_ListOfShape& Elist = VEmap(i);
4039 gp_Pnt PntVtx = BRep_Tool::Pnt(aVertex);
4040 TopTools_ListIteratorOfListOfShape itl(Elist);
4041 for (; itl.More(); itl.Next())
4043 const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
4044 TopoDS_Vertex V1, V2;
4045 TopExp::Vertices(anEdge, V1, V2);
4046 Standard_Real fpar, lpar;
4047 BRep_Tool::Range(anEdge, fpar, lpar);
4048 Standard_Real aParam = (V1.IsSame(aVertex))? fpar : lpar;
4049 if (!BRep_Tool::Degenerated(anEdge))
4051 BRepAdaptor_Curve BAcurve(anEdge);
4052 gp_Pnt aPnt = BAcurve.Value(aParam);
4053 Standard_Real aDist = PntVtx.Distance(aPnt);
4054 BB.UpdateVertex(aVertex, aDist);
4057 aPnt = BAcurve.Value(lpar);
4058 aDist = PntVtx.Distance(aPnt);
4059 BB.UpdateVertex(aVertex, aDist);
4062 BRepAdaptor_Curve BAcurveonsurf(anEdge, theFace);
4063 gp_Pnt aPnt = BAcurveonsurf.Value(aParam);
4064 Standard_Real aDist = PntVtx.Distance(aPnt);
4065 BB.UpdateVertex(aVertex, aDist);
4068 aPnt = BAcurveonsurf.Value(lpar);
4069 aDist = PntVtx.Distance(aPnt);
4070 BB.UpdateVertex(aVertex, aDist);