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.
17 #include <BRepOffset_Tool.hxx>
19 #include <Bnd_Box2d.hxx>
20 #include <BndLib_Add3dCurve.hxx>
21 #include <BOPAlgo_PaveFiller.hxx>
22 #include <BOPDS_DS.hxx>
23 #include <BOPTools_AlgoTools.hxx>
24 #include <BOPTools_AlgoTools2D.hxx>
25 #include <BRep_CurveRepresentation.hxx>
26 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
27 #include <BRep_TEdge.hxx>
28 #include <BRep_Tool.hxx>
29 #include <BRep_Builder.hxx>
30 #include <BRepAdaptor_Curve.hxx>
31 #include <BRepAdaptor_Curve2d.hxx>
32 #include <BRepAdaptor_Surface.hxx>
33 #include <BRepAlgo_AsDes.hxx>
34 #include <BRepAlgo_Image.hxx>
35 #include <BRepAlgo_Tool.hxx>
36 #include <BRepBndLib.hxx>
37 #include <BRepLib.hxx>
38 #include <BRepLib_MakeEdge.hxx>
39 #include <BRepLib_MakeFace.hxx>
40 #include <BRepLib_MakePolygon.hxx>
41 #include <BRepLib_MakeVertex.hxx>
42 #include <BRepOffset_Analyse.hxx>
43 #include <BRepOffset_Interval.hxx>
44 #include <BRepOffset_ListOfInterval.hxx>
45 #include <BRepTools.hxx>
46 #include <BRepTools_Modifier.hxx>
47 #include <BRepTools_TrsfModification.hxx>
48 #include <BRepTools_WireExplorer.hxx>
49 #include <BRepTopAdaptor_FClass2d.hxx>
52 #include <Extrema_ExtPC.hxx>
53 #include <Extrema_ExtPC2d.hxx>
54 #include <BRepExtrema_DistShapeShape.hxx>
55 #include <GCPnts_AbscissaPoint.hxx>
56 #include <GCPnts_QuasiUniformDeflection.hxx>
57 #include <GCPnts_UniformAbscissa.hxx>
58 #include <Geom2d_BezierCurve.hxx>
59 #include <Geom2d_BSplineCurve.hxx>
60 #include <Geom2d_Circle.hxx>
61 #include <Geom2d_Curve.hxx>
62 #include <Geom2d_Ellipse.hxx>
63 #include <Geom2d_Hyperbola.hxx>
64 #include <Geom2d_Line.hxx>
65 #include <Geom2d_Parabola.hxx>
66 #include <Geom2d_TrimmedCurve.hxx>
67 #include <Geom2dAdaptor_Curve.hxx>
68 #include <Geom2dConvert_ApproxCurve.hxx>
69 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
70 #include <Geom2dInt_GInter.hxx>
71 #include <Geom_BezierSurface.hxx>
72 #include <Geom_BSplineCurve.hxx>
73 #include <Geom_BSplineSurface.hxx>
74 #include <Geom_Conic.hxx>
75 #include <Geom_ConicalSurface.hxx>
76 #include <Geom_Curve.hxx>
77 #include <Geom_Line.hxx>
78 #include <Geom_OffsetSurface.hxx>
79 #include <Geom_Plane.hxx>
80 #include <Geom_RectangularTrimmedSurface.hxx>
81 #include <Geom_Surface.hxx>
82 #include <Geom_SurfaceOfLinearExtrusion.hxx>
83 #include <Geom_SurfaceOfRevolution.hxx>
84 #include <Geom_TrimmedCurve.hxx>
85 #include <GeomAdaptor_Surface.hxx>
86 #include <GeomAPI.hxx>
87 #include <GeomAPI_ExtremaCurveCurve.hxx>
88 #include <GeomAPI_ProjectPointOnCurve.hxx>
89 #include <GeomConvert_ApproxCurve.hxx>
90 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
91 #include <GeomInt_IntSS.hxx>
92 #include <GeomLib.hxx>
93 #include <GeomProjLib.hxx>
97 #include <IntRes2d_IntersectionPoint.hxx>
98 #include <IntRes2d_IntersectionSegment.hxx>
99 #include <IntTools_FaceFace.hxx>
100 #include <Precision.hxx>
101 #include <ProjLib_HProjectedCurve.hxx>
102 #include <ProjLib_ProjectedCurve.hxx>
103 #include <ShapeCustom_Curve2d.hxx>
104 #include <Standard_ConstructionError.hxx>
105 #include <TColgp_Array1OfPnt2d.hxx>
106 #include <TopAbs.hxx>
107 #include <TopExp.hxx>
108 #include <TopExp_Explorer.hxx>
109 #include <TopoDS.hxx>
110 #include <TopoDS_Compound.hxx>
111 #include <TopoDS_Edge.hxx>
112 #include <TopoDS_Face.hxx>
113 #include <TopoDS_Iterator.hxx>
114 #include <TopoDS_Shape.hxx>
115 #include <TopoDS_Vertex.hxx>
116 #include <TopoDS_Wire.hxx>
117 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
118 #include <TopTools_ListIteratorOfListOfShape.hxx>
119 #include <TopTools_SequenceOfShape.hxx>
123 // The constant defines the maximal value to enlarge surfaces.
124 // It is limited to 1.e+7. This limitation is justified by the
125 // floating point format. As we can have only 15
126 // valuable decimal numbers, then during intersection of surfaces with
127 // bounds of 1.e+8 the possible inaccuracy might appear already in seventh
128 // decimal place which will be more than Precision::Confusion value -
129 // 1.e-7, default tolerance value for the section curves.
130 // By decreasing the max enlarge value to 1.e+7 the inaccuracy will be
131 // shifted to eighth decimal place, i.e. the inaccuracy will be
132 // decreased to values less than 1.e-7.
133 const Standard_Real TheInfini = 1.e+7;
135 //tma: for new boolean operation
138 #include <Geom2d_Conic.hxx>
139 #include <Geom_BoundedCurve.hxx>
140 Standard_Boolean AffichInter = Standard_False;
141 static Standard_Integer NbNewEdges = 1;
142 static Standard_Integer NbFaces = 1;
143 static Standard_Integer NbFOB = 1;
144 static Standard_Integer NbFTE = 1;
145 static Standard_Integer NbExtE = 1;
149 static Standard_Boolean AffichExtent = Standard_False;
153 void PerformPlanes(const TopoDS_Face& theFace1,
154 const TopoDS_Face& theFace2,
155 const TopAbs_State theState,
156 TopTools_ListOfShape& theL1,
157 TopTools_ListOfShape& theL2);
159 static void UpdateVertexTolerances(const TopoDS_Face& theFace);
162 Standard_Boolean IsInf(const Standard_Real theVal);
164 //=======================================================================
165 //function : EdgeVertices
167 //=======================================================================
169 void BRepOffset_Tool::EdgeVertices (const TopoDS_Edge& E,
173 if (E.Orientation() == TopAbs_REVERSED) {
174 TopExp::Vertices(E,V2,V1);
177 TopExp::Vertices(E,V1,V2);
181 //=======================================================================
182 //function : FindPeriod
184 //=======================================================================
186 static void FindPeriod (const TopoDS_Face& F,
195 for (exp.Init(F,TopAbs_EDGE); exp.More(); exp.Next()) {
196 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
199 const Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,pf,pl);
200 if (C.IsNull()) return;
201 Geom2dAdaptor_Curve PC(C,pf,pl);
202 Standard_Real i, nbp = 20;
203 if (PC.GetType() == GeomAbs_Line) nbp = 2;
204 Standard_Real step = (pl - pf) / nbp;
208 for (i = 2; i < nbp; i++) {
215 B.Get(umin,vmin,umax,vmax);
219 //=======================================================================
220 //function : PutInBounds
221 //purpose : Recadre la courbe 2d dans les bounds de la face
222 //=======================================================================
224 static void PutInBounds (const TopoDS_Face& F,
225 const TopoDS_Edge& E,
226 Handle(Geom2d_Curve)& C2d)
228 Standard_Real umin,umax,vmin,vmax;
230 BRep_Tool::Range(E,f,l);
232 TopLoc_Location L; // Recup S avec la location pour eviter la copie.
233 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
235 if (S->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
236 S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
241 if (!S->IsUPeriodic() && !S->IsVPeriodic()) return;
243 FindPeriod (F,umin,umax,vmin,vmax);
245 if (S->IsUPeriodic()) {
246 Standard_Real period = S->UPeriod();
247 Standard_Real eps = period*1.e-6;
248 gp_Pnt2d Pf = C2d->Value(f);
249 gp_Pnt2d Pl = C2d->Value(l);
250 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
251 Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
252 Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
253 Standard_Real du = 0.;
254 if (minC< umin - eps) {
255 du = (int((umin - minC)/period) + 1)*period;
257 if (minC > umax + eps) {
258 du = -(int((minC - umax)/period) + 1)*period;
263 minC += du; maxC += du;
265 // Ajuste au mieux la courbe dans le domaine.
266 if (maxC > umax +100*eps) {
267 Standard_Real d1 = maxC - umax;
268 Standard_Real d2 = umin - minC + period;
269 if (d2 < d1) du =-period;
279 if (S->IsVPeriodic()) {
280 Standard_Real period = S->VPeriod();
281 Standard_Real eps = period*1.e-6;
282 gp_Pnt2d Pf = C2d->Value(f);
283 gp_Pnt2d Pl = C2d->Value(l);
284 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
285 Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
286 Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
287 Standard_Real dv = 0.;
288 if (minC< vmin - eps) {
289 dv = (int((vmin - minC)/period) + 1)*period;
291 if (minC > vmax + eps) {
292 dv = -(int((minC - vmax)/period) + 1)*period;
297 minC += dv; maxC += dv;
299 // Ajuste au mieux la courbe dans le domaine.
300 if (maxC > vmax +100*eps) {
301 Standard_Real d1 = maxC - vmax;
302 Standard_Real d2 = vmin - minC + period;
303 if (d2 < d1) dv =-period;
312 //=======================================================================
315 //=======================================================================
317 Standard_Real BRepOffset_Tool::Gabarit(const Handle(Geom_Curve)& aCurve)
319 GeomAdaptor_Curve GC( aCurve );
321 BndLib_Add3dCurve::Add( GC, Precision::Confusion(), aBox );
322 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dist;
323 aBox.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
324 dist = Max( (aXmax-aXmin), (aYmax-aYmin) );
325 dist = Max( dist, (aZmax-aZmin) );
329 //=======================================================================
330 //function : BuildPCurves
332 //=======================================================================
334 static void BuildPCurves (const TopoDS_Edge& E,
335 const TopoDS_Face& F)
338 Handle (Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E,F,ff,ll);
339 if (!C2d.IsNull()) return;
341 //Standard_Real Tolerance = Max(Precision::Confusion(),BRep_Tool::Tolerance(E));
342 Standard_Real Tolerance = Precision::Confusion();
344 BRepAdaptor_Surface AS(F,0);
345 BRepAdaptor_Curve AC(E);
347 //Try to find pcurve on a bound of BSpline or Bezier surface
348 Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( F );
349 Handle( Standard_Type ) typS = theSurf->DynamicType();
350 if (typS == STANDARD_TYPE(Geom_OffsetSurface))
351 typS = Handle(Geom_OffsetSurface)::DownCast (theSurf)->BasisSurface()->DynamicType();
352 if (typS == STANDARD_TYPE(Geom_BezierSurface) || typS == STANDARD_TYPE(Geom_BSplineSurface))
354 gp_Pnt fpoint = AC.Value( AC.FirstParameter() );
355 gp_Pnt lpoint = AC.Value( AC.LastParameter() );
356 TopoDS_Face theFace = BRepLib_MakeFace( theSurf, Precision::Confusion() );
357 Standard_Real U1 = 0., U2 = 0., TolProj = 1.e-4; //1.e-5;
359 TopExp_Explorer Explo;
360 Explo.Init( theFace, TopAbs_EDGE );
361 for (; Explo.More(); Explo.Next())
363 TopoDS_Edge anEdge = TopoDS::Edge( Explo.Current() );
364 BRepAdaptor_Curve aCurve( anEdge );
365 Extrema_ExtPC fextr( fpoint, aCurve );
366 if (!fextr.IsDone() || fextr.NbExt() < 1)
368 Standard_Real dist2, dist2min = RealLast();
370 for (i = 1; i <= fextr.NbExt(); i++)
372 dist2 = fextr.SquareDistance(i);
373 if (dist2 < dist2min)
376 U1 = fextr.Point(i).Parameter();
379 if (dist2min > TolProj * TolProj)
381 Extrema_ExtPC lextr( lpoint, aCurve );
382 if (!lextr.IsDone() || lextr.NbExt() <1)
384 dist2min = RealLast();
385 for (i = 1; i <= lextr.NbExt(); i++)
387 dist2 = lextr.SquareDistance(i);
388 if (dist2 < dist2min)
391 U2 = lextr.Point(i).Parameter();
394 if (dist2min <= TolProj * TolProj)
399 } // for (; Explo.More(); Explo.Current())
401 if (! theEdge.IsNull())
403 //Construction of pcurve
406 Standard_Real temp = U1;
411 C2d = BRep_Tool::CurveOnSurface( theEdge, theFace, f, l );
412 C2d = new Geom2d_TrimmedCurve( C2d, U1, U2 );
414 if (theSurf->IsUPeriodic() || theSurf->IsVPeriodic())
415 PutInBounds( F, E, C2d );
418 B.UpdateEdge( E, C2d, F, BRep_Tool::Tolerance(E) );
419 BRepLib::SameRange( E );
425 Handle(BRepAdaptor_Surface) HS = new BRepAdaptor_Surface(AS);
426 Handle(BRepAdaptor_Curve) HC = new BRepAdaptor_Curve(AC);
428 ProjLib_ProjectedCurve Proj(HS,HC,Tolerance);
430 switch ( Proj.GetType()) {
433 C2d = new Geom2d_Line(Proj.Line());
437 C2d = new Geom2d_Circle(Proj.Circle());
440 case GeomAbs_Ellipse:
441 C2d = new Geom2d_Ellipse(Proj.Ellipse());
444 case GeomAbs_Parabola:
445 C2d = new Geom2d_Parabola(Proj.Parabola());
448 case GeomAbs_Hyperbola:
449 C2d = new Geom2d_Hyperbola(Proj.Hyperbola());
452 case GeomAbs_BezierCurve:
456 case GeomAbs_BSplineCurve:
457 C2d = Proj.BSpline();
463 if (AS.IsUPeriodic() || AS.IsVPeriodic()) {
464 PutInBounds(F,E,C2d);
468 B.UpdateEdge (E,C2d,F,BRep_Tool::Tolerance(E));
471 throw Standard_ConstructionError("BRepOffset_Tool::BuildPCurves");
475 //=======================================================================
478 //=======================================================================
480 void BRepOffset_Tool::OrientSection (const TopoDS_Edge& E,
481 const TopoDS_Face& F1,
482 const TopoDS_Face& F2,
483 TopAbs_Orientation& O1,
484 TopAbs_Orientation& O2)
490 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
491 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
492 Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l);
493 Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l);
494 Handle (Geom_Curve) C = BRep_Tool::Curve(E,L,f,l);
496 BRepAdaptor_Curve BAcurve( E );
498 GCPnts_AbscissaPoint AP(BAcurve,GCPnts_AbscissaPoint::Length(BAcurve)/2.0,f);
499 Standard_Real ParOnC;
502 ParOnC = AP.Parameter();
504 ParOnC = BOPTools_AlgoTools2D::IntermediatePoint(f, l);
506 gp_Vec T1 = C->DN(ParOnC,1).Transformed(L.Transformation());
507 if (T1.SquareMagnitude() > gp::Resolution()) {
511 gp_Pnt2d P = C1->Value(ParOnC);
515 S1->D1(P.X(),P.Y(),P3,D1U,D1V);
517 if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse();
519 P = C2->Value(ParOnC);
520 S2->D1(P.X(),P.Y(),P3,D1U,D1V);
522 if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse();
524 gp_Vec ProVec = DN2^T1;
525 Standard_Real Prod = DN1.Dot(ProVec);
530 O1 = TopAbs_REVERSED;
533 Prod = DN2.Dot(ProVec);
538 O2 = TopAbs_REVERSED;
540 if (F1.Orientation() == TopAbs_REVERSED) O1 = TopAbs::Reverse(O1);
541 if (F2.Orientation() == TopAbs_REVERSED) O2 = TopAbs::Reverse(O2);
544 //=======================================================================
545 //function : FindCommonShapes
547 //=======================================================================
548 Standard_Boolean BRepOffset_Tool::FindCommonShapes(const TopoDS_Face& theF1,
549 const TopoDS_Face& theF2,
550 TopTools_ListOfShape& theLE,
551 TopTools_ListOfShape& theLV)
553 Standard_Boolean bFoundEdges =
554 FindCommonShapes(theF1, theF2, TopAbs_EDGE, theLE);
555 Standard_Boolean bFoundVerts =
556 FindCommonShapes(theF1, theF2, TopAbs_VERTEX, theLV);
557 return bFoundEdges || bFoundVerts;
560 //=======================================================================
561 //function : FindCommonShapes
563 //=======================================================================
564 Standard_Boolean BRepOffset_Tool::FindCommonShapes(const TopoDS_Shape& theS1,
565 const TopoDS_Shape& theS2,
566 const TopAbs_ShapeEnum theType,
567 TopTools_ListOfShape& theLSC)
571 TopTools_MapOfShape aMS;
572 TopExp_Explorer aExp(theS1, theType);
573 for (; aExp.More(); aExp.Next()) {
574 aMS.Add(aExp.Current());
578 return Standard_False;
581 TopTools_MapOfShape aMFence;
582 aExp.Init(theS2, theType);
583 for (; aExp.More(); aExp.Next()) {
584 const TopoDS_Shape& aS2 = aExp.Current();
585 if (aMS.Contains(aS2)) {
586 if (aMFence.Add(aS2)) {
592 return !theLSC.IsEmpty();
595 //=======================================================================
598 //=======================================================================
600 static Standard_Boolean ToSmall (const Handle(Geom_Curve)& C)
602 Standard_Real Tol = 10*Precision::Confusion();
603 Standard_Real m = (C->FirstParameter()*0.668 + C->LastParameter()*0.332);
604 gp_Pnt P1 = C->Value(C->FirstParameter());
605 gp_Pnt P2 = C->Value(C->LastParameter());
606 gp_Pnt P3 = C->Value(m);
607 if (P1.Distance(P2) > Tol) return Standard_False;
608 if (P2.Distance(P3) > Tol) return Standard_False;
609 return Standard_True;
613 //=======================================================================
614 //function : IsOnSurface
616 //=======================================================================
618 static Standard_Boolean IsOnSurface(const Handle(Geom_Curve)& C,
619 const Handle(Geom_Surface)& S,
620 Standard_Real TolConf,
621 Standard_Real& TolReached)
623 Standard_Real f = C->FirstParameter();
624 Standard_Real l = C->LastParameter();
625 Standard_Integer n = 5;
626 Standard_Real du = (f-l)/(n-1);
632 GeomAdaptor_Surface AS(S);
634 switch ( AS.GetType()) {
637 gp_Ax3 Ax = AS.Plane().Position();
638 for ( Standard_Integer i = 0; i < n; i++) {
639 P = C->Value(f+i*du);
640 ElSLib::PlaneParameters(Ax,P,U,V);
641 TolReached = P.Distance(ElSLib::PlaneValue(U,V,Ax));
642 if ( TolReached > TolConf)
643 return Standard_False;
647 case GeomAbs_Cylinder:
649 gp_Ax3 Ax = AS.Cylinder().Position();
650 Standard_Real Rad = AS.Cylinder().Radius();
651 for ( Standard_Integer i = 0; i < n; i++) {
652 P = C->Value(f+i*du);
653 ElSLib::CylinderParameters(Ax,Rad,P,U,V);
654 TolReached = P.Distance(ElSLib::CylinderValue(U,V,Ax,Rad));
655 if ( TolReached > TolConf)
656 return Standard_False;
662 gp_Ax3 Ax = AS.Cone().Position();
663 Standard_Real Rad = AS.Cone().RefRadius();
664 Standard_Real Alp = AS.Cone().SemiAngle();
665 for ( Standard_Integer i = 0; i < n; i++) {
666 P = C->Value(f+i*du);
667 ElSLib::ConeParameters(Ax,Rad,Alp,P,U,V);
668 TolReached = P.Distance(ElSLib::ConeValue(U,V,Ax,Rad,Alp));
669 if ( TolReached > TolConf)
670 return Standard_False;
676 gp_Ax3 Ax = AS.Sphere().Position();
677 Standard_Real Rad = AS.Sphere().Radius();
678 for ( Standard_Integer i = 0; i < n; i++) {
679 P = C->Value(f+i*du);
680 ElSLib::SphereParameters(Ax,Rad,P,U,V);
681 TolReached = P.Distance(ElSLib::SphereValue(U,V,Ax,Rad));
682 if ( TolReached > TolConf)
683 return Standard_False;
689 gp_Ax3 Ax = AS.Torus().Position();
690 Standard_Real R1 = AS.Torus().MajorRadius();
691 Standard_Real R2 = AS.Torus().MinorRadius();
692 for ( Standard_Integer i = 0; i < n; i++) {
693 P = C->Value(f+i*du);
694 ElSLib::TorusParameters(Ax,R1,R2,P,U,V);
695 TolReached = P.Distance(ElSLib::TorusValue(U,V,Ax,R1,R2));
696 if ( TolReached > TolConf)
697 return Standard_False;
704 return Standard_False;
708 return Standard_True;
712 //=======================================================================
713 //function : PipeInter
715 //=======================================================================
717 void BRepOffset_Tool::PipeInter(const TopoDS_Face& F1,
718 const TopoDS_Face& F2,
719 TopTools_ListOfShape& L1,
720 TopTools_ListOfShape& L2,
721 const TopAbs_State Side)
726 sprintf(name,"FF_%d",NbFaces++);
728 sprintf(name,"FF_%d",NbFaces++);
733 Handle (Geom_Curve) CI;
734 TopAbs_Orientation O1,O2;
735 L1.Clear(); L2.Clear();
737 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
738 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
740 GeomInt_IntSS Inter (S1,S2, Precision::Confusion(),1,1,1);
742 if (Inter.IsDone()) {
743 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
745 if (ToSmall(CI)) continue;
746 TopoDS_Edge E = BRepLib_MakeEdge(CI);
747 if (Inter.HasLineOnS1(i)) {
748 Handle(Geom2d_Curve) C2 = Inter.LineOnS1(i);
749 PutInBounds (F1,E,C2);
750 B.UpdateEdge (E,C2,F1,BRep_Tool::Tolerance(E));
755 if (Inter.HasLineOnS2(i)) {
756 Handle(Geom2d_Curve) C2 = Inter.LineOnS2(i);
757 PutInBounds (F2,E,C2);
758 B.UpdateEdge (E,C2,F2,BRep_Tool::Tolerance(E));
763 OrientSection (E,F1,F2,O1,O2);
764 if (Side == TopAbs_OUT) {
765 O1 = TopAbs::Reverse(O1);
766 O2 = TopAbs::Reverse(O2);
768 L1.Append (E.Oriented(O1));
769 L2.Append (E.Oriented(O2));
773 sprintf(name,"EI_%d",NbNewEdges++);
774 DBRep::Set(name,E.Oriented(O1));
781 //=======================================================================
782 //function : IsAutonomVertex
783 //purpose : Checks whether a vertex is "autonom" or not
784 //=======================================================================
786 static Standard_Boolean IsAutonomVertex(const TopoDS_Shape& theVertex,
787 const BOPDS_PDS& thePDS,
788 const TopoDS_Face& theFace1,
789 const TopoDS_Face& theFace2)
791 Standard_Integer nV = thePDS->Index(theVertex);
792 Standard_Integer nF [2];
793 nF[0] = thePDS->Index(theFace1);
794 nF[1] = thePDS->Index(theFace2);
796 for (Standard_Integer i = 0; i < 2; i++)
798 const BOPDS_FaceInfo& aFaceInfo = thePDS->FaceInfo(nF[i]);
799 const TColStd_MapOfInteger& IndMap = aFaceInfo.VerticesOn();
800 if (IndMap.Contains(nV))
801 return Standard_False;
804 return Standard_True;
807 //=======================================================================
808 //function : IsAutonomVertex
809 //purpose : Checks whether a vertex is "autonom" or not
810 //=======================================================================
812 static Standard_Boolean IsAutonomVertex(const TopoDS_Shape& aVertex,
813 const BOPDS_PDS& pDS)
815 Standard_Integer index;
816 Standard_Integer aNbVVs, aNbEEs, aNbEFs, aInt;
818 index = pDS->Index(aVertex);
820 Standard_Integer i, i1, i2;
821 i1=pDS->NbSourceShapes();
823 for (i=i1; i<i2; ++i) {
824 const TopoDS_Shape& aSx=pDS->Shape(i);
825 if(aSx.IsSame(aVertex)) {
832 if (!pDS->IsNewShape(index)) {
833 return Standard_False;
835 //check if vertex with index "index" is not created in VV or EE or EF interference
837 BOPDS_VectorOfInterfVV& aVVs=pDS->InterfVV();
838 aNbVVs = aVVs.Length();
839 for(aInt = 0; aInt < aNbVVs; aInt++) {
840 const BOPDS_InterfVV& aVV = aVVs(aInt);
841 if (aVV.HasIndexNew()) {
842 if (aVV.IndexNew() == index) {
843 return Standard_False;
848 BOPDS_VectorOfInterfEE& aEEs=pDS->InterfEE();
849 aNbEEs = aEEs.Length();
850 for(aInt = 0; aInt < aNbEEs; aInt++) {
851 const BOPDS_InterfEE& aEE = aEEs(aInt);
852 IntTools_CommonPrt aCP = aEE.CommonPart();
853 if(aCP.Type() == TopAbs_VERTEX) {
854 if (aEE.IndexNew() == index) {
855 return Standard_False;
860 BOPDS_VectorOfInterfEF& aEFs=pDS->InterfEF();
861 aNbEFs = aEFs.Length();
862 for(aInt = 0; aInt < aNbEFs; aInt++) {
863 const BOPDS_InterfEF& aEF = aEFs(aInt);
864 IntTools_CommonPrt aCP = aEF.CommonPart();
865 if(aCP.Type() == TopAbs_VERTEX) {
866 if (aEF.IndexNew() == index) {
867 return Standard_False;
871 return Standard_True;
875 //=======================================================================
876 //function : AreConnex
877 //purpose : define if two shapes are connex by a vertex (vertices)
878 //=======================================================================
880 static Standard_Boolean AreConnex(const TopoDS_Wire& W1,
881 const TopoDS_Wire& W2)
883 TopoDS_Vertex V11, V12, V21, V22;
884 TopExp::Vertices( W1, V11, V12 );
885 TopExp::Vertices( W2, V21, V22 );
887 if (V11.IsSame(V21) || V11.IsSame(V22) ||
888 V12.IsSame(V21) || V12.IsSame(V22))
889 return Standard_True;
891 return Standard_False;
894 //=======================================================================
895 //function : AreClosed
896 //purpose : define if two edges are connex by two vertices
897 //=======================================================================
899 static Standard_Boolean AreClosed(const TopoDS_Edge& E1,
900 const TopoDS_Edge& E2)
902 TopoDS_Vertex V11, V12, V21, V22;
903 TopExp::Vertices( E1, V11, V12 );
904 TopExp::Vertices( E2, V21, V22 );
906 if ((V11.IsSame(V21) && V12.IsSame(V22)) ||
907 (V11.IsSame(V22) && V12.IsSame(V21)))
908 return Standard_True;
910 return Standard_False;
913 //=======================================================================
914 //function : BSplineEdges
916 //=======================================================================
918 static Standard_Boolean BSplineEdges(const TopoDS_Edge& E1,
919 const TopoDS_Edge& E2,
920 const Standard_Integer par1,
921 const Standard_Integer par2,
922 Standard_Real& angle)
924 Standard_Real first1, last1, first2, last2, Param1, Param2;
926 Handle(Geom_Curve) C1 = BRep_Tool::Curve( E1, first1, last1 );
927 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
928 C1 = Handle(Geom_TrimmedCurve)::DownCast (C1)->BasisCurve();
930 Handle(Geom_Curve) C2 = BRep_Tool::Curve( E2, first2, last2 );
931 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
932 C2 = Handle(Geom_TrimmedCurve)::DownCast (C2)->BasisCurve();
934 if (!C1->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)) ||
935 !C2->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)))
936 return Standard_False;
938 Param1 = (par1 == 0)? first1 : last1;
939 Param2 = (par2 == 0)? first2 : last2;
943 C1->D1( Param1, Pnt1, Der1 );
944 C2->D1( Param2, Pnt2, Der2 );
946 if (Der1.Magnitude() <= gp::Resolution() ||
947 Der2.Magnitude() <= gp::Resolution())
950 angle = Der1.Angle(Der2);
952 return Standard_True;
955 //=======================================================================
956 //function : AngleWireEdge
958 //=======================================================================
960 static Standard_Real AngleWireEdge(const TopoDS_Wire& aWire,
961 const TopoDS_Edge& anEdge)
963 TopoDS_Vertex V11, V12, V21, V22, CV;
964 TopExp::Vertices( aWire, V11, V12 );
965 TopExp::Vertices( anEdge, V21, V22 );
966 CV = (V11.IsSame(V21) || V11.IsSame(V22))? V11 : V12;
967 TopoDS_Edge FirstEdge;
968 TopoDS_Iterator itw(aWire);
969 for (; itw.More(); itw.Next())
971 FirstEdge = TopoDS::Edge(itw.Value());
972 TopoDS_Vertex v1, v2;
973 TopExp::Vertices( FirstEdge, v1, v2 );
974 if (v1.IsSame(CV) || v2.IsSame(CV))
982 if (V11.IsSame(CV) && V21.IsSame(CV))
984 BSplineEdges( FirstEdge, anEdge, 0, 0, Angle );
985 Angle = M_PI - Angle;
987 else if (V11.IsSame(CV) && V22.IsSame(CV))
988 BSplineEdges( FirstEdge, anEdge, 0, 1, Angle );
989 else if (V12.IsSame(CV) && V21.IsSame(CV))
990 BSplineEdges( FirstEdge, anEdge, 1, 0, Angle );
993 BSplineEdges( FirstEdge, anEdge, 1, 1, Angle );
994 Angle = M_PI - Angle;
1000 //=======================================================================
1001 //function : ReconstructPCurves
1003 //=======================================================================
1005 static void ReconstructPCurves(const TopoDS_Edge& anEdge)
1008 Handle(Geom_Curve) C3d = BRep_Tool::Curve(anEdge, f, l);
1010 BRep_ListIteratorOfListOfCurveRepresentation
1011 itcr( (Handle(BRep_TEdge)::DownCast(anEdge.TShape()))->ChangeCurves() );
1012 for (; itcr.More(); itcr.Next())
1014 Handle( BRep_CurveRepresentation ) CurveRep = itcr.Value();
1015 if (CurveRep->IsCurveOnSurface())
1017 Handle(Geom_Surface) theSurf = CurveRep->Surface();
1018 TopLoc_Location theLoc = CurveRep->Location();
1019 theLoc = anEdge.Location() * theLoc;
1020 theSurf = Handle(Geom_Surface)::DownCast
1021 (theSurf->Transformed(theLoc.Transformation()));
1022 Handle(Geom2d_Curve) ProjPCurve =
1023 GeomProjLib::Curve2d( C3d, f, l, theSurf );
1024 if(!ProjPCurve.IsNull())
1026 CurveRep->PCurve( ProjPCurve );
1032 //=======================================================================
1033 //function : ConcatPCurves
1035 //=======================================================================
1037 static Handle(Geom2d_Curve) ConcatPCurves(const TopoDS_Edge& E1,
1038 const TopoDS_Edge& E2,
1039 const TopoDS_Face& F,
1040 const Standard_Boolean After,
1041 Standard_Real& newFirst,
1042 Standard_Real& newLast)
1044 Standard_Real Tol = 1.e-7;
1045 GeomAbs_Shape Continuity = GeomAbs_C1;
1046 Standard_Integer MaxDeg = 14;
1047 Standard_Integer MaxSeg = 16;
1049 Standard_Real first1, last1, first2, last2;
1050 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1052 PCurve1 = BRep_Tool::CurveOnSurface( E1, F, first1, last1 );
1053 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
1054 PCurve1 = Handle(Geom2d_TrimmedCurve)::DownCast (PCurve1)->BasisCurve();
1056 PCurve2 = BRep_Tool::CurveOnSurface( E2, F, first2, last2 );
1057 if (PCurve2->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
1058 PCurve2 = Handle(Geom2d_TrimmedCurve)::DownCast (PCurve2)->BasisCurve();
1060 if (PCurve1 == PCurve2)
1062 newPCurve = PCurve1;
1063 newFirst = Min( first1, first2 );
1064 newLast = Max( last1, last2 );
1066 else if (PCurve1->DynamicType() == PCurve2->DynamicType() &&
1067 (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)) ||
1068 PCurve1->IsKind(STANDARD_TYPE(Geom2d_Conic))))
1070 newPCurve = PCurve1;
1072 P1 = PCurve2->Value( first2 );
1073 P2 = PCurve2->Value( last2 );
1074 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)))
1076 Handle(Geom2d_Line) Lin1 = Handle(Geom2d_Line)::DownCast (PCurve1);
1077 gp_Lin2d theLin = Lin1->Lin2d();
1078 first2 = ElCLib::Parameter( theLin, P1 );
1079 last2 = ElCLib::Parameter( theLin, P2 );
1081 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Circle)))
1083 Handle(Geom2d_Circle) Circ1 = Handle(Geom2d_Circle)::DownCast (PCurve1);
1084 gp_Circ2d theCirc = Circ1->Circ2d();
1085 first2 = ElCLib::Parameter( theCirc, P1 );
1086 last2 = ElCLib::Parameter( theCirc, P2 );
1088 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Ellipse)))
1090 Handle(Geom2d_Ellipse) Ell1 = Handle(Geom2d_Ellipse)::DownCast (PCurve1);
1091 gp_Elips2d theElips = Ell1->Elips2d();
1092 first2 = ElCLib::Parameter( theElips, P1 );
1093 last2 = ElCLib::Parameter( theElips, P2 );
1095 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Parabola)))
1097 Handle(Geom2d_Parabola) Parab1 = Handle(Geom2d_Parabola)::DownCast (PCurve1);
1098 gp_Parab2d theParab = Parab1->Parab2d();
1099 first2 = ElCLib::Parameter( theParab, P1 );
1100 last2 = ElCLib::Parameter( theParab, P2 );
1102 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Hyperbola)))
1104 Handle(Geom2d_Hyperbola) Hypr1 = Handle(Geom2d_Hyperbola)::DownCast (PCurve1);
1105 gp_Hypr2d theHypr = Hypr1->Hypr2d();
1106 first2 = ElCLib::Parameter( theHypr, P1 );
1107 last2 = ElCLib::Parameter( theHypr, P2 );
1109 newFirst = Min( first1, first2 );
1110 newLast = Max( last1, last2 );
1114 Handle(Geom2d_TrimmedCurve) TC1 = new Geom2d_TrimmedCurve( PCurve1, first1, last1 );
1115 Handle(Geom2d_TrimmedCurve) TC2 = new Geom2d_TrimmedCurve( PCurve2, first2, last2 );
1116 Geom2dConvert_CompCurveToBSplineCurve Concat2d( TC1 );
1117 Concat2d.Add( TC2, Precision::Confusion(), After );
1118 newPCurve = Concat2d.BSplineCurve();
1119 if (newPCurve->Continuity() < GeomAbs_C1)
1121 Geom2dConvert_ApproxCurve Approx2d( newPCurve, Tol, Continuity, MaxSeg, MaxDeg );
1122 if (Approx2d.HasResult())
1123 newPCurve = Approx2d.Curve();
1125 newFirst = newPCurve->FirstParameter();
1126 newLast = newPCurve->LastParameter();
1132 //=======================================================================
1134 //purpose : glue two edges.
1135 //=======================================================================
1137 static TopoDS_Edge Glue(const TopoDS_Edge& E1,
1138 const TopoDS_Edge& E2,
1139 const TopoDS_Vertex& Vfirst,
1140 const TopoDS_Vertex& Vlast,
1141 const Standard_Boolean After,
1142 const TopoDS_Face& F1,
1143 const Standard_Boolean addPCurve1,
1144 const TopoDS_Face& F2,
1145 const Standard_Boolean addPCurve2,
1146 const Standard_Real theGlueTol)
1148 TopoDS_Edge newEdge;
1150 Standard_Real Tol = 1.e-7;
1151 GeomAbs_Shape Continuity = GeomAbs_C1;
1152 Standard_Integer MaxDeg = 14;
1153 Standard_Integer MaxSeg = 16;
1155 Handle(Geom_Curve) C1, C2, newCurve;
1156 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1157 Standard_Real first1, last1, first2, last2, fparam=0., lparam=0.;
1158 Standard_Boolean IsCanonic = Standard_False;
1160 C1 = BRep_Tool::Curve( E1, first1, last1 );
1161 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
1162 C1 = Handle(Geom_TrimmedCurve)::DownCast (C1)->BasisCurve();
1164 C2 = BRep_Tool::Curve( E2, first2, last2 );
1165 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
1166 C2 = Handle(Geom_TrimmedCurve)::DownCast (C2)->BasisCurve();
1171 fparam = Min( first1, first2 );
1172 lparam = Max( last1, last2 );
1174 else if (C1->DynamicType() == C2->DynamicType() &&
1175 (C1->IsInstance(STANDARD_TYPE(Geom_Line)) ||
1176 C1->IsKind(STANDARD_TYPE(Geom_Conic))))
1178 IsCanonic = Standard_True;
1183 Handle(Geom_TrimmedCurve) TC1 = new Geom_TrimmedCurve( C1, first1, last1 );
1184 Handle(Geom_TrimmedCurve) TC2 = new Geom_TrimmedCurve( C2, first2, last2 );
1185 GeomConvert_CompCurveToBSplineCurve Concat( TC1 );
1186 if (!Concat.Add( TC2, theGlueTol, After ))
1188 newCurve = Concat.BSplineCurve();
1189 if (newCurve->Continuity() < GeomAbs_C1)
1191 GeomConvert_ApproxCurve Approx3d( newCurve, Tol, Continuity, MaxSeg, MaxDeg );
1192 if (Approx3d.HasResult())
1193 newCurve = Approx3d.Curve();
1195 fparam = newCurve->FirstParameter();
1196 lparam = newCurve->LastParameter();
1202 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast );
1204 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast, fparam, lparam );
1206 Standard_Real newFirst, newLast;
1209 newPCurve = ConcatPCurves( E1, E2, F1, After, newFirst, newLast );
1210 BB.UpdateEdge( newEdge, newPCurve, F1, 0. );
1211 BB.Range( newEdge, F1, newFirst, newLast );
1215 newPCurve = ConcatPCurves( E1, E2, F2, After, newFirst, newLast );
1216 BB.UpdateEdge( newEdge, newPCurve, F2, 0. );
1217 BB.Range( newEdge, F2, newFirst, newLast );
1223 //=======================================================================
1224 //function : CheckIntersFF
1226 //=======================================================================
1228 static void CheckIntersFF(const BOPDS_PDS& pDS,
1229 const TopoDS_Edge& RefEdge,
1230 TopTools_IndexedMapOfShape& TrueEdges)
1232 BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF();
1233 Standard_Integer aNb = aFFs.Length();
1234 Standard_Integer i, j, nbe = 0;
1236 TopoDS_Compound Edges;
1238 BB.MakeCompound(Edges);
1240 for (i = 0; i < aNb; ++i)
1242 BOPDS_InterfFF& aFFi=aFFs(i);
1243 const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
1244 Standard_Integer aNbCurves = aBCurves.Length();
1246 for (j = 0; j < aNbCurves; ++j)
1248 const BOPDS_Curve& aBC=aBCurves(j);
1249 const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
1251 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1252 aPBIt.Initialize(aSectEdges);
1254 for (; aPBIt.More(); aPBIt.Next())
1256 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
1257 Standard_Integer nSect = aPB->Edge();
1258 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
1259 BB.Add(Edges, anEdge);
1268 TopTools_ListOfShape CompList;
1269 BOPTools_AlgoTools::MakeConnexityBlocks(Edges, TopAbs_VERTEX, TopAbs_EDGE, CompList);
1271 TopoDS_Shape NearestCompound;
1272 if (CompList.Extent() == 1)
1273 NearestCompound = CompList.First();
1276 BRepAdaptor_Curve BAcurve(RefEdge);
1277 gp_Pnt Pref = BAcurve.Value((BAcurve.FirstParameter()+BAcurve.LastParameter())/2);
1278 TopoDS_Vertex Vref = BRepLib_MakeVertex(Pref);
1279 Standard_Real MinDist = RealLast();
1280 TopTools_ListIteratorOfListOfShape itl(CompList);
1281 for (; itl.More(); itl.Next())
1283 const TopoDS_Shape& aCompound = itl.Value();
1285 BRepExtrema_DistShapeShape Projector(Vref, aCompound);
1286 if (!Projector.IsDone() || Projector.NbSolution() == 0)
1289 Standard_Real aDist = Projector.Value();
1290 if (aDist < MinDist)
1293 NearestCompound = aCompound;
1298 TopExp::MapShapes(NearestCompound, TopAbs_EDGE, TrueEdges);
1301 //=======================================================================
1302 //function : AssembleEdge
1304 //=======================================================================
1306 static TopoDS_Edge AssembleEdge(const BOPDS_PDS& pDS,
1307 const TopoDS_Face& F1,
1308 const TopoDS_Face& F2,
1309 const Standard_Boolean addPCurve1,
1310 const Standard_Boolean addPCurve2,
1311 const TopTools_SequenceOfShape& EdgesForConcat)
1313 TopoDS_Edge NullEdge;
1314 TopoDS_Edge CurEdge = TopoDS::Edge( EdgesForConcat(1) );
1315 Standard_Real aGlueTol = Precision::Confusion();
1317 for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
1319 TopoDS_Edge anEdge = TopoDS::Edge( EdgesForConcat(j) );
1320 Standard_Boolean After = Standard_False;
1321 TopoDS_Vertex Vfirst, Vlast;
1322 Standard_Boolean AreClosedWire = AreClosed( CurEdge, anEdge );
1325 TopoDS_Vertex V1, V2;
1326 TopExp::Vertices( CurEdge, V1, V2 );
1327 Standard_Boolean IsAutonomV1 = IsAutonomVertex( V1, pDS, F1, F2 );
1328 Standard_Boolean IsAutonomV2 = IsAutonomVertex( V2, pDS, F1, F2 );
1331 After = Standard_False;
1332 Vfirst = Vlast = V2;
1334 else if (IsAutonomV2)
1336 After = Standard_True;
1337 Vfirst = Vlast = V1;
1344 TopoDS_Vertex CV, V11, V12, V21, V22;
1345 TopExp::CommonVertex( CurEdge, anEdge, CV );
1346 Standard_Boolean IsAutonomCV = Standard_False;
1349 IsAutonomCV = IsAutonomVertex(CV, pDS, F1, F2);
1353 aGlueTol = BRep_Tool::Tolerance(CV);
1354 TopExp::Vertices( CurEdge, V11, V12 );
1355 TopExp::Vertices( anEdge, V21, V22 );
1356 if (V11.IsSame(CV) && V21.IsSame(CV))
1361 else if (V11.IsSame(CV) && V22.IsSame(CV))
1366 else if (V12.IsSame(CV) && V21.IsSame(CV))
1379 } //end of else (open wire)
1381 TopoDS_Edge NewEdge = Glue(CurEdge, anEdge, Vfirst, Vlast, After,
1382 F1, addPCurve1, F2, addPCurve2, aGlueTol);
1383 if (NewEdge.IsNull())
1387 } //end of for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
1392 //=======================================================================
1393 //function : Inter3D
1395 //=======================================================================
1397 void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1,
1398 const TopoDS_Face& F2,
1399 TopTools_ListOfShape& L1,
1400 TopTools_ListOfShape& L2,
1401 const TopAbs_State Side,
1402 const TopoDS_Edge& RefEdge,
1403 const Standard_Boolean IsRefEdgeDefined)
1408 sprintf(name,"FF_%d",NbFaces++);
1409 DBRep::Set(name,F1);
1410 sprintf(name,"FF_%d",NbFaces++);
1411 DBRep::Set(name,F2);
1415 // Check if the faces are planar and not trimmed - in this case
1416 // the IntTools_FaceFace intersection algorithm will be used directly.
1417 BRepAdaptor_Surface aBAS1(F1, Standard_False), aBAS2(F2, Standard_False);
1418 if (aBAS1.GetType() == GeomAbs_Plane &&
1419 aBAS2.GetType() == GeomAbs_Plane) {
1420 aBAS1.Initialize(F1, Standard_True);
1421 if (IsInf(aBAS1.LastUParameter()) && IsInf(aBAS1.LastVParameter())) {
1422 aBAS2.Initialize(F2, Standard_True);
1423 if (IsInf(aBAS2.LastUParameter()) && IsInf(aBAS2.LastVParameter())) {
1424 // Intersect the planes without pave filler
1425 PerformPlanes(F1, F2, Side, L1, L2);
1431 // create 3D curves on faces
1432 BRepLib::BuildCurves3d(F1);
1433 BRepLib::BuildCurves3d(F2);
1434 UpdateVertexTolerances(F1);
1435 UpdateVertexTolerances(F2);
1437 BOPAlgo_PaveFiller aPF;
1438 TopTools_ListOfShape aLS;
1441 aPF.SetArguments(aLS);
1445 TopTools_IndexedMapOfShape TrueEdges;
1446 if (IsRefEdgeDefined)
1447 CheckIntersFF( aPF.PDS(), RefEdge, TrueEdges );
1449 Standard_Boolean addPCurve1 = 1;
1450 Standard_Boolean addPCurve2 = 1;
1452 const BOPDS_PDS& pDS = aPF.PDS();
1453 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
1454 Standard_Integer aNb = aFFs.Length();
1455 Standard_Integer i = 0, j = 0, k;
1457 L1.Clear(); L2.Clear();
1458 TopAbs_Orientation O1,O2;
1461 const Handle(IntTools_Context)& aContext = aPF.Context();
1463 for (i = 0; i < aNb; i++) {
1464 BOPDS_InterfFF& aFFi=aFFs(i);
1465 const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
1467 Standard_Integer aNbCurves = aBCurves.Length();
1469 for (j = 0; j < aNbCurves; j++) {
1470 const BOPDS_Curve& aBC=aBCurves(j);
1471 const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
1473 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1474 aPBIt.Initialize(aSectEdges);
1476 for (; aPBIt.More(); aPBIt.Next()) {
1477 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
1478 Standard_Integer nSect = aPB->Edge();
1479 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
1480 if (!TrueEdges.IsEmpty() && !TrueEdges.Contains(anEdge))
1484 const Handle(Geom_Curve)& aC3DE = BRep_Tool::Curve(anEdge, f, l);
1485 Handle(Geom_TrimmedCurve) aC3DETrim;
1488 aC3DETrim = new Geom_TrimmedCurve(aC3DE, f, l);
1490 Standard_Real aTolEdge = BRep_Tool::Tolerance(anEdge);
1492 if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F1)) {
1493 Handle(Geom2d_Curve) aC2d = aBC.Curve().FirstCurve2d();
1494 if(!aC3DETrim.IsNull()) {
1495 Handle(Geom2d_Curve) aC2dNew;
1497 if(aC3DE->IsPeriodic()) {
1498 BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, f, l, aC2d, aC2dNew, aContext);
1501 BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, aC3DETrim, aC2d, aC2dNew, aContext);
1505 BB.UpdateEdge(anEdge, aC2d, F1, aTolEdge);
1508 if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F2)) {
1509 Handle(Geom2d_Curve) aC2d = aBC.Curve().SecondCurve2d();
1510 if(!aC3DETrim.IsNull()) {
1511 Handle(Geom2d_Curve) aC2dNew;
1513 if(aC3DE->IsPeriodic()) {
1514 BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, f, l, aC2d, aC2dNew, aContext);
1517 BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, aC3DETrim, aC2d, aC2dNew, aContext);
1521 BB.UpdateEdge(anEdge, aC2d, F2, aTolEdge);
1524 OrientSection (anEdge, F1, F2, O1, O2);
1525 if (Side == TopAbs_OUT) {
1526 O1 = TopAbs::Reverse(O1);
1527 O2 = TopAbs::Reverse(O2);
1530 L1.Append (anEdge.Oriented(O1));
1531 L2.Append (anEdge.Oriented(O2));
1536 sprintf(name,"EI_%d",NbNewEdges++);
1537 DBRep::Set(name,anEdge.Oriented(O1));
1545 Standard_Real aSameParTol = Precision::Confusion();
1546 Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
1548 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F1);
1549 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1550 aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
1551 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1552 addPCurve1 = Standard_False;
1553 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1554 isEl1 = Standard_True;
1556 aSurf = BRep_Tool::Surface(F2);
1557 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1558 aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
1559 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1560 addPCurve2 = Standard_False;
1561 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1562 isEl2 = Standard_True;
1564 if (L1.Extent() > 1 && (!isEl1 || !isEl2)) {
1565 TopTools_SequenceOfShape eseq;
1566 TopTools_SequenceOfShape EdgesForConcat;
1568 if (!TrueEdges.IsEmpty())
1570 for (i = TrueEdges.Extent(); i >= 1; i--)
1571 EdgesForConcat.Append( TrueEdges(i) );
1572 TopoDS_Edge AssembledEdge =
1573 AssembleEdge( pDS, F1, F2, addPCurve1, addPCurve2, EdgesForConcat );
1574 if (AssembledEdge.IsNull())
1575 for (i = TrueEdges.Extent(); i >= 1; i--)
1576 eseq.Append( TrueEdges(i) );
1578 eseq.Append(AssembledEdge);
1582 TopTools_SequenceOfShape wseq;
1583 TopTools_SequenceOfShape edges;
1584 TopTools_ListIteratorOfListOfShape itl(L1);
1585 for (; itl.More(); itl.Next())
1586 edges.Append( itl.Value() );
1587 while (!edges.IsEmpty())
1589 TopoDS_Edge anEdge = TopoDS::Edge( edges.First() );
1590 TopoDS_Wire aWire, resWire;
1592 BB.Add( aWire, anEdge );
1593 TColStd_SequenceOfInteger Candidates;
1594 for (k = 1; k <= wseq.Length(); k++)
1596 resWire = TopoDS::Wire(wseq(k));
1597 if (AreConnex( resWire, aWire ))
1599 Candidates.Append( 1 );
1603 if (Candidates.IsEmpty())
1605 wseq.Append( aWire );
1610 for (j = 2; j <= edges.Length(); j++)
1612 anEdge = TopoDS::Edge( edges(j) );
1615 BB.Add( aWire, anEdge );
1616 if (AreConnex( resWire, aWire ))
1617 Candidates.Append( j );
1619 Standard_Integer minind = 1;
1620 if (Candidates.Length() > 1)
1622 Standard_Real MinAngle = RealLast();
1623 for (j = 1; j <= Candidates.Length(); j++)
1625 anEdge = TopoDS::Edge( edges(Candidates(j)) );
1626 Standard_Real anAngle = AngleWireEdge( resWire, anEdge );
1627 if (anAngle < MinAngle)
1634 BB.Add( resWire, TopoDS::Edge(edges(Candidates(minind))) );
1636 edges.Remove(Candidates(minind));
1638 } //end of while (!edges.IsEmpty())
1640 for (i = 1; i <= wseq.Length(); i++)
1642 TopoDS_Wire aWire = TopoDS::Wire(wseq(i));
1643 TopTools_SequenceOfShape aLocalEdgesForConcat;
1646 TopoDS_Vertex StartVertex;
1647 TopoDS_Edge StartEdge;
1648 Standard_Boolean StartFound = Standard_False;
1649 TopTools_ListOfShape Elist;
1651 TopoDS_Iterator itw(aWire);
1652 for (; itw.More(); itw.Next())
1654 TopoDS_Edge anEdge = TopoDS::Edge(itw.Value());
1656 Elist.Append(anEdge);
1659 TopoDS_Vertex V1, V2;
1660 TopExp::Vertices( anEdge, V1, V2 );
1661 if (!IsAutonomVertex( V1, pDS ))
1665 StartFound = Standard_True;
1667 else if (!IsAutonomVertex( V2, pDS ))
1671 StartFound = Standard_True;
1674 Elist.Append(anEdge);
1676 } //end of for (; itw.More(); itw.Next())
1679 itl.Initialize(Elist);
1680 StartEdge = TopoDS::Edge(itl.Value());
1682 TopoDS_Vertex V1, V2;
1683 TopExp::Vertices( StartEdge, V1, V2 );
1686 aLocalEdgesForConcat.Append( StartEdge );
1687 while (!Elist.IsEmpty())
1689 for (itl.Initialize(Elist); itl.More(); itl.Next())
1691 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
1692 TopoDS_Vertex V1, V2;
1693 TopExp::Vertices( anEdge, V1, V2 );
1694 if (V1.IsSame(StartVertex))
1697 aLocalEdgesForConcat.Append( anEdge );
1701 else if (V2.IsSame(StartVertex))
1704 aLocalEdgesForConcat.Append( anEdge );
1709 } //end of while (!Elist.IsEmpty())
1710 } //end of if (aWire.Closed())
1713 BRepTools_WireExplorer Wexp( aWire );
1714 for (; Wexp.More(); Wexp.Next())
1715 aLocalEdgesForConcat.Append( Wexp.Current() );
1718 TopoDS_Edge AssembledEdge =
1719 AssembleEdge( pDS, F1, F2, addPCurve1, addPCurve2, aLocalEdgesForConcat );
1720 if (AssembledEdge.IsNull())
1721 for (j = aLocalEdgesForConcat.Length(); j >= 1; j--)
1722 eseq.Append( aLocalEdgesForConcat(j) );
1724 eseq.Append( AssembledEdge );
1726 } //end of else (when TrueEdges is empty)
1728 if (eseq.Length() < L1.Extent())
1732 for (i = 1; i <= eseq.Length(); i++)
1734 TopoDS_Shape aShape = eseq(i);
1735 TopoDS_Edge anEdge = TopoDS::Edge(eseq(i));
1736 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1737 Standard_Real EdgeTol = BRep_Tool::Tolerance(anEdge);
1739 std::cout<<"Tolerance of glued E = "<<EdgeTol<<std::endl;
1741 if (EdgeTol > 1.e-2)
1744 if (EdgeTol >= 1.e-4)
1746 ReconstructPCurves(anEdge);
1747 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1749 std::cout<<"After projection tol of E = "<<BRep_Tool::Tolerance(anEdge)<<std::endl;
1753 OrientSection( anEdge, F1, F2, O1, O2 );
1754 if (Side == TopAbs_OUT)
1756 O1 = TopAbs::Reverse(O1);
1757 O2 = TopAbs::Reverse(O2);
1760 L1.Append( anEdge.Oriented(O1) );
1761 L2.Append( anEdge.Oriented(O2) );
1764 } //end of if (L1.Extent() > 1)
1768 TopTools_ListIteratorOfListOfShape itl(L1);
1769 for (; itl.More(); itl.Next())
1771 const TopoDS_Edge& anEdge = TopoDS::Edge( itl.Value() );
1772 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1777 //=======================================================================
1778 //function : TryProject
1780 //=======================================================================
1782 Standard_Boolean BRepOffset_Tool::TryProject
1783 (const TopoDS_Face& F1,
1784 const TopoDS_Face& F2,
1785 const TopTools_ListOfShape& Edges,
1786 TopTools_ListOfShape& LInt1,
1787 TopTools_ListOfShape& LInt2,
1788 const TopAbs_State Side,
1789 const Standard_Real TolConf)
1794 sprintf(name,"FF_%d",NbFaces++);
1795 DBRep::Set(name,F1);
1796 sprintf(name,"FF_%d",NbFaces++);
1797 DBRep::Set(name,F2);
1801 // try to find if the edges <Edges> are laying on the face F1.
1802 LInt1.Clear(); LInt2.Clear();
1803 TopTools_ListIteratorOfListOfShape it(Edges);
1804 Standard_Boolean isOk = Standard_True;
1805 Standard_Boolean Ok = Standard_True;
1806 TopAbs_Orientation O1,O2;
1807 Handle(Geom_Surface) Bouchon = BRep_Tool::Surface(F1);
1810 for ( ; it.More(); it.Next()) {
1813 TopoDS_Edge CurE = TopoDS::Edge(it.Value());
1814 Handle(Geom_Curve) C = BRep_Tool::Curve(CurE,L,f,l);
1816 BRepLib::BuildCurve3d(CurE,BRep_Tool::Tolerance(CurE));
1817 C = BRep_Tool::Curve(CurE,L,f,l);
1819 C = new Geom_TrimmedCurve(C,f,l);
1820 if ( !L.IsIdentity()) C->Transform(L);
1821 Standard_Real TolReached;
1822 isOk = IsOnSurface(C,Bouchon,TolConf,TolReached);
1825 B.UpdateEdge(CurE,TolReached);
1826 BuildPCurves(CurE,F1);
1827 OrientSection (CurE,F1,F2,O1,O2);
1828 if (Side == TopAbs_OUT) {
1829 O1 = TopAbs::Reverse(O1);
1830 O2 = TopAbs::Reverse(O2);
1832 LInt1.Append (CurE.Oriented(O1));
1833 LInt2.Append (CurE.Oriented(O2));
1837 sprintf(name,"EI_%d",NbNewEdges++);
1838 DBRep::Set(name,CurE.Oriented(O1));
1843 Ok = Standard_False;
1849 //=======================================================================
1850 //function : InterOrExtent
1852 //=======================================================================
1854 void BRepOffset_Tool::InterOrExtent(const TopoDS_Face& F1,
1855 const TopoDS_Face& F2,
1856 TopTools_ListOfShape& L1,
1857 TopTools_ListOfShape& L2,
1858 const TopAbs_State Side)
1863 sprintf(name,"FF_%d",NbFaces++);
1864 DBRep::Set(name,F1);
1865 sprintf(name,"FF_%d",NbFaces++);
1866 DBRep::Set(name,F2);
1870 Handle (Geom_Curve) CI;
1871 TopAbs_Orientation O1,O2;
1872 L1.Clear(); L2.Clear();
1873 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
1874 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
1876 if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1877 Handle(Geom_RectangularTrimmedSurface) RTS ;
1878 RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S1);
1879 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
1880 S1 = RTS->BasisSurface();
1883 if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1884 Handle(Geom_RectangularTrimmedSurface) RTS ;
1885 RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S2);
1886 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
1887 S2 = RTS->BasisSurface();
1891 GeomInt_IntSS Inter (S1,S2, Precision::Confusion());
1893 if (Inter.IsDone()) {
1894 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
1897 if (ToSmall(CI)) continue;
1898 TopoDS_Edge E = BRepLib_MakeEdge(CI);
1899 BuildPCurves (E,F1);
1900 BuildPCurves (E,F2);
1901 OrientSection (E,F1,F2,O1,O2);
1902 if (Side == TopAbs_OUT) {
1903 O1 = TopAbs::Reverse(O1);
1904 O2 = TopAbs::Reverse(O2);
1906 L1.Append (E.Oriented(O1));
1907 L2.Append (E.Oriented(O2));
1911 sprintf(name,"EI_%d",NbNewEdges++);
1912 DBRep::Set(name,E.Oriented(O1));
1919 //=======================================================================
1920 //function : ExtentEdge
1922 //=======================================================================
1924 static void ExtentEdge(const TopoDS_Face& F,
1925 const TopoDS_Face& EF,
1926 const TopoDS_Edge& E,
1929 BRepAdaptor_Curve CE(E);
1930 GeomAbs_CurveType Type = CE.GetType();
1931 TopoDS_Shape aLocalEdge = E.EmptyCopied();
1932 NE = TopoDS::Edge(aLocalEdge);
1933 // NE = TopoDS::Edge(E.EmptyCopied());
1935 if (Type == GeomAbs_Line || Type == GeomAbs_Circle || Type == GeomAbs_Ellipse ||
1936 Type == GeomAbs_Hyperbola || Type == GeomAbs_Parabola) {
1939 // Extension en tangence jusqu'au bord de la surface.
1940 Standard_Real PMax = 1.e2;
1942 Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
1943 Standard_Real umin,umax,vmin,vmax;
1945 S->Bounds(umin,umax,vmin,vmax);
1946 umin = Max(umin,-PMax);vmin = Max(vmin,-PMax);
1947 umax = Min(umax, PMax);vmax = Min(vmax, PMax);
1951 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f,l);
1953 //calcul point cible . ie point d'intersection du prolongement tangent et des bords.
1956 C2d->D1(CE.FirstParameter(),P,Tang);
1957 Standard_Real tx,ty,tmin;
1958 tx = ty = Precision::Infinite();
1959 if (Abs(Tang.X()) > Precision::Confusion())
1960 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
1961 if (Abs(Tang.Y()) > Precision::Confusion())
1962 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
1965 gp_Pnt2d PF2d (P.X() - Tang.X(),P.Y() - Tang.Y());
1967 C2d->D1(CE.LastParameter(),P,Tang);
1968 tx = ty = Precision::Infinite();
1969 if (Abs(Tang.X()) > Precision::Confusion())
1970 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
1971 if (Abs(Tang.Y()) > Precision::Confusion())
1972 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
1975 gp_Pnt2d PL2d (P.X() + Tang.X(),P.Y() + Tang.Y());
1977 Handle(Geom_Curve) CC = GeomAPI::To3d(C2d,gp_Pln(gp::XOY()));
1978 gp_Pnt PF(PF2d.X(),PF2d.Y(),0.);
1979 gp_Pnt PL(PL2d.X(),PL2d.Y(),0.);
1981 Handle(Geom_BoundedCurve) ExtC = Handle(Geom_BoundedCurve)::DownCast(CC);
1982 if (ExtC.IsNull()) return;
1984 GeomLib::ExtendCurveToPoint(ExtC,PF,1,0);
1985 GeomLib::ExtendCurveToPoint(ExtC,PL,1,1);
1987 Handle(Geom2d_Curve) CNE2d = GeomAPI::To2d(ExtC,gp_Pln(gp::XOY()));
1989 //Construction de la nouvelle arrete;
1992 // B.UpdateEdge (NE,CNE2d,F,BRep_Tool::Tolerance(E));
1993 B.UpdateEdge (NE,CNE2d,EF,BRep_Tool::Tolerance(E));
1994 B.Range (NE,CNE2d->FirstParameter(), CNE2d->LastParameter());
1995 NE.Orientation(E.Orientation());
1999 sprintf (name,"F_%d",NbExtE);
2000 DBRep::Set(name,EF);
2001 sprintf (name,"OE_%d",NbExtE);
2002 DBRep::Set (name,E);
2003 sprintf (name,"ExtE_%d",NbExtE++);
2004 DBRep::Set(name,NE);
2009 //=======================================================================
2010 //function : ProjectVertexOnEdge
2012 //=======================================================================
2014 static Standard_Boolean ProjectVertexOnEdge(TopoDS_Vertex& V,
2015 const TopoDS_Edge& E,
2016 Standard_Real TolConf)
2026 Standard_Real U = 0.;
2028 Standard_Boolean found = Standard_False;
2030 gp_Pnt P = BRep_Tool::Pnt (V);
2031 BRepAdaptor_Curve C = BRepAdaptor_Curve(E);
2032 f = C.FirstParameter(); l = C.LastParameter();
2034 if (V.Orientation() == TopAbs_FORWARD) {
2035 if (Abs(f) < Precision::Infinite()) {
2036 gp_Pnt PF = C.Value (f);
2037 if (PF.IsEqual(P,TolConf)) {
2039 found = Standard_True;
2043 if (V.Orientation() == TopAbs_REVERSED) {
2044 if (!found && Abs(l) < Precision::Infinite()) {
2045 gp_Pnt PL = C.Value (l);
2046 if (PL.IsEqual(P,TolConf)) {
2048 found = Standard_True;
2053 Extrema_ExtPC Proj(P,C);
2054 if (Proj.IsDone() && Proj.NbExt() > 0) {
2055 Standard_Real Dist2,Dist2Min = Proj.SquareDistance(1);
2056 U = Proj.Point(1).Parameter();
2057 for (Standard_Integer i = 2; i <= Proj.NbExt(); i++) {
2058 Dist2 = Proj.SquareDistance(i);
2059 if (Dist2 < Dist2Min) {
2061 U = Proj.Point(i).Parameter();
2064 found = Standard_True;
2070 Standard_Real Dist = P.Distance(C.Value(U));
2071 if (Dist > TolConf) {
2072 std::cout << " ProjectVertexOnEdge :distance vertex edge :"<<Dist<<std::endl;
2074 if (U < f - Precision::Confusion() ||
2075 U > l + Precision::Confusion()) {
2076 std::cout << " ProjectVertexOnEdge : hors borne :"<<std::endl;
2077 std::cout << " f = "<<f<<" l ="<<l<< " U ="<<U<<std::endl;
2081 std::cout <<"BRepOffset_Tool::ProjectVertexOnEdge Parameter no found"<<std::endl;
2082 if (Abs(f) < Precision::Infinite() &&
2083 Abs(l) < Precision::Infinite()) {
2091 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
2092 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
2093 aLocalShape = V.Oriented(TopAbs_INTERNAL);
2094 // TopoDS_Edge EE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
2095 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
2096 U,EE,BRep_Tool::Tolerance(E));
2102 //=======================================================================
2103 //function : Inter2d
2105 //=======================================================================
2107 void BRepOffset_Tool::Inter2d (const TopoDS_Face& F,
2108 const TopoDS_Edge& E1,
2109 const TopoDS_Edge& E2,
2110 TopTools_ListOfShape& LV,
2111 const Standard_Real TolConf)
2115 DBRep::Set("E1",E1);
2116 DBRep::Set("E2",E2);
2121 Standard_Real fl1[2],fl2[2];
2124 // Si l edge a ete etendu les pcurves ne sont pas forcement
2130 // Construction des curves 3d si elles n existent pas
2131 // utile pour coder correctement les parametres des vertex
2132 // d intersection sur les edges.
2133 //TopLoc_Location L;
2134 //Standard_Real f,l;
2135 //Handle(Geom_Curve) C3d1 = BRep_Tool::Curve(E1,L,f,l);
2136 //if (C3d1.IsNull()) {
2137 // BRepLib::BuildCurve3d(E1,BRep_Tool::Tolerance(E1));
2139 //Handle(Geom_Curve) C3d2 = BRep_Tool::Curve(E2,L,f,l);
2140 //if (C3d2.IsNull()) {
2141 // BRepLib::BuildCurve3d(E2,BRep_Tool::Tolerance(E2));
2144 Standard_Integer NbPC1 = 1, NbPC2 = 1;
2145 if (BRep_Tool::IsClosed(E1,F)) NbPC1++;
2146 if (BRep_Tool::IsClosed(E2,F)) NbPC2++;
2148 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
2149 Handle(Geom2d_Curve) C1, C2;
2150 Standard_Boolean YaSol = Standard_False;
2151 Standard_Integer itry = 0;
2153 while (!YaSol && itry < 2) {
2154 for ( Standard_Integer i = 1; i <= NbPC1 ; i++) {
2155 TopoDS_Shape aLocalEdgeReversedE1 = E1.Reversed();
2156 if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
2157 else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdgeReversedE1),
2159 // if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
2160 // else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E1.Reversed()),
2161 // F,fl1[0],fl1[1]);
2162 for ( Standard_Integer j = 1; j <= NbPC2; j++ ) {
2163 TopoDS_Shape aLocalEdge = E2.Reversed();
2164 if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2165 else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdge),
2167 // if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2168 // else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E2.Reversed()),
2169 // F,fl2[0],fl2[1]);
2171 if (C1.IsNull() || C2.IsNull()) {
2172 std::cout <<"Inter2d : Pas de pcurve"<<std::endl;
2174 DBRep::Set("E1",E1);
2175 DBRep::Set("E2",E2);
2181 Standard_Real U1 = 0.,U2 = 0.;
2183 Standard_Boolean aCurrentFind = Standard_False;
2185 fl1[0] = C1->FirstParameter(); fl1[1] = C1->LastParameter();
2186 fl2[0] = C2->FirstParameter(); fl2[1] = C2->LastParameter();
2188 Geom2dAdaptor_Curve AC1(C1,fl1[0],fl1[1]);
2189 Geom2dAdaptor_Curve AC2(C2,fl2[0],fl2[1]);
2192 gp_Pnt2d P1[2],P2[2];
2193 P1[0] = C1->Value(fl1[0]); P1[1] = C1->Value(fl1[1]);
2194 P2[0] = C2->Value(fl2[0]); P2[1] = C2->Value(fl2[1]);
2196 Standard_Integer i1 ;
2197 for ( i1 = 0; i1 < 2; i1++) {
2198 for (Standard_Integer i2 = 0; i2 < 2; i2++) {
2199 if (Abs(fl1[i1]) < Precision::Infinite() &&
2200 Abs(fl2[i2]) < Precision::Infinite() ) {
2201 if (P1[i1].IsEqual(P2[i2],TolConf)) {
2202 YaSol = Standard_True;
2203 aCurrentFind = Standard_True;
2204 U1 = fl1[i1]; U2 = fl2[i2];
2205 P2d = C1->Value(U1);
2211 for (i1 = 0; i1 < 2; i1++)
2213 Extrema_ExtPC2d extr( P1[i1], AC2 );
2214 if (extr.IsDone() && extr.NbExt() > 0)
2216 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2217 Standard_Integer IndexMin = 1;
2218 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2220 Dist2 = extr.SquareDistance(ind);
2221 if (Dist2 < Dist2Min)
2227 if (Dist2Min <= Precision::SquareConfusion())
2229 YaSol = Standard_True;
2230 aCurrentFind = Standard_True;
2233 U2 = (extr.Point(IndexMin)).Parameter();
2239 for (Standard_Integer i2 = 0; i2 < 2; i2++)
2241 Extrema_ExtPC2d extr( P2[i2], AC1 );
2242 if (extr.IsDone() && extr.NbExt() > 0)
2244 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2245 Standard_Integer IndexMin = 1;
2246 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2248 Dist2 = extr.SquareDistance(ind);
2249 if (Dist2 < Dist2Min)
2255 if (Dist2Min <= Precision::SquareConfusion())
2257 YaSol = Standard_True;
2258 aCurrentFind = Standard_True;
2261 U1 = (extr.Point(IndexMin)).Parameter();
2269 Geom2dInt_GInter Inter (AC1,AC2,TolConf,TolConf);
2271 if (!Inter.IsEmpty() && Inter.NbPoints() > 0) {
2272 YaSol = Standard_True;
2273 aCurrentFind = Standard_True;
2274 U1 = Inter.Point(1).ParamOnFirst();
2275 U2 = Inter.Point(1).ParamOnSecond();
2276 P2d = Inter.Point(1).Value();
2278 else if (!Inter.IsEmpty() && Inter.NbSegments() > 0) {
2279 YaSol = Standard_True;
2280 aCurrentFind = Standard_True;
2281 IntRes2d_IntersectionSegment Seg = Inter.Segment(1);
2282 IntRes2d_IntersectionPoint IntP1 = Seg.FirstPoint();
2283 IntRes2d_IntersectionPoint IntP2 = Seg.LastPoint();
2284 Standard_Real U1on1 = IntP1.ParamOnFirst();
2285 Standard_Real U1on2 = IntP2.ParamOnFirst();
2286 Standard_Real U2on1 = IntP1.ParamOnSecond();
2287 Standard_Real U2on2 = IntP2.ParamOnSecond();
2289 std::cout << " BRepOffset_Tool::Inter2d SEGMENT d intersection" << std::endl;
2290 std::cout << " ===> Parametres sur Curve1 : ";
2291 std::cout << U1on1 << " " << U1on2 << std::endl;
2292 std::cout << " ===> Parametres sur Curve2 : ";
2293 std::cout << U2on1 << " " << U2on2 << std::endl;
2295 U1 = (U1on1 + U1on2)/2.;
2296 U2 = (U2on1 + U2on2)/2.;
2297 gp_Pnt2d P2d1 = C1->Value(U1);
2298 gp_Pnt2d P2d2 = C2->Value(U2);
2299 P2d.SetX( (P2d1.X() + P2d2.X()) / 2.);
2300 P2d.SetY( (P2d1.Y() + P2d2.Y()) / 2.);
2304 gp_Pnt P = S->Value(P2d.X(),P2d.Y());
2305 TopoDS_Vertex V = BRepLib_MakeVertex(P);
2306 V.Orientation(TopAbs_INTERNAL);
2307 TopoDS_Shape aLocalEdgeOrientedE1 = E1.Oriented(TopAbs_FORWARD);
2308 B.UpdateVertex(V,U1,TopoDS::Edge(aLocalEdgeOrientedE1),TolConf);
2309 aLocalEdgeOrientedE1 = E2.Oriented(TopAbs_FORWARD);
2310 B.UpdateVertex(V,U2,TopoDS::Edge(aLocalEdgeOrientedE1),TolConf);
2311 // B.UpdateVertex(V,U1,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)),TolConf);
2312 // B.UpdateVertex(V,U2,TopoDS::Edge(E2.Oriented(TopAbs_FORWARD)),TolConf);
2320 if (LV.Extent() > 1) {
2321 //------------------------------------------------
2322 // garde seulement les vertex les plus proches du
2323 //debut et de la fin.
2324 //------------------------------------------------
2325 TopTools_ListIteratorOfListOfShape it(LV);
2326 TopoDS_Vertex VF,VL;
2327 Standard_Real UMin = Precision::Infinite();
2328 Standard_Real UMax = -Precision::Infinite();
2331 for ( ; it.More(); it.Next()) {
2332 TopoDS_Vertex CV = TopoDS::Vertex(it.Value());
2333 TopoDS_Shape aLocalEdge = E1.Oriented(TopAbs_FORWARD);
2334 U = BRep_Tool::Parameter(CV,TopoDS::Edge(aLocalEdge));
2335 // U = BRep_Tool::Parameter(CV,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)));
2343 LV.Clear();LV.Append(VF); LV.Append(VL);
2348 std::cout <<"Inter2d : Pas de solution"<<std::endl;
2350 DBRep::Set("E1",E1);
2351 DBRep::Set("E2",E2);
2358 //=======================================================================
2359 //function : SelectEdge
2361 //=======================================================================
2363 static void SelectEdge (const TopoDS_Face& /*F*/,
2364 const TopoDS_Face& /*EF*/,
2365 const TopoDS_Edge& E,
2366 TopTools_ListOfShape& LInt)
2368 //------------------------------------------------------------
2369 // detrompeur sur les intersections sur les faces periodiques
2370 //------------------------------------------------------------
2371 TopTools_ListIteratorOfListOfShape it(LInt);
2372 Standard_Real dU = 1.0e100;
2375 Standard_Real Fst, Lst, tmp;
2376 BRep_Tool::Range(E, Fst, Lst);
2377 BRepAdaptor_Curve Ad1(E);
2379 gp_Pnt PFirst = Ad1.Value( Fst );
2380 gp_Pnt PLast = Ad1.Value( Lst );
2382 //----------------------------------------------------------------------
2383 // Selection de l edge qui couvre le plus le domaine de l edge initiale.
2384 //----------------------------------------------------------------------
2385 for (; it.More(); it.Next()) {
2386 const TopoDS_Edge& EI = TopoDS::Edge(it.Value());
2388 BRep_Tool::Range(EI, Fst, Lst);
2389 BRepAdaptor_Curve Ad2(EI);
2390 gp_Pnt P1 = Ad2.Value(Fst);
2391 gp_Pnt P2 = Ad2.Value(Lst);
2393 tmp = P1.Distance(PFirst) + P2.Distance(PLast);
2405 //=======================================================================
2408 //=======================================================================
2410 static void MakeFace(const Handle(Geom_Surface)& S,
2411 const Standard_Real Um,
2412 const Standard_Real UM,
2413 const Standard_Real Vm,
2414 const Standard_Real VM,
2415 const Standard_Boolean uclosed,
2416 const Standard_Boolean vclosed,
2417 const Standard_Boolean isVminDegen,
2418 const Standard_Boolean isVmaxDegen,
2421 Standard_Real UMin = Um;
2422 Standard_Real UMax = UM;
2423 Standard_Real VMin = Vm;
2424 Standard_Real VMax = VM;
2426 // compute infinite flags
2427 Standard_Boolean umininf = Precision::IsNegativeInfinite(UMin);
2428 Standard_Boolean umaxinf = Precision::IsPositiveInfinite(UMax);
2429 Standard_Boolean vmininf = Precision::IsNegativeInfinite(VMin);
2430 Standard_Boolean vmaxinf = Precision::IsPositiveInfinite(VMax);
2432 // degenerated flags (for cones)
2433 Standard_Boolean vmindegen = isVminDegen, vmaxdegen = isVmaxDegen;
2434 Handle(Geom_Surface) theSurf = S;
2435 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
2436 theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
2437 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
2439 Handle(Geom_ConicalSurface) ConicalS = Handle(Geom_ConicalSurface)::DownCast (theSurf);
2440 gp_Cone theCone = ConicalS->Cone();
2441 gp_Pnt theApex = theCone.Apex();
2442 Standard_Real Uapex, Vapex;
2443 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
2444 if (Abs(VMin - Vapex) <= Precision::Confusion())
2445 vmindegen = Standard_True;
2446 if (Abs(VMax - Vapex) <= Precision::Confusion())
2447 vmaxdegen = Standard_True;
2452 Standard_Real tol = Precision::Confusion();
2454 TopoDS_Vertex V00,V10,V11,V01;
2457 if (!vmininf) B.MakeVertex(V00,S->Value(UMin,VMin),tol);
2458 if (!vmaxinf) B.MakeVertex(V01,S->Value(UMin,VMax),tol);
2461 if (!vmininf) B.MakeVertex(V10,S->Value(UMax,VMin),tol);
2462 if (!vmaxinf) B.MakeVertex(V11,S->Value(UMax,VMax),tol);
2481 Handle(Geom2d_Line) Lumin,Lumax,Lvmin,Lvmax;
2483 Lumin = new Geom2d_Line(gp_Pnt2d(UMin,0),gp_Dir2d(0,1));
2485 Lumax = new Geom2d_Line(gp_Pnt2d(UMax,0),gp_Dir2d(0,1));
2487 Lvmin = new Geom2d_Line(gp_Pnt2d(0,VMin),gp_Dir2d(1,0));
2489 Lvmax = new Geom2d_Line(gp_Pnt2d(0,VMax),gp_Dir2d(1,0));
2491 Handle(Geom_Curve) Cumin,Cumax,Cvmin,Cvmax;
2492 Standard_Real TolApex = 1.e-5;
2493 //Standard_Boolean hasiso = ! S->IsKind(STANDARD_TYPE(Geom_OffsetSurface));
2494 Standard_Boolean hasiso = S->IsKind(STANDARD_TYPE(Geom_ElementarySurface));
2497 Cumin = S->UIso(UMin);
2499 Cumax = S->UIso(UMax);
2502 Cvmin = S->VIso(VMin);
2503 if (BRepOffset_Tool::Gabarit( Cvmin ) <= TolApex)
2504 vmindegen = Standard_True;
2508 Cvmax = S->VIso(VMax);
2509 if (BRepOffset_Tool::Gabarit( Cvmax ) <= TolApex)
2510 vmaxdegen = Standard_True;
2515 B.MakeFace(F,S,tol);
2518 TopoDS_Edge eumin,eumax,evmin,evmax;
2522 B.MakeEdge(eumin,Cumin,tol);
2526 B.UpdateEdge(eumin,Lumax,Lumin,F,tol);
2528 B.UpdateEdge(eumin,Lumin,F,tol);
2530 V00.Orientation(TopAbs_FORWARD);
2534 V01.Orientation(TopAbs_REVERSED);
2537 B.Range(eumin,VMin,VMax);
2545 B.MakeEdge(eumax,Cumax,tol);
2548 B.UpdateEdge(eumax,Lumax,F,tol);
2550 V10.Orientation(TopAbs_FORWARD);
2554 V11.Orientation(TopAbs_REVERSED);
2557 B.Range(eumax,VMin,VMax);
2562 if (hasiso && !vmindegen)
2563 B.MakeEdge(evmin,Cvmin,tol);
2567 B.UpdateEdge(evmin,Lvmin,Lvmax,F,tol);
2569 B.UpdateEdge(evmin,Lvmin,F,tol);
2571 V00.Orientation(TopAbs_FORWARD);
2575 V10.Orientation(TopAbs_REVERSED);
2578 B.Range(evmin,UMin,UMax);
2580 B.Degenerated(evmin, Standard_True);
2587 if (hasiso && !vmaxdegen)
2588 B.MakeEdge(evmax,Cvmax,tol);
2591 B.UpdateEdge(evmax,Lvmax,F,tol);
2593 V01.Orientation(TopAbs_FORWARD);
2597 V11.Orientation(TopAbs_REVERSED);
2600 B.Range(evmax,UMin,UMax);
2602 B.Degenerated(evmax, Standard_True);
2606 // make the wires and add them to the face
2607 eumin.Orientation(TopAbs_REVERSED);
2608 evmax.Orientation(TopAbs_REVERSED);
2612 if (!umininf && !umaxinf && vmininf && vmaxinf) {
2623 else if (umininf && umaxinf && !vmininf && !vmaxinf) {
2634 else if (!umininf || !umaxinf || !vmininf || !vmaxinf) {
2637 if (!umininf) B.Add(W,eumin);
2638 if (!vmininf) B.Add(W,evmin);
2639 if (!umaxinf) B.Add(W,eumax);
2640 if (!vmaxinf) B.Add(W,evmax);
2642 W.Closed(!umininf && !umaxinf && !vmininf && !vmaxinf);
2643 F.Closed(uclosed && vclosed);
2647 //=======================================================================
2648 //function : EnLargeGeometry
2650 //=======================================================================
2652 static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S,
2657 Standard_Boolean& IsV1degen,
2658 Standard_Boolean& IsV2degen,
2659 const Standard_Real uf1,
2660 const Standard_Real uf2,
2661 const Standard_Real vf1,
2662 const Standard_Real vf2,
2663 const Standard_Real coeff,
2664 const Standard_Boolean theGlobalEnlargeU,
2665 const Standard_Boolean theGlobalEnlargeVfirst,
2666 const Standard_Boolean theGlobalEnlargeVlast,
2667 const Standard_Real theLenBeforeUfirst,
2668 const Standard_Real theLenAfterUlast,
2669 const Standard_Real theLenBeforeVfirst,
2670 const Standard_Real theLenAfterVlast)
2672 const Standard_Real TolApex = 1.e-5;
2674 Standard_Boolean SurfaceChange = Standard_False;
2675 if ( S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2676 Handle(Geom_Surface) BS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
2677 EnlargeGeometry(BS,U1,U2,V1,V2,IsV1degen,IsV2degen,
2678 uf1,uf2,vf1,vf2,coeff,
2679 theGlobalEnlargeU, theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
2680 theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
2681 if (!theGlobalEnlargeVfirst)
2683 if (!theGlobalEnlargeVlast)
2685 if (!theGlobalEnlargeVfirst || !theGlobalEnlargeVlast)
2686 //Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->SetTrim( U1, U2, V1, V2 );
2687 S = new Geom_RectangularTrimmedSurface( BS, U1, U2, V1, V2 );
2690 SurfaceChange = Standard_True;
2692 else if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)) {
2693 Handle(Geom_Surface) Surf = Handle(Geom_OffsetSurface)::DownCast (S)->BasisSurface();
2694 SurfaceChange = EnlargeGeometry(Surf,U1,U2,V1,V2,IsV1degen,IsV2degen,
2695 uf1,uf2,vf1,vf2,coeff,
2696 theGlobalEnlargeU, theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
2697 theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
2698 Handle(Geom_OffsetSurface)::DownCast(S)->SetBasisSurface(Surf);
2700 else if (S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
2701 S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution))
2703 Standard_Real du_first = 0., du_last = 0.,
2704 dv_first = 0., dv_last = 0.;
2705 Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
2706 Standard_Real u1, u2, v1, v2;
2707 Standard_Boolean enlargeU = theGlobalEnlargeU, enlargeV = Standard_True;
2708 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2709 Standard_Boolean enlargeVfirst = theGlobalEnlargeVfirst, enlargeVlast = theGlobalEnlargeVlast;
2710 S->Bounds( u1, u2, v1, v2 );
2711 if (Precision::IsInfinite(u1) || Precision::IsInfinite(u2))
2713 du_first = du_last = uf2-uf1;
2714 u1 = uf1 - du_first;
2716 enlargeU = Standard_False;
2718 else if (S->IsUClosed())
2719 enlargeU = Standard_False;
2722 viso = S->VIso( vf1 );
2723 GeomAdaptor_Curve gac( viso );
2724 Standard_Real du_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
2725 du_first = (theLenBeforeUfirst == -1)? du_default : theLenBeforeUfirst;
2726 du_last = (theLenAfterUlast == -1)? du_default : theLenAfterUlast;
2727 uiso1 = S->UIso( uf1 );
2728 uiso2 = S->UIso( uf2 );
2729 if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
2730 enlargeUfirst = Standard_False;
2731 if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
2732 enlargeUlast = Standard_False;
2734 if (Precision::IsInfinite(v1) || Precision::IsInfinite(v2))
2736 dv_first = dv_last = vf2-vf1;
2737 v1 = vf1 - dv_first;
2739 enlargeV = Standard_False;
2741 else if (S->IsVClosed())
2742 enlargeV = Standard_False;
2745 uiso = S->UIso( uf1 );
2746 GeomAdaptor_Curve gac( uiso );
2747 Standard_Real dv_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
2748 dv_first = (theLenBeforeVfirst == -1)? dv_default : theLenBeforeVfirst;
2749 dv_last = (theLenAfterVlast == -1)? dv_default : theLenAfterVlast;
2750 viso1 = S->VIso( vf1 );
2751 viso2 = S->VIso( vf2 );
2752 if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
2754 enlargeVfirst = Standard_False;
2755 IsV1degen = Standard_True;
2757 if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
2759 enlargeVlast = Standard_False;
2760 IsV2degen = Standard_True;
2763 Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface( S, u1, u2, v1, v2 );
2766 if (enlargeUfirst && du_first != 0.)
2767 GeomLib::ExtendSurfByLength (aSurf, du_first, 1, Standard_True, Standard_False);
2768 if (enlargeUlast && du_last != 0.)
2769 GeomLib::ExtendSurfByLength (aSurf, du_last, 1, Standard_True, Standard_True);
2773 if (enlargeVfirst && dv_first != 0.)
2774 GeomLib::ExtendSurfByLength (aSurf, dv_first, 1, Standard_False, Standard_False);
2775 if (enlargeVlast && dv_last != 0.)
2776 GeomLib::ExtendSurfByLength (aSurf, dv_last, 1, Standard_False, Standard_True);
2779 S->Bounds( U1, U2, V1, V2 );
2780 SurfaceChange = Standard_True;
2782 else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
2783 S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
2785 Standard_Boolean enlargeU = theGlobalEnlargeU, enlargeV = Standard_True;
2786 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2787 Standard_Boolean enlargeVfirst = theGlobalEnlargeVfirst, enlargeVlast = theGlobalEnlargeVlast;
2789 enlargeU = Standard_False;
2791 enlargeV = Standard_False;
2793 Standard_Real duf = uf2-uf1, dvf = vf2-vf1;
2794 Standard_Real u1, u2, v1, v2;
2795 S->Bounds( u1, u2, v1, v2 );
2797 Standard_Real du_first = 0., du_last = 0.,
2798 dv_first = 0., dv_last = 0.;
2799 Handle( Geom_Curve ) uiso1, uiso2, viso1, viso2;
2800 Standard_Real gabarit_uiso1, gabarit_uiso2, gabarit_viso1, gabarit_viso2;
2802 uiso1 = S->UIso( u1 );
2803 uiso2 = S->UIso( u2 );
2804 viso1 = S->VIso( v1 );
2805 viso2 = S->VIso( v2 );
2806 gabarit_uiso1 = BRepOffset_Tool::Gabarit( uiso1 );
2807 gabarit_uiso2 = BRepOffset_Tool::Gabarit( uiso2 );
2808 gabarit_viso1 = BRepOffset_Tool::Gabarit( viso1 );
2809 gabarit_viso2 = BRepOffset_Tool::Gabarit( viso2 );
2810 if (gabarit_viso1 <= TolApex ||
2811 gabarit_viso2 <= TolApex)
2812 enlargeU = Standard_False;
2813 if (gabarit_uiso1 <= TolApex ||
2814 gabarit_uiso2 <= TolApex)
2815 enlargeV = Standard_False;
2817 GeomAdaptor_Curve gac;
2821 Standard_Real du_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
2822 du_first = (theLenBeforeUfirst == -1)? du_default : theLenBeforeUfirst;
2823 du_last = (theLenAfterUlast == -1)? du_default : theLenAfterUlast;
2824 if (gabarit_uiso1 <= TolApex)
2825 enlargeUfirst = Standard_False;
2826 if (gabarit_uiso2 <= TolApex)
2827 enlargeUlast = Standard_False;
2832 Standard_Real dv_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
2833 dv_first = (theLenBeforeVfirst == -1)? dv_default : theLenBeforeVfirst;
2834 dv_last = (theLenAfterVlast == -1)? dv_default : theLenAfterVlast;
2835 if (gabarit_viso1 <= TolApex)
2837 enlargeVfirst = Standard_False;
2838 IsV1degen = Standard_True;
2840 if (gabarit_viso2 <= TolApex)
2842 enlargeVlast = Standard_False;
2843 IsV2degen = Standard_True;
2847 Handle(Geom_BoundedSurface) aSurf = Handle(Geom_BoundedSurface)::DownCast (S);
2850 if (enlargeUfirst && uf1-u1 < duf && du_first != 0.)
2851 GeomLib::ExtendSurfByLength (aSurf, du_first, 1, Standard_True, Standard_False);
2852 if (enlargeUlast && u2-uf2 < duf && du_last != 0.)
2853 GeomLib::ExtendSurfByLength (aSurf, du_last, 1, Standard_True, Standard_True);
2857 if (enlargeVfirst && vf1-v1 < dvf && dv_first != 0.)
2858 GeomLib::ExtendSurfByLength (aSurf, dv_first, 1, Standard_False, Standard_False);
2859 if (enlargeVlast && v2-vf2 < dvf && dv_last != 0.)
2860 GeomLib::ExtendSurfByLength (aSurf, dv_last, 1, Standard_False, Standard_True);
2864 S->Bounds( U1, U2, V1, V2 );
2865 SurfaceChange = Standard_True;
2868 Standard_Real UU1,UU2,VV1,VV2;
2869 S->Bounds(UU1,UU2,VV1,VV2);
2870 // Pas d extension au dela des bornes de la surface.
2876 return SurfaceChange;
2879 //=======================================================================
2880 //function : UpDatePCurve
2881 //purpose : Mise a jour des pcurves de F sur la surface de de BF.
2882 // F and BF has to be FORWARD,
2883 //=======================================================================
2885 static void UpdatePCurves (const TopoDS_Face& F,
2891 TopTools_IndexedMapOfShape Emap;
2892 Handle(Geom2d_Curve) NullPCurve;
2894 TopExp::MapShapes( F, TopAbs_EDGE, Emap );
2896 for (i = 1; i <= Emap.Extent(); i++)
2898 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
2899 CE.Orientation( TopAbs_FORWARD );
2900 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface( CE, F, f, l );
2903 if (BRep_Tool::IsClosed( CE, F ))
2906 Handle(Geom2d_Curve) C2R = BRep_Tool::CurveOnSurface( CE, F, f, l );
2907 B.UpdateEdge( CE, NullPCurve, NullPCurve, F, BRep_Tool::Tolerance(CE) );
2908 B.UpdateEdge( CE, C2, C2R, BF, BRep_Tool::Tolerance(CE) );
2912 B.UpdateEdge( CE, NullPCurve, F, BRep_Tool::Tolerance(CE) );
2913 B.UpdateEdge( CE, C2, BF, BRep_Tool::Tolerance(CE) );
2921 //=======================================================================
2922 //function :CompactUVBounds
2924 //=======================================================================
2926 static void CompactUVBounds (const TopoDS_Face& F,
2927 Standard_Real& UMin,
2928 Standard_Real& UMax,
2929 Standard_Real& VMin,
2930 Standard_Real& VMax)
2932 // Calcul serre pour que les bornes ne couvrent pas plus d une periode
2933 Standard_Real U1,U2;
2934 Standard_Real N = 33;
2937 TopExp_Explorer exp;
2938 for (exp.Init(F, TopAbs_EDGE); exp.More(); exp.Next()) {
2939 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
2940 BRepAdaptor_Curve2d C(E,F);
2941 BRep_Tool::Range(E,U1,U2);
2943 Standard_Real U = U1;
2944 Standard_Real DU = (U2-U1)/(N-1);
2945 for (Standard_Integer j=1;j<N;j++) {
2955 B.Get(UMin,VMin,UMax,VMax);
2957 BRep_Tool::Surface(F)->Bounds (UMin, UMax, VMin, VMax);
2960 //=======================================================================
2961 //function : CheckBounds
2963 //=======================================================================
2965 void BRepOffset_Tool::CheckBounds(const TopoDS_Face& F,
2966 const BRepOffset_Analyse& Analyse,
2967 Standard_Boolean& enlargeU,
2968 Standard_Boolean& enlargeVfirst,
2969 Standard_Boolean& enlargeVlast)
2971 enlargeU = Standard_True;
2972 enlargeVfirst = Standard_True; enlargeVlast = Standard_True;
2974 Standard_Integer Ubound = 0, Vbound = 0;
2975 Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
2976 Standard_Real Vfirst = RealLast(), Vlast = RealFirst();
2978 Standard_Real UF1,UF2,VF1,VF2;
2979 CompactUVBounds(F,UF1,UF2,VF1,VF2);
2981 Handle(Geom_Surface) theSurf = BRep_Tool::Surface(F);
2982 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
2983 theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (theSurf)->BasisSurface();
2985 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
2986 theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution) ||
2987 theSurf->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
2988 theSurf->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
2990 TopExp_Explorer Explo(F, TopAbs_EDGE);
2991 for (; Explo.More(); Explo.Next())
2993 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
2994 const BRepOffset_ListOfInterval& L = Analyse.Type(anEdge);
2995 if (!L.IsEmpty() || BRep_Tool::Degenerated(anEdge))
2997 ChFiDS_TypeOfConcavity OT = L.First().Type();
2998 if (OT == ChFiDS_Tangential || BRep_Tool::Degenerated(anEdge))
3000 Standard_Real fpar, lpar;
3001 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, F, fpar, lpar);
3002 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
3003 aCurve = Handle(Geom2d_TrimmedCurve)::DownCast (aCurve)->BasisCurve();
3005 Handle(Geom2d_Line) theLine;
3006 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_Line))
3007 theLine = Handle(Geom2d_Line)::DownCast (aCurve);
3008 else if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BezierCurve) ||
3009 aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BSplineCurve))
3011 Standard_Real newFpar, newLpar, deviation;
3012 theLine = ShapeCustom_Curve2d::ConvertToLine2d(aCurve, fpar, lpar, Precision::Confusion(),
3013 newFpar, newLpar, deviation);
3016 if (!theLine.IsNull())
3018 gp_Dir2d theDir = theLine->Direction();
3019 if (theDir.IsParallel( gp::DX2d(), Precision::Angular() ))
3022 if (BRep_Tool::Degenerated(anEdge))
3024 if (Abs(theLine->Location().Y() - VF1) <= Precision::Confusion())
3025 enlargeVfirst = Standard_False;
3026 else //theLine->Location().Y() is near VF2
3027 enlargeVlast = Standard_False;
3031 if (theLine->Location().Y() < Vfirst)
3032 Vfirst = theLine->Location().Y();
3033 if (theLine->Location().Y() > Vlast)
3034 Vlast = theLine->Location().Y();
3037 else if (theDir.IsParallel( gp::DY2d(), Precision::Angular() ))
3040 if (theLine->Location().X() < Ufirst)
3041 Ufirst = theLine->Location().X();
3042 if (theLine->Location().X() > Ulast)
3043 Ulast = theLine->Location().X();
3051 if (Ubound >= 2 || Vbound >= 2)
3054 Abs(UF1-Ufirst) <= Precision::Confusion() &&
3055 Abs(UF2-Ulast) <= Precision::Confusion())
3056 enlargeU = Standard_False;
3058 Abs(VF1-Vfirst) <= Precision::Confusion() &&
3059 Abs(VF2-Vlast) <= Precision::Confusion())
3061 enlargeVfirst = Standard_False;
3062 enlargeVlast = Standard_False;
3067 //=======================================================================
3068 //function : EnLargeFace
3070 //=======================================================================
3072 Standard_Boolean BRepOffset_Tool::EnLargeFace
3073 (const TopoDS_Face& F,
3075 const Standard_Boolean CanExtentSurface,
3076 const Standard_Boolean UpdatePCurve,
3077 const Standard_Boolean theEnlargeU,
3078 const Standard_Boolean theEnlargeVfirst,
3079 const Standard_Boolean theEnlargeVlast,
3080 const Standard_Integer theExtensionMode,
3081 const Standard_Real theLenBeforeUfirst,
3082 const Standard_Real theLenAfterUlast,
3083 const Standard_Real theLenBeforeVfirst,
3084 const Standard_Real theLenAfterVlast)
3086 //---------------------------
3087 // extension de la geometrie.
3088 //---------------------------
3090 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
3091 Standard_Real UU1,VV1,UU2,VV2;
3092 Standard_Boolean uperiodic = Standard_False, vperiodic = Standard_False;
3093 Standard_Boolean isVV1degen = Standard_False, isVV2degen = Standard_False;
3094 Standard_Real US1,VS1,US2,VS2;
3095 Standard_Real UF1,VF1,UF2,VF2;
3096 Standard_Boolean SurfaceChange = Standard_False;
3098 if (S->IsUPeriodic() || S->IsVPeriodic()) {
3099 // Calcul serre pour que les bornes ne couvre pas plus d une periode
3100 CompactUVBounds(F,UF1,UF2,VF1,VF2);
3103 BRepTools::UVBounds(F,UF1,UF2,VF1,VF2);
3106 S->Bounds (US1,US2,VS1,VS2);
3107 Standard_Real coeff;
3108 if (theExtensionMode == 1)
3110 UU1 = VV1 = - TheInfini;
3111 UU2 = VV2 = TheInfini;
3116 Standard_Real FaceDU = UF2 - UF1;
3117 Standard_Real FaceDV = VF2 - VF1;
3118 UU1 = UF1 - 10*FaceDU;
3119 UU2 = UF2 + 10*FaceDU;
3120 VV1 = VF1 - 10*FaceDV;
3121 VV2 = VF2 + 10*FaceDV;
3125 if (CanExtentSurface) {
3126 SurfaceChange = EnlargeGeometry(S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2, coeff,
3127 theEnlargeU, theEnlargeVfirst, theEnlargeVlast,
3128 theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
3131 UU1 = Max(US1,UU1); UU2 = Min(UU2,US2);
3132 VV1 = Max(VS1,VV1); VV2 = Min(VS2,VV2);
3135 if (S->IsUPeriodic()) {
3136 uperiodic = Standard_True;
3137 Standard_Real Period = S->UPeriod();
3138 Standard_Real Delta = Period - (UF2 - UF1);
3139 Standard_Real alpha = 0.1;
3140 UU1 = UF1 - alpha*Delta; UU2 = UF2 + alpha*Delta;
3141 if ((UU2 - UU1) > Period) {
3145 if (S->IsVPeriodic()) {
3146 vperiodic = Standard_True;
3147 Standard_Real Period = S->VPeriod();
3148 Standard_Real Delta = Period - (VF2 - VF1);
3149 Standard_Real alpha = 0.1;
3150 VV1 = VF1 - alpha*Delta; VV2 = VF2 + alpha*Delta;
3151 if ((VV2 - VV1) > Period) {
3156 //Special treatment for conical surfaces
3157 Handle(Geom_Surface) theSurf = S;
3158 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
3159 theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
3160 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
3162 Handle(Geom_ConicalSurface) ConicalS = Handle(Geom_ConicalSurface)::DownCast (theSurf);
3163 gp_Cone theCone = ConicalS->Cone();
3164 gp_Pnt theApex = theCone.Apex();
3165 Standard_Real Uapex, Vapex;
3166 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
3167 if (VV1 < Vapex && Vapex < VV2)
3169 //consider that VF1 and VF2 are on the same side from apex
3170 Standard_Real TolApex = 1.e-5;
3171 if (Vapex - VF1 >= TolApex ||
3172 Vapex - VF2 >= TolApex) //if (VF1 < Vapex || VF2 < Vapex)
3181 UU1 = UF1; UU2 = UF2;
3183 if (!theEnlargeVfirst)
3185 if (!theEnlargeVlast)
3188 //Detect closedness in U and V directions
3189 Standard_Boolean uclosed = Standard_False, vclosed = Standard_False;
3190 BRepTools::DetectClosedness(F, uclosed, vclosed);
3191 if (uclosed && !uperiodic &&
3192 (theLenBeforeUfirst != 0. || theLenAfterUlast != 0.))
3193 uclosed = Standard_False;
3194 if (vclosed && !vperiodic &&
3195 (theLenBeforeVfirst != 0. && theLenAfterVlast != 0.))
3196 vclosed = Standard_False;
3198 MakeFace(S,UU1,UU2,VV1,VV2,uclosed,vclosed,isVV1degen,isVV2degen,BF);
3201 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
3203 //----------------------------------------------------------------
3204 // utile pour les bouchons on ne doit pas changer leur geometrie.
3205 // (Ce que fait BRepLib_MakeFace si S est restreinte).
3206 // On remet S et on update les pcurves.
3207 //----------------------------------------------------------------
3208 TopExp_Explorer exp;
3209 exp.Init(BF,TopAbs_EDGE);
3210 Standard_Real f=0.,l=0.;
3211 for (; exp.More(); exp.Next()) {
3212 TopoDS_Edge CE = TopoDS::Edge(exp.Current());
3213 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,BF,f,l);
3214 B.UpdateEdge (CE,C2,S,L,BRep_Tool::Tolerance(CE));
3216 B.UpdateFace(BF,S,L,BRep_Tool::Tolerance(F));
3219 if (SurfaceChange && UpdatePCurve) {
3220 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3221 UpdatePCurves(TopoDS::Face(aLocalFace),BF);
3222 //UpdatePCurves(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),BF);
3224 BB.UpdateFace( F, S, L, BRep_Tool::Tolerance(F) );
3227 BF.Orientation(F.Orientation());
3228 return SurfaceChange;
3231 //=======================================================================
3232 //function : TryParameter
3234 //=======================================================================
3236 static Standard_Boolean TryParameter (const TopoDS_Edge& OE,
3238 const TopoDS_Edge& NE,
3239 Standard_Real TolConf)
3241 BRepAdaptor_Curve OC(OE);
3242 BRepAdaptor_Curve NC(NE);
3243 Standard_Real Of = OC.FirstParameter(); Standard_Real Ol = OC.LastParameter();
3244 Standard_Real Nf = NC.FirstParameter(); Standard_Real Nl = NC.LastParameter();
3245 Standard_Real U = 0.;
3246 gp_Pnt P = BRep_Tool::Pnt(V);
3247 Standard_Boolean OK = Standard_False;
3249 if (P.Distance(OC.Value(Of)) < TolConf) {
3250 if (Of > Nf && Of < Nl && P.Distance(NC.Value(Of)) < TolConf) {
3255 if (P.Distance(OC.Value(Ol)) < TolConf) {
3256 if (Ol > Nf && Ol < Nl && P.Distance(NC.Value(Ol)) < TolConf) {
3263 TopoDS_Shape aLocalShape = NE.Oriented(TopAbs_FORWARD);
3264 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
3265 // TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD));
3266 aLocalShape = V.Oriented(TopAbs_INTERNAL);
3267 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
3268 U,NE,BRep_Tool::Tolerance(NE));
3269 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
3270 // U,NE,BRep_Tool::Tolerance(NE));
3275 //=======================================================================
3278 //=======================================================================
3280 void BRepOffset_Tool::MapVertexEdges (const TopoDS_Shape& S,
3281 TopTools_DataMapOfShapeListOfShape& MEV)
3283 TopExp_Explorer exp;
3284 exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3285 TopTools_MapOfShape DejaVu;
3286 for ( ; exp.More(); exp.Next()) {
3287 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3288 if (DejaVu.Add(E)) {
3289 TopoDS_Vertex V1,V2;
3290 TopExp::Vertices (E,V1,V2);
3291 if (!MEV.IsBound(V1)) {
3292 TopTools_ListOfShape empty;
3296 if (!V1.IsSame(V2)) {
3297 if (!MEV.IsBound(V2)) {
3298 TopTools_ListOfShape empty;
3307 //=======================================================================
3310 //=======================================================================
3312 void BRepOffset_Tool::BuildNeighbour (const TopoDS_Wire& W,
3313 const TopoDS_Face& F,
3314 TopTools_DataMapOfShapeShape& NOnV1,
3315 TopTools_DataMapOfShapeShape& NOnV2)
3317 TopoDS_Vertex V1,V2,VP1,VP2,FV1,FV2;
3318 TopoDS_Edge CurE,FirstE,PrecE;
3319 BRepTools_WireExplorer wexp;
3321 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3322 TopoDS_Shape aLocalWire = W.Oriented(TopAbs_FORWARD);
3323 wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
3324 // wexp.Init(TopoDS::Wire(W.Oriented(TopAbs_FORWARD)),
3325 // TopoDS::Face(F.Oriented(TopAbs_FORWARD)));
3326 CurE = FirstE = PrecE = wexp.Current();
3327 TopExp::Vertices(CurE,V1,V2);
3328 FV1 = VP1 = V1; FV2 = VP2 = V2;
3330 while (wexp.More()) {
3331 CurE = wexp.Current();
3332 TopExp::Vertices(CurE,V1,V2);
3333 if (V1.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3334 if (V1.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3335 if (V2.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3336 if (V2.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3341 if (V1.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3342 if (V1.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3343 if (V2.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3344 if (V2.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3347 //=======================================================================
3348 //function : ExtentFace
3350 //=======================================================================
3352 void BRepOffset_Tool::ExtentFace (const TopoDS_Face& F,
3353 TopTools_DataMapOfShapeShape& ConstShapes,
3354 TopTools_DataMapOfShapeShape& ToBuild,
3355 const TopAbs_State Side,
3356 const Standard_Real TolConf,
3362 sprintf(name,"FTE_%d",NbFTE++);
3367 TopExp_Explorer exp,exp2;
3368 TopTools_DataMapOfShapeShape Build;
3369 TopTools_DataMapOfShapeShape Extent;
3370 TopoDS_Edge FirstE,PrecE,CurE,NE;
3374 // Construction de la boite englobante de la face a etendre et des bouchons pour
3375 // limiter les extensions.
3376 //Bnd_Box ContextBox;
3377 //BRepBndLib::Add(F,B);
3378 //TopTools_DataMapIteratorOfDataMapOfShape itTB(ToBuild);
3379 //for (; itTB.More(); itTB.Next()) {
3380 //BRepBndLib::Add(TopBuild.Value(), ContextBox);
3384 Standard_Boolean SurfaceChange;
3385 SurfaceChange = EnLargeFace (F,EF,Standard_True);
3387 TopoDS_Shape aLocalShape = EF.EmptyCopied();
3388 NF = TopoDS::Face(aLocalShape);
3389 // NF = TopoDS::Face(EF.EmptyCopied());
3390 NF.Orientation(TopAbs_FORWARD);
3392 if (SurfaceChange) {
3393 //------------------------------------------------
3394 // Mise a jour des pcurves sur la surface de base.
3395 //------------------------------------------------
3396 TopoDS_Face Fforward = F;
3397 Fforward.Orientation(TopAbs_FORWARD);
3398 TopTools_IndexedMapOfShape Emap;
3399 TopExp::MapShapes( Fforward, TopAbs_EDGE, Emap );
3401 for (Standard_Integer i = 1; i <= Emap.Extent(); i++) {
3402 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
3403 CE.Orientation(TopAbs_FORWARD);
3404 TopoDS_Edge Ecs; //patch
3405 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,Fforward,f,l);
3407 if (ConstShapes.IsBound(CE)) {
3408 Ecs = TopoDS::Edge(ConstShapes(CE));
3409 BRep_Tool::Range(Ecs,f,l);
3411 if (BRep_Tool::IsClosed(CE,Fforward)) {
3412 TopoDS_Shape aLocalShapeReversedCE = CE.Reversed();
3413 Handle(Geom2d_Curve) C2R =
3414 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShapeReversedCE),Fforward,f,l);
3415 // Handle(Geom2d_Curve) C2R =
3416 // BRep_Tool::CurveOnSurface(TopoDS::Edge(CE.Reversed()),F,f,l);
3417 B.UpdateEdge (CE,C2,C2R,EF,BRep_Tool::Tolerance(CE));
3419 B.UpdateEdge (Ecs,C2,C2R,EF,BRep_Tool::Tolerance(CE));
3422 B.UpdateEdge (CE,C2,EF,BRep_Tool::Tolerance(CE));
3424 B.UpdateEdge (Ecs,C2,EF,BRep_Tool::Tolerance(CE));
3433 for (exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
3436 const TopoDS_Wire& W = TopoDS::Wire(exp.Current());
3437 TopTools_DataMapOfShapeListOfShape MVE; // Vertex -> Edges incidentes.
3438 TopTools_DataMapOfShapeShape NOnV1;
3439 TopTools_DataMapOfShapeShape NOnV2;
3441 MapVertexEdges (W,MVE);
3442 BuildNeighbour (W,F,NOnV1,NOnV2);
3444 TopTools_ListOfShape LInt1,LInt2;
3445 TopoDS_Face StopFace;
3446 //------------------------------------------------
3447 // Construction edges
3448 //------------------------------------------------
3449 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3450 exp2.More(); exp2.Next()) {
3451 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3452 if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
3453 if (ToBuild.IsBound(E)) {
3454 TopTools_ListOfShape LOE;
3456 BRepOffset_Tool::TryProject (TopoDS::Face(ToBuild(E)),
3457 EF,LOE,LInt2,LInt1,Side,TolConf);
3458 if (!LInt1.IsEmpty())
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 EnLargeFace(TopoDS::Face(ToBuild(E)),StopFace,Standard_False);
3469 BRepOffset_Tool::Inter3D (EF,StopFace,LInt1,LInt2,Side,E,Standard_True);
3470 // No intersection, it may happen for example for a chosen (non-offseted) planar face and
3471 // its neighbour offseted cylindrical face, if the offset is directed so that
3472 // the radius of the cylinder becomes smaller.
3473 if (LInt1.IsEmpty())
3475 if (LInt1.Extent() > 1) {
3476 // l intersection est en plusieurs edges (franchissement de couture)
3477 SelectEdge (F,EF,E,LInt1);
3479 NE = TopoDS::Edge(LInt1.First());
3480 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &NE.TShape());
3481 TE->Tolerance( TE->Tolerance()*10. ); //????
3482 if (NE.Orientation() == E.Orientation()) {
3483 Build.Bind(E,NE.Oriented(TopAbs_FORWARD));
3486 Build.Bind(E,NE.Oriented(TopAbs_REVERSED));
3488 const TopoDS_Edge& EOnV1 = TopoDS::Edge(NOnV1(E));
3489 if (!ToBuild .IsBound(EOnV1) &&
3490 !ConstShapes.IsBound(EOnV1) &&
3491 !Build .IsBound(EOnV1)) {
3492 ExtentEdge (F,EF,EOnV1,NE);
3493 Build.Bind (EOnV1,NE.Oriented(TopAbs_FORWARD));
3495 const TopoDS_Edge& EOnV2 = TopoDS::Edge(NOnV2(E));
3496 if (!ToBuild .IsBound(EOnV2) &&
3497 !ConstShapes.IsBound(EOnV2) &&
3498 !Build .IsBound(EOnV2)) {
3499 ExtentEdge (F,EF,EOnV2,NE);
3500 Build.Bind (EOnV2,NE.Oriented (TopAbs_FORWARD));
3505 //------------------------------------------------
3506 // Construction Vertex.
3507 //------------------------------------------------
3508 TopTools_ListOfShape LV;
3511 TopoDS_Vertex V1,V2;
3513 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE); exp2.More(); exp2.Next())
3515 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3516 TopExp::Vertices (E,V1,V2);
3517 BRep_Tool::Range (E,f,l);
3519 if (Build.IsBound(E))
3521 const TopoDS_Edge& NEOnV1 = TopoDS::Edge(NOnV1(E));
3522 if (Build.IsBound(NEOnV1) && (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV1)))
3524 if (E.IsSame(NEOnV1))
3525 V = TopExp::FirstVertex(TopoDS::Edge(Build(E)));
3531 if (!Build.IsBound(V1))
3533 Inter2d (EF,TopoDS::Edge(Build(E)), TopoDS::Edge(Build(NEOnV1)),LV,/*TolConf*/Precision::Confusion());
3537 if (Build(E).Orientation() == TopAbs_FORWARD)
3539 V = TopoDS::Vertex(LV.First());
3543 V = TopoDS::Vertex(LV.Last());
3553 V = TopoDS::Vertex(Build(V1));
3554 if (MVE (V1).Extent() > 2)
3556 V.Orientation(TopAbs_FORWARD);
3557 if (Build(E).Orientation() == TopAbs_REVERSED)
3558 V.Orientation(TopAbs_REVERSED);
3560 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3571 if (ConstShapes.IsBound(V1)) V = TopoDS::Vertex(ConstShapes(V1));
3572 V.Orientation(TopAbs_FORWARD);
3573 if (Build(E).Orientation() == TopAbs_REVERSED)
3574 V.Orientation(TopAbs_REVERSED);
3575 if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
3576 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3579 ConstShapes.Bind(V1,V);
3581 const TopoDS_Edge& NEOnV2 = TopoDS::Edge(NOnV2(E));
3582 if (Build.IsBound(NEOnV2) && (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV2)))
3584 if (E.IsSame(NEOnV2))
3585 V = TopExp::LastVertex(TopoDS::Edge(Build(E)));
3592 if (!Build.IsBound(V2))
3594 Inter2d (EF,TopoDS::Edge(Build(E)), TopoDS::Edge(Build(NEOnV2)),LV,/*TolConf*/Precision::Confusion());
3598 if (Build(E).Orientation() == TopAbs_FORWARD)
3600 V = TopoDS::Vertex(LV.Last());
3604 V = TopoDS::Vertex(LV.First());
3614 V = TopoDS::Vertex(Build(V2));
3615 if (MVE (V2).Extent() > 2)
3617 V.Orientation(TopAbs_REVERSED);
3618 if (Build(E).Orientation() == TopAbs_REVERSED)
3619 V.Orientation(TopAbs_FORWARD);
3621 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3632 if (ConstShapes.IsBound(V2))
3633 V = TopoDS::Vertex(ConstShapes(V2));
3634 V.Orientation(TopAbs_REVERSED);
3635 if (Build(E).Orientation() == TopAbs_REVERSED)
3636 V.Orientation(TopAbs_FORWARD);
3637 if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
3638 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3640 ConstShapes.Bind(V2,V);
3646 TopoDS_Vertex NV1,NV2;
3647 TopAbs_Orientation Or;
3648 Standard_Real U1,U2;
3649 Standard_Real eps = Precision::Confusion();
3659 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3660 exp2.More(); exp2.Next()) {
3661 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3662 TopExp::Vertices (E,V1,V2);
3663 if (Build.IsBound(E)) {
3664 NE = TopoDS::Edge(Build(E));
3665 BRep_Tool::Range(NE,f,l);
3666 Or = NE.Orientation();
3667 //-----------------------------------------------------
3668 // Copy pour virer les vertex deja sur la nouvelle edge.
3669 //-----------------------------------------------------
3670 NV1 = TopoDS::Vertex(ConstShapes(V1));
3671 NV2 = TopoDS::Vertex(ConstShapes(V2));
3673 TopoDS_Shape aLocalVertexOrientedNV1 = NV1.Oriented(TopAbs_INTERNAL);
3674 TopoDS_Shape aLocalEdge = NE.Oriented(TopAbs_INTERNAL);
3676 U1 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalVertexOrientedNV1),
3677 TopoDS::Edge (aLocalEdge));
3678 aLocalVertexOrientedNV1 = NV2.Oriented(TopAbs_INTERNAL);
3679 aLocalEdge = NE.Oriented(TopAbs_FORWARD);
3680 U2 = BRep_Tool::Parameter (TopoDS::Vertex(aLocalVertexOrientedNV1),TopoDS::Edge (aLocalEdge));
3681 // U1 = BRep_Tool::Parameter
3682 // (TopoDS::Vertex(NV1.Oriented(TopAbs_INTERNAL)),
3683 // TopoDS::Edge (NE .Oriented(TopAbs_FORWARD)));
3684 // U2 = BRep_Tool::Parameter
3685 // (TopoDS::Vertex(NV2.Oriented(TopAbs_INTERNAL)),
3686 // TopoDS::Edge (NE.Oriented(TopAbs_FORWARD)));
3687 aLocalEdge = NE.EmptyCopied();
3688 NE = TopoDS::Edge(aLocalEdge);
3689 NE.Orientation(TopAbs_FORWARD);
3690 if (NV1.IsSame(NV2))
3695 if (Or == TopAbs_FORWARD) {U1 = f; U2 = l;}
3696 else {U1 = l; U2 = f;}
3697 if (Or == TopAbs_FORWARD)
3701 if (Abs(U1-l) < eps) U1 = f;
3702 if (Abs(U2-f) < eps) U2 = l;
3704 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3705 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3706 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3707 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3708 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3709 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3711 ConstShapes.Bind(E,NE);
3712 NE.Orientation(E.Orientation());
3718 if (Abs(U2-l) < eps) U2 = f;
3719 if (Abs(U1-f) < eps) U1 = l;
3721 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3722 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3723 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3724 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3725 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3726 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3728 ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
3729 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3734 //-------------------
3735 // edge is not ferme.
3736 //-------------------
3737 if (Or == TopAbs_FORWARD) {
3739 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3740 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3741 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3742 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3743 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3744 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3749 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3750 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3751 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3752 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3753 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3754 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3757 ConstShapes.Bind(E,NE);
3758 NE.Orientation(E.Orientation());
3762 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3763 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3764 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3765 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3766 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3767 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3769 ConstShapes.Bind(E,NE);
3770 NE.Orientation(E.Orientation());
3774 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3775 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3776 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3777 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3778 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3779 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3781 ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
3782 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3787 } // Build.IsBound(E)
3788 else if (ConstShapes.IsBound(E)) { // !Build.IsBound(E)
3789 NE = TopoDS::Edge(ConstShapes(E));
3790 BuildPCurves(NE,NF);
3791 Or = NE.Orientation();
3792 if (Or == TopAbs_REVERSED) {
3793 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3796 NE.Orientation(E.Orientation());
3801 ConstShapes.Bind(E,NE.Oriented(TopAbs_FORWARD));
3805 B.Add(NF,NW.Oriented(W.Orientation()));
3807 NF.Orientation(F.Orientation());
3808 BRepTools::Update(NF); // Maj des UVPoints
3813 sprintf(name,"FOB_%d",NbFOB++);
3814 DBRep::Set(name,NF);
3820 //=======================================================================
3821 //function : Deboucle3D
3823 //=======================================================================
3825 TopoDS_Shape BRepOffset_Tool::Deboucle3D(const TopoDS_Shape& S,
3826 const TopTools_MapOfShape& Boundary)
3828 return BRepAlgo_Tool::Deboucle3D(S,Boundary);
3831 //=======================================================================
3832 //function : IsInOut
3834 //=======================================================================
3836 static Standard_Boolean IsInOut (BRepTopAdaptor_FClass2d& FC,
3837 Geom2dAdaptor_Curve AC,
3838 const TopAbs_State& S )
3840 Standard_Real Def = 100*Precision::Confusion();
3841 GCPnts_QuasiUniformDeflection QU(AC,Def);
3843 for (Standard_Integer i = 1; i <= QU.NbPoints(); i++) {
3844 gp_Pnt2d P = AC.Value(QU.Parameter(i));
3845 if (FC.Perform(P) != S) {
3846 return Standard_False;
3849 return Standard_True;
3852 //=======================================================================
3853 //function : CorrectOrientation
3855 //=======================================================================
3857 void BRepOffset_Tool::CorrectOrientation(const TopoDS_Shape& SI,
3858 const TopTools_IndexedMapOfShape& NewEdges,
3859 Handle(BRepAlgo_AsDes)& AsDes,
3860 BRepAlgo_Image& InitOffset,
3861 const Standard_Real Offset)
3864 TopExp_Explorer exp;
3865 exp.Init(SI,TopAbs_FACE);
3866 Standard_Real f=0.,l=0.;
3868 for (; exp.More(); exp.Next()) {
3870 const TopoDS_Face& FI = TopoDS::Face(exp.Current());
3871 const TopTools_ListOfShape& LOF = InitOffset.Image(FI);
3872 TopTools_ListIteratorOfListOfShape it(LOF);
3873 for (; it.More(); it.Next()) {
3874 const TopoDS_Face& OF = TopoDS::Face(it.Value());
3875 TopTools_ListOfShape& LOE = AsDes->ChangeDescendant(OF);
3876 TopTools_ListIteratorOfListOfShape itE(LOE);
3878 Standard_Boolean YaInt = Standard_False;
3879 for (; itE.More(); itE.Next()) {
3880 const TopoDS_Edge& OE = TopoDS::Edge(itE.Value());
3881 if (NewEdges.Contains(OE)) {YaInt = Standard_True; break;}
3884 TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
3885 BRepTopAdaptor_FClass2d FC (TopoDS::Face(aLocalFace),
3886 Precision::Confusion());
3887 // BRepTopAdaptor_FClass2d FC (TopoDS::Face(FI.Oriented(TopAbs_FORWARD)),
3888 // Precision::Confusion());
3889 for (itE.Initialize(LOE); itE.More(); itE.Next()) {
3890 TopoDS_Shape& OE = itE.Value();
3891 if (NewEdges.Contains(OE)) {
3892 Handle(Geom2d_Curve) CO2d =
3893 BRep_Tool::CurveOnSurface(TopoDS::Edge(OE),OF,f,l);
3894 Geom2dAdaptor_Curve AC(CO2d,f,l);
3897 if (IsInOut(FC,AC,TopAbs_OUT)) OE.Reverse();
3900 // if (IsInOut(FC,AC,TopAbs_IN)) OE.Reverse();
3910 //=======================================================================
3911 //function : CheckNormals
3913 //=======================================================================
3914 Standard_Boolean BRepOffset_Tool::CheckPlanesNormals(const TopoDS_Face& theFace1,
3915 const TopoDS_Face& theFace2,
3916 const Standard_Real theTolAng)
3918 BRepAdaptor_Surface aBAS1(theFace1, Standard_False), aBAS2(theFace2, Standard_False);
3919 if (aBAS1.GetType() != GeomAbs_Plane ||
3920 aBAS2.GetType() != GeomAbs_Plane) {
3921 return Standard_False;
3924 gp_Dir aDN1 = aBAS1.Plane().Position().Direction();
3925 if (theFace1.Orientation() == TopAbs_REVERSED) {
3929 gp_Dir aDN2 = aBAS2.Plane().Position().Direction();
3930 if (theFace2.Orientation() == TopAbs_REVERSED) {
3934 Standard_Real anAngle = aDN1.Angle(aDN2);
3935 return (anAngle < theTolAng);
3938 //=======================================================================
3939 //function : PerformPlanes
3941 //=======================================================================
3942 void PerformPlanes(const TopoDS_Face& theFace1,
3943 const TopoDS_Face& theFace2,
3944 const TopAbs_State theSide,
3945 TopTools_ListOfShape& theL1,
3946 TopTools_ListOfShape& theL2)
3950 // Intersect the planes using IntTools_FaceFace directly
3951 IntTools_FaceFace aFF;
3952 aFF.SetParameters(Standard_True, Standard_True, Standard_True, Precision::Confusion());
3953 aFF.Perform(theFace1, theFace2);
3955 if (!aFF.IsDone()) {
3959 const IntTools_SequenceOfCurves& aSC = aFF.Lines();
3960 if (aSC.IsEmpty()) {
3964 // In Plane/Plane intersection only one curve is always produced.
3965 // Make the edge from this section curve.
3969 const IntTools_Curve& aIC = aSC(1);
3970 const Handle(Geom_Curve)& aC3D = aIC.Curve();
3971 aBB.MakeEdge(aE, aC3D, aIC.Tolerance());
3972 // Get bounds of the curve
3973 Standard_Real aTF, aTL;
3975 aIC.Bounds(aTF, aTL, aPF, aPL);
3976 // Make the bounding vertices
3977 TopoDS_Vertex aVF, aVL;
3978 aBB.MakeVertex(aVF, aPF, aIC.Tolerance());
3979 aBB.MakeVertex(aVL, aPL, aIC.Tolerance());
3980 aVL.Orientation(TopAbs_REVERSED);
3981 // Add vertices to the edge
3984 // Add 2D curves to the edge
3985 aBB.UpdateEdge(aE, aIC.FirstCurve2d(), theFace1, aIC.Tolerance());
3986 aBB.UpdateEdge(aE, aIC.SecondCurve2d(), theFace2, aIC.Tolerance());
3987 // Update range of the new edge
3988 aBB.Range(aE, aTF, aTL);
3992 TopAbs_Orientation O1, O2;
3993 BRepOffset_Tool::OrientSection(aE, theFace1, theFace2, O1, O2);
3994 if (theSide == TopAbs_OUT) {
3995 O1 = TopAbs::Reverse(O1);
3996 O2 = TopAbs::Reverse(O2);
3999 BRepLib::SameParameter(aE, Precision::Confusion(), Standard_True);
4001 // Add edge to result
4002 theL1.Append(aE.Oriented(O1));
4003 theL2.Append(aE.Oriented(O2));
4006 //=======================================================================
4008 //purpose : Checks if the given value is close to infinite (TheInfini)
4009 //=======================================================================
4010 Standard_Boolean IsInf(const Standard_Real theVal)
4012 return (theVal > TheInfini*0.9);
4015 static void UpdateVertexTolerances(const TopoDS_Face& theFace)
4018 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
4019 TopExp::MapShapesAndAncestors(theFace, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
4021 for (Standard_Integer i = 1; i <= VEmap.Extent(); i++)
4023 const TopoDS_Vertex& aVertex = TopoDS::Vertex(VEmap.FindKey(i));
4024 const TopTools_ListOfShape& Elist = VEmap(i);
4025 gp_Pnt PntVtx = BRep_Tool::Pnt(aVertex);
4026 TopTools_ListIteratorOfListOfShape itl(Elist);
4027 for (; itl.More(); itl.Next())
4029 const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
4030 TopoDS_Vertex V1, V2;
4031 TopExp::Vertices(anEdge, V1, V2);
4032 Standard_Real fpar, lpar;
4033 BRep_Tool::Range(anEdge, fpar, lpar);
4034 Standard_Real aParam = (V1.IsSame(aVertex))? fpar : lpar;
4035 if (!BRep_Tool::Degenerated(anEdge))
4037 BRepAdaptor_Curve BAcurve(anEdge);
4038 gp_Pnt aPnt = BAcurve.Value(aParam);
4039 Standard_Real aDist = PntVtx.Distance(aPnt);
4040 BB.UpdateVertex(aVertex, aDist);
4043 aPnt = BAcurve.Value(lpar);
4044 aDist = PntVtx.Distance(aPnt);
4045 BB.UpdateVertex(aVertex, aDist);
4048 BRepAdaptor_Curve BAcurveonsurf(anEdge, theFace);
4049 gp_Pnt aPnt = BAcurveonsurf.Value(aParam);
4050 Standard_Real aDist = PntVtx.Distance(aPnt);
4051 BB.UpdateVertex(aVertex, aDist);
4054 aPnt = BAcurveonsurf.Value(lpar);
4055 aDist = PntVtx.Distance(aPnt);
4056 BB.UpdateVertex(aVertex, aDist);