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_TEdge.hxx>
26 #include <BRep_Builder.hxx>
27 #include <BRepAdaptor_Curve.hxx>
28 #include <BRepAdaptor_Curve2d.hxx>
29 #include <BRepAdaptor_Surface.hxx>
30 #include <BRepAlgo_AsDes.hxx>
31 #include <BRepAlgo_Image.hxx>
32 #include <BRepLib.hxx>
33 #include <BRepLib_MakeEdge.hxx>
34 #include <BRepLib_MakeFace.hxx>
35 #include <BRepLib_MakeVertex.hxx>
36 #include <BRepOffset_Analyse.hxx>
37 #include <BRepOffset_Interval.hxx>
38 #include <BRepOffset_ListOfInterval.hxx>
39 #include <BRepTools.hxx>
40 #include <BRepTools_Modifier.hxx>
41 #include <BRepTools_WireExplorer.hxx>
42 #include <BRepTopAdaptor_FClass2d.hxx>
45 #include <Extrema_ExtPC2d.hxx>
46 #include <BRepExtrema_DistShapeShape.hxx>
47 #include <GCPnts_AbscissaPoint.hxx>
48 #include <GCPnts_QuasiUniformDeflection.hxx>
49 #include <Geom2d_BezierCurve.hxx>
50 #include <Geom2d_BSplineCurve.hxx>
51 #include <Geom2d_Circle.hxx>
52 #include <Geom2d_Curve.hxx>
53 #include <Geom2d_Ellipse.hxx>
54 #include <Geom2d_Hyperbola.hxx>
55 #include <Geom2d_Line.hxx>
56 #include <Geom2d_Parabola.hxx>
57 #include <Geom2d_TrimmedCurve.hxx>
58 #include <Geom2dAdaptor_Curve.hxx>
59 #include <Geom2dConvert_ApproxCurve.hxx>
60 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
61 #include <Geom2dInt_GInter.hxx>
62 #include <Geom_BezierSurface.hxx>
63 #include <Geom_BSplineCurve.hxx>
64 #include <Geom_Conic.hxx>
65 #include <Geom_ConicalSurface.hxx>
66 #include <Geom_Curve.hxx>
67 #include <Geom_Line.hxx>
68 #include <Geom_OffsetSurface.hxx>
69 #include <Geom_Plane.hxx>
70 #include <Geom_RectangularTrimmedSurface.hxx>
71 #include <Geom_Surface.hxx>
72 #include <Geom_SurfaceOfLinearExtrusion.hxx>
73 #include <Geom_SurfaceOfRevolution.hxx>
74 #include <Geom_TrimmedCurve.hxx>
75 #include <GeomAdaptor_Surface.hxx>
76 #include <GeomAPI.hxx>
77 #include <GeomAPI_ExtremaCurveCurve.hxx>
78 #include <GeomAPI_ProjectPointOnCurve.hxx>
79 #include <GeomConvert_ApproxCurve.hxx>
80 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
81 #include <GeomInt_IntSS.hxx>
82 #include <GeomLib.hxx>
83 #include <GeomProjLib.hxx>
87 #include <IntRes2d_IntersectionPoint.hxx>
88 #include <IntRes2d_IntersectionSegment.hxx>
89 #include <IntTools_FaceFace.hxx>
90 #include <Precision.hxx>
91 #include <ProjLib_ProjectedCurve.hxx>
92 #include <ShapeCustom_Curve2d.hxx>
93 #include <Standard_ConstructionError.hxx>
96 #include <TopExp_Explorer.hxx>
98 #include <TopoDS_Compound.hxx>
99 #include <TopoDS_Edge.hxx>
100 #include <TopoDS_Face.hxx>
101 #include <TopoDS_Iterator.hxx>
102 #include <TopoDS_Shape.hxx>
103 #include <TopoDS_Vertex.hxx>
104 #include <TopoDS_Wire.hxx>
105 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
106 #include <TopTools_SequenceOfShape.hxx>
110 // The constant defines the maximal value to enlarge surfaces.
111 // It is limited to 1.e+7. This limitation is justified by the
112 // floating point format. As we can have only 15
113 // valuable decimal numbers, then during intersection of surfaces with
114 // bounds of 1.e+8 the possible inaccuracy might appear already in seventh
115 // decimal place which will be more than Precision::Confusion value -
116 // 1.e-7, default tolerance value for the section curves.
117 // By decreasing the max enlarge value to 1.e+7 the inaccuracy will be
118 // shifted to eighth decimal place, i.e. the inaccuracy will be
119 // decreased to values less than 1.e-7.
120 const Standard_Real TheInfini = 1.e+7;
122 //tma: for new boolean operation
125 #include <Geom2d_Conic.hxx>
126 #include <Geom_BoundedCurve.hxx>
127 Standard_Boolean AffichInter = Standard_False;
128 static Standard_Integer NbNewEdges = 1;
129 static Standard_Integer NbFaces = 1;
130 static Standard_Integer NbFOB = 1;
131 static Standard_Integer NbFTE = 1;
132 static Standard_Integer NbExtE = 1;
136 static Standard_Boolean AffichExtent = Standard_False;
140 void PerformPlanes(const TopoDS_Face& theFace1,
141 const TopoDS_Face& theFace2,
142 const TopAbs_State theState,
143 TopTools_ListOfShape& theL1,
144 TopTools_ListOfShape& theL2);
146 static void UpdateVertexTolerances(const TopoDS_Face& theFace);
149 Standard_Boolean IsInf(const Standard_Real theVal);
151 //=======================================================================
152 //function : EdgeVertices
154 //=======================================================================
156 void BRepOffset_Tool::EdgeVertices (const TopoDS_Edge& E,
160 if (E.Orientation() == TopAbs_REVERSED) {
161 TopExp::Vertices(E,V2,V1);
164 TopExp::Vertices(E,V1,V2);
168 //=======================================================================
169 //function : FindPeriod
171 //=======================================================================
173 static void FindPeriod (const TopoDS_Face& F,
182 for (exp.Init(F,TopAbs_EDGE); exp.More(); exp.Next()) {
183 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
186 const Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,pf,pl);
187 if (C.IsNull()) return;
188 Geom2dAdaptor_Curve PC(C,pf,pl);
189 Standard_Real i, nbp = 20;
190 if (PC.GetType() == GeomAbs_Line) nbp = 2;
191 Standard_Real step = (pl - pf) / nbp;
195 for (i = 2; i < nbp; i++) {
202 B.Get(umin,vmin,umax,vmax);
206 //=======================================================================
207 //function : PutInBounds
208 //purpose : Recadre la courbe 2d dans les bounds de la face
209 //=======================================================================
211 static void PutInBounds (const TopoDS_Face& F,
212 const TopoDS_Edge& E,
213 Handle(Geom2d_Curve)& C2d)
215 Standard_Real umin,umax,vmin,vmax;
217 BRep_Tool::Range(E,f,l);
219 TopLoc_Location L; // Recup S avec la location pour eviter la copie.
220 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
222 if (S->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
223 S = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
228 if (!S->IsUPeriodic() && !S->IsVPeriodic()) return;
230 FindPeriod (F,umin,umax,vmin,vmax);
232 if (S->IsUPeriodic()) {
233 Standard_Real period = S->UPeriod();
234 Standard_Real eps = period*1.e-6;
235 gp_Pnt2d Pf = C2d->Value(f);
236 gp_Pnt2d Pl = C2d->Value(l);
237 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
238 Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
239 Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
240 Standard_Real du = 0.;
241 if (minC< umin - eps) {
242 du = (int((umin - minC)/period) + 1)*period;
244 if (minC > umax + eps) {
245 du = -(int((minC - umax)/period) + 1)*period;
250 minC += du; maxC += du;
252 // Ajuste au mieux la courbe dans le domaine.
253 if (maxC > umax +100*eps) {
254 Standard_Real d1 = maxC - umax;
255 Standard_Real d2 = umin - minC + period;
256 if (d2 < d1) du =-period;
266 if (S->IsVPeriodic()) {
267 Standard_Real period = S->VPeriod();
268 Standard_Real eps = period*1.e-6;
269 gp_Pnt2d Pf = C2d->Value(f);
270 gp_Pnt2d Pl = C2d->Value(l);
271 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
272 Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
273 Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
274 Standard_Real dv = 0.;
275 if (minC< vmin - eps) {
276 dv = (int((vmin - minC)/period) + 1)*period;
278 if (minC > vmax + eps) {
279 dv = -(int((minC - vmax)/period) + 1)*period;
284 minC += dv; maxC += dv;
286 // Ajuste au mieux la courbe dans le domaine.
287 if (maxC > vmax +100*eps) {
288 Standard_Real d1 = maxC - vmax;
289 Standard_Real d2 = vmin - minC + period;
290 if (d2 < d1) dv =-period;
299 //=======================================================================
302 //=======================================================================
304 Standard_Real BRepOffset_Tool::Gabarit(const Handle(Geom_Curve)& aCurve)
306 GeomAdaptor_Curve GC( aCurve );
308 BndLib_Add3dCurve::Add( GC, Precision::Confusion(), aBox );
309 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dist;
310 aBox.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
311 dist = Max( (aXmax-aXmin), (aYmax-aYmin) );
312 dist = Max( dist, (aZmax-aZmin) );
316 //=======================================================================
317 //function : BuildPCurves
319 //=======================================================================
321 static void BuildPCurves (const TopoDS_Edge& E,
322 const TopoDS_Face& F)
325 Handle (Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E,F,ff,ll);
326 if (!C2d.IsNull()) return;
328 //Standard_Real Tolerance = Max(Precision::Confusion(),BRep_Tool::Tolerance(E));
329 Standard_Real Tolerance = Precision::Confusion();
331 BRepAdaptor_Surface AS(F,0);
332 BRepAdaptor_Curve AC(E);
334 //Try to find pcurve on a bound of BSpline or Bezier surface
335 Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( F );
336 Handle( Standard_Type ) typS = theSurf->DynamicType();
337 if (typS == STANDARD_TYPE(Geom_OffsetSurface))
338 typS = Handle(Geom_OffsetSurface)::DownCast (theSurf)->BasisSurface()->DynamicType();
339 if (typS == STANDARD_TYPE(Geom_BezierSurface) || typS == STANDARD_TYPE(Geom_BSplineSurface))
341 gp_Pnt fpoint = AC.Value( AC.FirstParameter() );
342 gp_Pnt lpoint = AC.Value( AC.LastParameter() );
343 TopoDS_Face theFace = BRepLib_MakeFace( theSurf, Precision::Confusion() );
344 Standard_Real U1 = 0., U2 = 0., TolProj = 1.e-4; //1.e-5;
346 TopExp_Explorer Explo;
347 Explo.Init( theFace, TopAbs_EDGE );
348 for (; Explo.More(); Explo.Next())
350 TopoDS_Edge anEdge = TopoDS::Edge( Explo.Current() );
351 BRepAdaptor_Curve aCurve( anEdge );
352 Extrema_ExtPC fextr( fpoint, aCurve );
353 if (!fextr.IsDone() || fextr.NbExt() < 1)
355 Standard_Real dist2, dist2min = RealLast();
357 for (i = 1; i <= fextr.NbExt(); i++)
359 dist2 = fextr.SquareDistance(i);
360 if (dist2 < dist2min)
363 U1 = fextr.Point(i).Parameter();
366 if (dist2min > TolProj * TolProj)
368 Extrema_ExtPC lextr( lpoint, aCurve );
369 if (!lextr.IsDone() || lextr.NbExt() <1)
371 dist2min = RealLast();
372 for (i = 1; i <= lextr.NbExt(); i++)
374 dist2 = lextr.SquareDistance(i);
375 if (dist2 < dist2min)
378 U2 = lextr.Point(i).Parameter();
381 if (dist2min <= TolProj * TolProj)
386 } // for (; Explo.More(); Explo.Current())
388 if (! theEdge.IsNull())
390 //Construction of pcurve
393 Standard_Real temp = U1;
398 C2d = BRep_Tool::CurveOnSurface( theEdge, theFace, f, l );
399 C2d = new Geom2d_TrimmedCurve( C2d, U1, U2 );
401 if (theSurf->IsUPeriodic() || theSurf->IsVPeriodic())
402 PutInBounds( F, E, C2d );
405 B.UpdateEdge( E, C2d, F, BRep_Tool::Tolerance(E) );
406 BRepLib::SameRange( E );
412 Handle(BRepAdaptor_Surface) HS = new BRepAdaptor_Surface(AS);
413 Handle(BRepAdaptor_Curve) HC = new BRepAdaptor_Curve(AC);
415 ProjLib_ProjectedCurve Proj(HS,HC,Tolerance);
417 switch ( Proj.GetType()) {
420 C2d = new Geom2d_Line(Proj.Line());
424 C2d = new Geom2d_Circle(Proj.Circle());
427 case GeomAbs_Ellipse:
428 C2d = new Geom2d_Ellipse(Proj.Ellipse());
431 case GeomAbs_Parabola:
432 C2d = new Geom2d_Parabola(Proj.Parabola());
435 case GeomAbs_Hyperbola:
436 C2d = new Geom2d_Hyperbola(Proj.Hyperbola());
439 case GeomAbs_BezierCurve:
443 case GeomAbs_BSplineCurve:
444 C2d = Proj.BSpline();
450 if (AS.IsUPeriodic() || AS.IsVPeriodic()) {
451 PutInBounds(F,E,C2d);
455 B.UpdateEdge (E,C2d,F,BRep_Tool::Tolerance(E));
458 throw Standard_ConstructionError("BRepOffset_Tool::BuildPCurves");
462 //=======================================================================
465 //=======================================================================
467 void BRepOffset_Tool::OrientSection (const TopoDS_Edge& E,
468 const TopoDS_Face& F1,
469 const TopoDS_Face& F2,
470 TopAbs_Orientation& O1,
471 TopAbs_Orientation& O2)
477 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
478 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
479 Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l);
480 Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l);
481 Handle (Geom_Curve) C = BRep_Tool::Curve(E,L,f,l);
483 BRepAdaptor_Curve BAcurve( E );
485 GCPnts_AbscissaPoint AP(BAcurve,GCPnts_AbscissaPoint::Length(BAcurve)/2.0,f);
486 Standard_Real ParOnC;
489 ParOnC = AP.Parameter();
491 ParOnC = BOPTools_AlgoTools2D::IntermediatePoint(f, l);
493 gp_Vec T1 = C->DN(ParOnC,1).Transformed(L.Transformation());
494 if (T1.SquareMagnitude() > gp::Resolution()) {
498 gp_Pnt2d P = C1->Value(ParOnC);
502 S1->D1(P.X(),P.Y(),P3,D1U,D1V);
504 if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse();
506 P = C2->Value(ParOnC);
507 S2->D1(P.X(),P.Y(),P3,D1U,D1V);
509 if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse();
511 gp_Vec ProVec = DN2^T1;
512 Standard_Real Prod = DN1.Dot(ProVec);
517 O1 = TopAbs_REVERSED;
520 Prod = DN2.Dot(ProVec);
525 O2 = TopAbs_REVERSED;
527 if (F1.Orientation() == TopAbs_REVERSED) O1 = TopAbs::Reverse(O1);
528 if (F2.Orientation() == TopAbs_REVERSED) O2 = TopAbs::Reverse(O2);
531 //=======================================================================
532 //function : FindCommonShapes
534 //=======================================================================
535 Standard_Boolean BRepOffset_Tool::FindCommonShapes(const TopoDS_Face& theF1,
536 const TopoDS_Face& theF2,
537 TopTools_ListOfShape& theLE,
538 TopTools_ListOfShape& theLV)
540 Standard_Boolean bFoundEdges =
541 FindCommonShapes(theF1, theF2, TopAbs_EDGE, theLE);
542 Standard_Boolean bFoundVerts =
543 FindCommonShapes(theF1, theF2, TopAbs_VERTEX, theLV);
544 return bFoundEdges || bFoundVerts;
547 //=======================================================================
548 //function : FindCommonShapes
550 //=======================================================================
551 Standard_Boolean BRepOffset_Tool::FindCommonShapes(const TopoDS_Shape& theS1,
552 const TopoDS_Shape& theS2,
553 const TopAbs_ShapeEnum theType,
554 TopTools_ListOfShape& theLSC)
558 TopTools_MapOfShape aMS;
559 TopExp_Explorer aExp(theS1, theType);
560 for (; aExp.More(); aExp.Next()) {
561 aMS.Add(aExp.Current());
565 return Standard_False;
568 TopTools_MapOfShape aMFence;
569 aExp.Init(theS2, theType);
570 for (; aExp.More(); aExp.Next()) {
571 const TopoDS_Shape& aS2 = aExp.Current();
572 if (aMS.Contains(aS2)) {
573 if (aMFence.Add(aS2)) {
579 return !theLSC.IsEmpty();
582 //=======================================================================
585 //=======================================================================
587 static Standard_Boolean ToSmall (const Handle(Geom_Curve)& C)
589 Standard_Real Tol = 10*Precision::Confusion();
590 Standard_Real m = (C->FirstParameter()*0.668 + C->LastParameter()*0.332);
591 gp_Pnt P1 = C->Value(C->FirstParameter());
592 gp_Pnt P2 = C->Value(C->LastParameter());
593 gp_Pnt P3 = C->Value(m);
594 if (P1.Distance(P2) > Tol) return Standard_False;
595 if (P2.Distance(P3) > Tol) return Standard_False;
596 return Standard_True;
600 //=======================================================================
601 //function : IsOnSurface
603 //=======================================================================
605 static Standard_Boolean IsOnSurface(const Handle(Geom_Curve)& C,
606 const Handle(Geom_Surface)& S,
607 Standard_Real TolConf,
608 Standard_Real& TolReached)
610 Standard_Real f = C->FirstParameter();
611 Standard_Real l = C->LastParameter();
612 Standard_Integer n = 5;
613 Standard_Real du = (f-l)/(n-1);
619 GeomAdaptor_Surface AS(S);
621 switch ( AS.GetType()) {
624 gp_Ax3 Ax = AS.Plane().Position();
625 for ( Standard_Integer i = 0; i < n; i++) {
626 P = C->Value(f+i*du);
627 ElSLib::PlaneParameters(Ax,P,U,V);
628 TolReached = P.Distance(ElSLib::PlaneValue(U,V,Ax));
629 if ( TolReached > TolConf)
630 return Standard_False;
634 case GeomAbs_Cylinder:
636 gp_Ax3 Ax = AS.Cylinder().Position();
637 Standard_Real Rad = AS.Cylinder().Radius();
638 for ( Standard_Integer i = 0; i < n; i++) {
639 P = C->Value(f+i*du);
640 ElSLib::CylinderParameters(Ax,Rad,P,U,V);
641 TolReached = P.Distance(ElSLib::CylinderValue(U,V,Ax,Rad));
642 if ( TolReached > TolConf)
643 return Standard_False;
649 gp_Ax3 Ax = AS.Cone().Position();
650 Standard_Real Rad = AS.Cone().RefRadius();
651 Standard_Real Alp = AS.Cone().SemiAngle();
652 for ( Standard_Integer i = 0; i < n; i++) {
653 P = C->Value(f+i*du);
654 ElSLib::ConeParameters(Ax,Rad,Alp,P,U,V);
655 TolReached = P.Distance(ElSLib::ConeValue(U,V,Ax,Rad,Alp));
656 if ( TolReached > TolConf)
657 return Standard_False;
663 gp_Ax3 Ax = AS.Sphere().Position();
664 Standard_Real Rad = AS.Sphere().Radius();
665 for ( Standard_Integer i = 0; i < n; i++) {
666 P = C->Value(f+i*du);
667 ElSLib::SphereParameters(Ax,Rad,P,U,V);
668 TolReached = P.Distance(ElSLib::SphereValue(U,V,Ax,Rad));
669 if ( TolReached > TolConf)
670 return Standard_False;
676 gp_Ax3 Ax = AS.Torus().Position();
677 Standard_Real R1 = AS.Torus().MajorRadius();
678 Standard_Real R2 = AS.Torus().MinorRadius();
679 for ( Standard_Integer i = 0; i < n; i++) {
680 P = C->Value(f+i*du);
681 ElSLib::TorusParameters(Ax,R1,R2,P,U,V);
682 TolReached = P.Distance(ElSLib::TorusValue(U,V,Ax,R1,R2));
683 if ( TolReached > TolConf)
684 return Standard_False;
691 return Standard_False;
695 return Standard_True;
699 //=======================================================================
700 //function : PipeInter
702 //=======================================================================
704 void BRepOffset_Tool::PipeInter(const TopoDS_Face& F1,
705 const TopoDS_Face& F2,
706 TopTools_ListOfShape& L1,
707 TopTools_ListOfShape& L2,
708 const TopAbs_State Side)
713 sprintf(name,"FF_%d",NbFaces++);
715 sprintf(name,"FF_%d",NbFaces++);
720 Handle (Geom_Curve) CI;
721 TopAbs_Orientation O1,O2;
722 L1.Clear(); L2.Clear();
724 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
725 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
727 GeomInt_IntSS Inter (S1,S2, Precision::Confusion(),1,1,1);
729 if (Inter.IsDone()) {
730 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
732 if (ToSmall(CI)) continue;
733 TopoDS_Edge E = BRepLib_MakeEdge(CI);
734 if (Inter.HasLineOnS1(i)) {
735 Handle(Geom2d_Curve) C2 = Inter.LineOnS1(i);
736 PutInBounds (F1,E,C2);
737 B.UpdateEdge (E,C2,F1,BRep_Tool::Tolerance(E));
742 if (Inter.HasLineOnS2(i)) {
743 Handle(Geom2d_Curve) C2 = Inter.LineOnS2(i);
744 PutInBounds (F2,E,C2);
745 B.UpdateEdge (E,C2,F2,BRep_Tool::Tolerance(E));
750 OrientSection (E,F1,F2,O1,O2);
751 if (Side == TopAbs_OUT) {
752 O1 = TopAbs::Reverse(O1);
753 O2 = TopAbs::Reverse(O2);
755 L1.Append (E.Oriented(O1));
756 L2.Append (E.Oriented(O2));
760 sprintf(name,"EI_%d",NbNewEdges++);
761 DBRep::Set(name,E.Oriented(O1));
768 //=======================================================================
769 //function : IsAutonomVertex
770 //purpose : Checks whether a vertex is "autonom" or not
771 //=======================================================================
773 static Standard_Boolean IsAutonomVertex(const TopoDS_Shape& theVertex,
774 const BOPDS_PDS& thePDS,
775 const TopoDS_Face& theFace1,
776 const TopoDS_Face& theFace2)
778 Standard_Integer nV = thePDS->Index(theVertex);
779 Standard_Integer nF [2];
780 nF[0] = thePDS->Index(theFace1);
781 nF[1] = thePDS->Index(theFace2);
783 for (Standard_Integer i = 0; i < 2; i++)
785 const BOPDS_FaceInfo& aFaceInfo = thePDS->FaceInfo(nF[i]);
786 const TColStd_MapOfInteger& IndMap = aFaceInfo.VerticesOn();
787 if (IndMap.Contains(nV))
788 return Standard_False;
791 return Standard_True;
794 //=======================================================================
795 //function : IsAutonomVertex
796 //purpose : Checks whether a vertex is "autonom" or not
797 //=======================================================================
799 static Standard_Boolean IsAutonomVertex(const TopoDS_Shape& aVertex,
800 const BOPDS_PDS& pDS)
802 Standard_Integer index;
803 Standard_Integer aNbVVs, aNbEEs, aNbEFs, aInt;
805 index = pDS->Index(aVertex);
807 Standard_Integer i, i1, i2;
808 i1=pDS->NbSourceShapes();
810 for (i=i1; i<i2; ++i) {
811 const TopoDS_Shape& aSx=pDS->Shape(i);
812 if(aSx.IsSame(aVertex)) {
819 if (!pDS->IsNewShape(index)) {
820 return Standard_False;
822 //check if vertex with index "index" is not created in VV or EE or EF interference
824 BOPDS_VectorOfInterfVV& aVVs=pDS->InterfVV();
825 aNbVVs = aVVs.Length();
826 for(aInt = 0; aInt < aNbVVs; aInt++) {
827 const BOPDS_InterfVV& aVV = aVVs(aInt);
828 if (aVV.HasIndexNew()) {
829 if (aVV.IndexNew() == index) {
830 return Standard_False;
835 BOPDS_VectorOfInterfEE& aEEs=pDS->InterfEE();
836 aNbEEs = aEEs.Length();
837 for(aInt = 0; aInt < aNbEEs; aInt++) {
838 const BOPDS_InterfEE& aEE = aEEs(aInt);
839 IntTools_CommonPrt aCP = aEE.CommonPart();
840 if(aCP.Type() == TopAbs_VERTEX) {
841 if (aEE.IndexNew() == index) {
842 return Standard_False;
847 BOPDS_VectorOfInterfEF& aEFs=pDS->InterfEF();
848 aNbEFs = aEFs.Length();
849 for(aInt = 0; aInt < aNbEFs; aInt++) {
850 const BOPDS_InterfEF& aEF = aEFs(aInt);
851 IntTools_CommonPrt aCP = aEF.CommonPart();
852 if(aCP.Type() == TopAbs_VERTEX) {
853 if (aEF.IndexNew() == index) {
854 return Standard_False;
858 return Standard_True;
862 //=======================================================================
863 //function : AreConnex
864 //purpose : define if two shapes are connex by a vertex (vertices)
865 //=======================================================================
867 static Standard_Boolean AreConnex(const TopoDS_Wire& W1,
868 const TopoDS_Wire& W2)
870 TopoDS_Vertex V11, V12, V21, V22;
871 TopExp::Vertices( W1, V11, V12 );
872 TopExp::Vertices( W2, V21, V22 );
874 if (V11.IsSame(V21) || V11.IsSame(V22) ||
875 V12.IsSame(V21) || V12.IsSame(V22))
876 return Standard_True;
878 return Standard_False;
881 //=======================================================================
882 //function : AreClosed
883 //purpose : define if two edges are connex by two vertices
884 //=======================================================================
886 static Standard_Boolean AreClosed(const TopoDS_Edge& E1,
887 const TopoDS_Edge& E2)
889 TopoDS_Vertex V11, V12, V21, V22;
890 TopExp::Vertices( E1, V11, V12 );
891 TopExp::Vertices( E2, V21, V22 );
893 if ((V11.IsSame(V21) && V12.IsSame(V22)) ||
894 (V11.IsSame(V22) && V12.IsSame(V21)))
895 return Standard_True;
897 return Standard_False;
900 //=======================================================================
901 //function : BSplineEdges
903 //=======================================================================
905 static Standard_Boolean BSplineEdges(const TopoDS_Edge& E1,
906 const TopoDS_Edge& E2,
907 const Standard_Integer par1,
908 const Standard_Integer par2,
909 Standard_Real& angle)
911 Standard_Real first1, last1, first2, last2, Param1, Param2;
913 Handle(Geom_Curve) C1 = BRep_Tool::Curve( E1, first1, last1 );
914 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
915 C1 = Handle(Geom_TrimmedCurve)::DownCast (C1)->BasisCurve();
917 Handle(Geom_Curve) C2 = BRep_Tool::Curve( E2, first2, last2 );
918 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
919 C2 = Handle(Geom_TrimmedCurve)::DownCast (C2)->BasisCurve();
921 if (!C1->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)) ||
922 !C2->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)))
923 return Standard_False;
925 Param1 = (par1 == 0)? first1 : last1;
926 Param2 = (par2 == 0)? first2 : last2;
930 C1->D1( Param1, Pnt1, Der1 );
931 C2->D1( Param2, Pnt2, Der2 );
933 if (Der1.Magnitude() <= gp::Resolution() ||
934 Der2.Magnitude() <= gp::Resolution())
937 angle = Der1.Angle(Der2);
939 return Standard_True;
942 //=======================================================================
943 //function : AngleWireEdge
945 //=======================================================================
947 static Standard_Real AngleWireEdge(const TopoDS_Wire& aWire,
948 const TopoDS_Edge& anEdge)
950 TopoDS_Vertex V11, V12, V21, V22, CV;
951 TopExp::Vertices( aWire, V11, V12 );
952 TopExp::Vertices( anEdge, V21, V22 );
953 CV = (V11.IsSame(V21) || V11.IsSame(V22))? V11 : V12;
954 TopoDS_Edge FirstEdge;
955 TopoDS_Iterator itw(aWire);
956 for (; itw.More(); itw.Next())
958 FirstEdge = TopoDS::Edge(itw.Value());
959 TopoDS_Vertex v1, v2;
960 TopExp::Vertices( FirstEdge, v1, v2 );
961 if (v1.IsSame(CV) || v2.IsSame(CV))
969 if (V11.IsSame(CV) && V21.IsSame(CV))
971 BSplineEdges( FirstEdge, anEdge, 0, 0, Angle );
972 Angle = M_PI - Angle;
974 else if (V11.IsSame(CV) && V22.IsSame(CV))
975 BSplineEdges( FirstEdge, anEdge, 0, 1, Angle );
976 else if (V12.IsSame(CV) && V21.IsSame(CV))
977 BSplineEdges( FirstEdge, anEdge, 1, 0, Angle );
980 BSplineEdges( FirstEdge, anEdge, 1, 1, Angle );
981 Angle = M_PI - Angle;
987 //=======================================================================
988 //function : ReconstructPCurves
990 //=======================================================================
992 static void ReconstructPCurves(const TopoDS_Edge& anEdge)
995 Handle(Geom_Curve) C3d = BRep_Tool::Curve(anEdge, f, l);
997 BRep_ListIteratorOfListOfCurveRepresentation
998 itcr( (Handle(BRep_TEdge)::DownCast(anEdge.TShape()))->ChangeCurves() );
999 for (; itcr.More(); itcr.Next())
1001 Handle( BRep_CurveRepresentation ) CurveRep = itcr.Value();
1002 if (CurveRep->IsCurveOnSurface())
1004 Handle(Geom_Surface) theSurf = CurveRep->Surface();
1005 TopLoc_Location theLoc = CurveRep->Location();
1006 theLoc = anEdge.Location() * theLoc;
1007 theSurf = Handle(Geom_Surface)::DownCast
1008 (theSurf->Transformed(theLoc.Transformation()));
1009 Handle(Geom2d_Curve) ProjPCurve =
1010 GeomProjLib::Curve2d( C3d, f, l, theSurf );
1011 if(!ProjPCurve.IsNull())
1013 CurveRep->PCurve( ProjPCurve );
1019 //=======================================================================
1020 //function : ConcatPCurves
1022 //=======================================================================
1024 static Handle(Geom2d_Curve) ConcatPCurves(const TopoDS_Edge& E1,
1025 const TopoDS_Edge& E2,
1026 const TopoDS_Face& F,
1027 const Standard_Boolean After,
1028 Standard_Real& newFirst,
1029 Standard_Real& newLast)
1031 Standard_Real Tol = 1.e-7;
1032 GeomAbs_Shape Continuity = GeomAbs_C1;
1033 Standard_Integer MaxDeg = 14;
1034 Standard_Integer MaxSeg = 16;
1036 Standard_Real first1, last1, first2, last2;
1037 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1039 PCurve1 = BRep_Tool::CurveOnSurface( E1, F, first1, last1 );
1040 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
1041 PCurve1 = Handle(Geom2d_TrimmedCurve)::DownCast (PCurve1)->BasisCurve();
1043 PCurve2 = BRep_Tool::CurveOnSurface( E2, F, first2, last2 );
1044 if (PCurve2->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
1045 PCurve2 = Handle(Geom2d_TrimmedCurve)::DownCast (PCurve2)->BasisCurve();
1047 if (PCurve1 == PCurve2)
1049 newPCurve = PCurve1;
1050 newFirst = Min( first1, first2 );
1051 newLast = Max( last1, last2 );
1053 else if (PCurve1->DynamicType() == PCurve2->DynamicType() &&
1054 (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)) ||
1055 PCurve1->IsKind(STANDARD_TYPE(Geom2d_Conic))))
1057 newPCurve = PCurve1;
1059 P1 = PCurve2->Value( first2 );
1060 P2 = PCurve2->Value( last2 );
1061 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)))
1063 Handle(Geom2d_Line) Lin1 = Handle(Geom2d_Line)::DownCast (PCurve1);
1064 gp_Lin2d theLin = Lin1->Lin2d();
1065 first2 = ElCLib::Parameter( theLin, P1 );
1066 last2 = ElCLib::Parameter( theLin, P2 );
1068 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Circle)))
1070 Handle(Geom2d_Circle) Circ1 = Handle(Geom2d_Circle)::DownCast (PCurve1);
1071 gp_Circ2d theCirc = Circ1->Circ2d();
1072 first2 = ElCLib::Parameter( theCirc, P1 );
1073 last2 = ElCLib::Parameter( theCirc, P2 );
1075 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Ellipse)))
1077 Handle(Geom2d_Ellipse) Ell1 = Handle(Geom2d_Ellipse)::DownCast (PCurve1);
1078 gp_Elips2d theElips = Ell1->Elips2d();
1079 first2 = ElCLib::Parameter( theElips, P1 );
1080 last2 = ElCLib::Parameter( theElips, P2 );
1082 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Parabola)))
1084 Handle(Geom2d_Parabola) Parab1 = Handle(Geom2d_Parabola)::DownCast (PCurve1);
1085 gp_Parab2d theParab = Parab1->Parab2d();
1086 first2 = ElCLib::Parameter( theParab, P1 );
1087 last2 = ElCLib::Parameter( theParab, P2 );
1089 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Hyperbola)))
1091 Handle(Geom2d_Hyperbola) Hypr1 = Handle(Geom2d_Hyperbola)::DownCast (PCurve1);
1092 gp_Hypr2d theHypr = Hypr1->Hypr2d();
1093 first2 = ElCLib::Parameter( theHypr, P1 );
1094 last2 = ElCLib::Parameter( theHypr, P2 );
1096 newFirst = Min( first1, first2 );
1097 newLast = Max( last1, last2 );
1101 Handle(Geom2d_TrimmedCurve) TC1 = new Geom2d_TrimmedCurve( PCurve1, first1, last1 );
1102 Handle(Geom2d_TrimmedCurve) TC2 = new Geom2d_TrimmedCurve( PCurve2, first2, last2 );
1103 Geom2dConvert_CompCurveToBSplineCurve Concat2d( TC1 );
1104 Concat2d.Add( TC2, Precision::Confusion(), After );
1105 newPCurve = Concat2d.BSplineCurve();
1106 if (newPCurve->Continuity() < GeomAbs_C1)
1108 Geom2dConvert_ApproxCurve Approx2d( newPCurve, Tol, Continuity, MaxSeg, MaxDeg );
1109 if (Approx2d.HasResult())
1110 newPCurve = Approx2d.Curve();
1112 newFirst = newPCurve->FirstParameter();
1113 newLast = newPCurve->LastParameter();
1119 //=======================================================================
1121 //purpose : glue two edges.
1122 //=======================================================================
1124 static TopoDS_Edge Glue(const TopoDS_Edge& E1,
1125 const TopoDS_Edge& E2,
1126 const TopoDS_Vertex& Vfirst,
1127 const TopoDS_Vertex& Vlast,
1128 const Standard_Boolean After,
1129 const TopoDS_Face& F1,
1130 const Standard_Boolean addPCurve1,
1131 const TopoDS_Face& F2,
1132 const Standard_Boolean addPCurve2,
1133 const Standard_Real theGlueTol)
1135 TopoDS_Edge newEdge;
1137 Standard_Real Tol = 1.e-7;
1138 GeomAbs_Shape Continuity = GeomAbs_C1;
1139 Standard_Integer MaxDeg = 14;
1140 Standard_Integer MaxSeg = 16;
1142 Handle(Geom_Curve) C1, C2, newCurve;
1143 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1144 Standard_Real first1, last1, first2, last2, fparam=0., lparam=0.;
1145 Standard_Boolean IsCanonic = Standard_False;
1147 C1 = BRep_Tool::Curve( E1, first1, last1 );
1148 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
1149 C1 = Handle(Geom_TrimmedCurve)::DownCast (C1)->BasisCurve();
1151 C2 = BRep_Tool::Curve( E2, first2, last2 );
1152 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
1153 C2 = Handle(Geom_TrimmedCurve)::DownCast (C2)->BasisCurve();
1158 fparam = Min( first1, first2 );
1159 lparam = Max( last1, last2 );
1161 else if (C1->DynamicType() == C2->DynamicType() &&
1162 (C1->IsInstance(STANDARD_TYPE(Geom_Line)) ||
1163 C1->IsKind(STANDARD_TYPE(Geom_Conic))))
1165 IsCanonic = Standard_True;
1170 Handle(Geom_TrimmedCurve) TC1 = new Geom_TrimmedCurve( C1, first1, last1 );
1171 Handle(Geom_TrimmedCurve) TC2 = new Geom_TrimmedCurve( C2, first2, last2 );
1172 GeomConvert_CompCurveToBSplineCurve Concat( TC1 );
1173 if (!Concat.Add( TC2, theGlueTol, After ))
1175 newCurve = Concat.BSplineCurve();
1176 if (newCurve->Continuity() < GeomAbs_C1)
1178 GeomConvert_ApproxCurve Approx3d( newCurve, Tol, Continuity, MaxSeg, MaxDeg );
1179 if (Approx3d.HasResult())
1180 newCurve = Approx3d.Curve();
1182 fparam = newCurve->FirstParameter();
1183 lparam = newCurve->LastParameter();
1189 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast );
1191 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast, fparam, lparam );
1193 Standard_Real newFirst, newLast;
1196 newPCurve = ConcatPCurves( E1, E2, F1, After, newFirst, newLast );
1197 BB.UpdateEdge( newEdge, newPCurve, F1, 0. );
1198 BB.Range( newEdge, F1, newFirst, newLast );
1202 newPCurve = ConcatPCurves( E1, E2, F2, After, newFirst, newLast );
1203 BB.UpdateEdge( newEdge, newPCurve, F2, 0. );
1204 BB.Range( newEdge, F2, newFirst, newLast );
1210 //=======================================================================
1211 //function : CheckIntersFF
1213 //=======================================================================
1215 static void CheckIntersFF(const BOPDS_PDS& pDS,
1216 const TopoDS_Edge& RefEdge,
1217 TopTools_IndexedMapOfShape& TrueEdges)
1219 BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF();
1220 Standard_Integer aNb = aFFs.Length();
1221 Standard_Integer i, j, nbe = 0;
1223 TopoDS_Compound Edges;
1225 BB.MakeCompound(Edges);
1227 for (i = 0; i < aNb; ++i)
1229 BOPDS_InterfFF& aFFi=aFFs(i);
1230 const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
1231 Standard_Integer aNbCurves = aBCurves.Length();
1233 for (j = 0; j < aNbCurves; ++j)
1235 const BOPDS_Curve& aBC=aBCurves(j);
1236 const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
1238 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1239 aPBIt.Initialize(aSectEdges);
1241 for (; aPBIt.More(); aPBIt.Next())
1243 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
1244 Standard_Integer nSect = aPB->Edge();
1245 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
1246 BB.Add(Edges, anEdge);
1255 TopTools_ListOfShape CompList;
1256 BOPTools_AlgoTools::MakeConnexityBlocks(Edges, TopAbs_VERTEX, TopAbs_EDGE, CompList);
1258 TopoDS_Shape NearestCompound;
1259 if (CompList.Extent() == 1)
1260 NearestCompound = CompList.First();
1263 BRepAdaptor_Curve BAcurve(RefEdge);
1264 gp_Pnt Pref = BAcurve.Value((BAcurve.FirstParameter()+BAcurve.LastParameter())/2);
1265 TopoDS_Vertex Vref = BRepLib_MakeVertex(Pref);
1266 Standard_Real MinDist = RealLast();
1267 TopTools_ListIteratorOfListOfShape itl(CompList);
1268 for (; itl.More(); itl.Next())
1270 const TopoDS_Shape& aCompound = itl.Value();
1272 BRepExtrema_DistShapeShape Projector(Vref, aCompound);
1273 if (!Projector.IsDone() || Projector.NbSolution() == 0)
1276 Standard_Real aDist = Projector.Value();
1277 if (aDist < MinDist)
1280 NearestCompound = aCompound;
1285 TopExp::MapShapes(NearestCompound, TopAbs_EDGE, TrueEdges);
1288 //=======================================================================
1289 //function : AssembleEdge
1291 //=======================================================================
1293 static TopoDS_Edge AssembleEdge(const BOPDS_PDS& pDS,
1294 const TopoDS_Face& F1,
1295 const TopoDS_Face& F2,
1296 const Standard_Boolean addPCurve1,
1297 const Standard_Boolean addPCurve2,
1298 const TopTools_SequenceOfShape& EdgesForConcat)
1300 TopoDS_Edge NullEdge;
1301 TopoDS_Edge CurEdge = TopoDS::Edge( EdgesForConcat(1) );
1302 Standard_Real aGlueTol = Precision::Confusion();
1304 for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
1306 TopoDS_Edge anEdge = TopoDS::Edge( EdgesForConcat(j) );
1307 Standard_Boolean After = Standard_False;
1308 TopoDS_Vertex Vfirst, Vlast;
1309 Standard_Boolean AreClosedWire = AreClosed( CurEdge, anEdge );
1312 TopoDS_Vertex V1, V2;
1313 TopExp::Vertices( CurEdge, V1, V2 );
1314 Standard_Boolean IsAutonomV1 = IsAutonomVertex( V1, pDS, F1, F2 );
1315 Standard_Boolean IsAutonomV2 = IsAutonomVertex( V2, pDS, F1, F2 );
1318 After = Standard_False;
1319 Vfirst = Vlast = V2;
1321 else if (IsAutonomV2)
1323 After = Standard_True;
1324 Vfirst = Vlast = V1;
1331 TopoDS_Vertex CV, V11, V12, V21, V22;
1332 TopExp::CommonVertex( CurEdge, anEdge, CV );
1333 Standard_Boolean IsAutonomCV = Standard_False;
1336 IsAutonomCV = IsAutonomVertex(CV, pDS, F1, F2);
1340 aGlueTol = BRep_Tool::Tolerance(CV);
1341 TopExp::Vertices( CurEdge, V11, V12 );
1342 TopExp::Vertices( anEdge, V21, V22 );
1343 if (V11.IsSame(CV) && V21.IsSame(CV))
1348 else if (V11.IsSame(CV) && V22.IsSame(CV))
1353 else if (V12.IsSame(CV) && V21.IsSame(CV))
1366 } //end of else (open wire)
1368 TopoDS_Edge NewEdge = Glue(CurEdge, anEdge, Vfirst, Vlast, After,
1369 F1, addPCurve1, F2, addPCurve2, aGlueTol);
1370 if (NewEdge.IsNull())
1374 } //end of for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
1379 //=======================================================================
1380 //function : Inter3D
1382 //=======================================================================
1384 void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1,
1385 const TopoDS_Face& F2,
1386 TopTools_ListOfShape& L1,
1387 TopTools_ListOfShape& L2,
1388 const TopAbs_State Side,
1389 const TopoDS_Edge& RefEdge,
1390 const TopoDS_Face& theRefFace1,
1391 const TopoDS_Face& theRefFace2)
1396 sprintf(name,"FF_%d",NbFaces++);
1397 DBRep::Set(name,F1);
1398 sprintf(name,"FF_%d",NbFaces++);
1399 DBRep::Set(name,F2);
1403 // Check if the faces are planar and not trimmed - in this case
1404 // the IntTools_FaceFace intersection algorithm will be used directly.
1405 BRepAdaptor_Surface aBAS1(F1, Standard_False), aBAS2(F2, Standard_False);
1406 if (aBAS1.GetType() == GeomAbs_Plane &&
1407 aBAS2.GetType() == GeomAbs_Plane) {
1408 aBAS1.Initialize(F1, Standard_True);
1409 if (IsInf(aBAS1.LastUParameter()) && IsInf(aBAS1.LastVParameter())) {
1410 aBAS2.Initialize(F2, Standard_True);
1411 if (IsInf(aBAS2.LastUParameter()) && IsInf(aBAS2.LastVParameter())) {
1412 // Intersect the planes without pave filler
1413 PerformPlanes(F1, F2, Side, L1, L2);
1419 // create 3D curves on faces
1420 BRepLib::BuildCurves3d(F1);
1421 BRepLib::BuildCurves3d(F2);
1422 UpdateVertexTolerances(F1);
1423 UpdateVertexTolerances(F2);
1425 BOPAlgo_PaveFiller aPF;
1426 TopTools_ListOfShape aLS;
1429 aPF.SetArguments(aLS);
1433 TopTools_IndexedMapOfShape TrueEdges;
1434 if (!RefEdge.IsNull())
1435 CheckIntersFF( aPF.PDS(), RefEdge, TrueEdges );
1437 Standard_Boolean addPCurve1 = 1;
1438 Standard_Boolean addPCurve2 = 1;
1440 const BOPDS_PDS& pDS = aPF.PDS();
1441 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
1442 Standard_Integer aNb = aFFs.Length();
1443 Standard_Integer i = 0, j = 0, k;
1445 L1.Clear(); L2.Clear();
1446 TopAbs_Orientation O1,O2;
1449 const Handle(IntTools_Context)& aContext = aPF.Context();
1451 for (i = 0; i < aNb; i++) {
1452 BOPDS_InterfFF& aFFi=aFFs(i);
1453 const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
1455 Standard_Integer aNbCurves = aBCurves.Length();
1457 for (j = 0; j < aNbCurves; j++) {
1458 const BOPDS_Curve& aBC=aBCurves(j);
1459 const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
1461 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1462 aPBIt.Initialize(aSectEdges);
1464 for (; aPBIt.More(); aPBIt.Next()) {
1465 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
1466 Standard_Integer nSect = aPB->Edge();
1467 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
1468 if (!TrueEdges.IsEmpty() && !TrueEdges.Contains(anEdge))
1472 const Handle(Geom_Curve)& aC3DE = BRep_Tool::Curve(anEdge, f, l);
1473 Handle(Geom_TrimmedCurve) aC3DETrim;
1476 aC3DETrim = new Geom_TrimmedCurve(aC3DE, f, l);
1478 Standard_Real aTolEdge = BRep_Tool::Tolerance(anEdge);
1480 if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F1)) {
1481 Handle(Geom2d_Curve) aC2d = aBC.Curve().FirstCurve2d();
1482 if(!aC3DETrim.IsNull()) {
1483 Handle(Geom2d_Curve) aC2dNew;
1485 if(aC3DE->IsPeriodic()) {
1486 BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, f, l, aC2d, aC2dNew, aContext);
1489 BOPTools_AlgoTools2D::AdjustPCurveOnFace(F1, aC3DETrim, aC2d, aC2dNew, aContext);
1493 BB.UpdateEdge(anEdge, aC2d, F1, aTolEdge);
1496 if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, F2)) {
1497 Handle(Geom2d_Curve) aC2d = aBC.Curve().SecondCurve2d();
1498 if(!aC3DETrim.IsNull()) {
1499 Handle(Geom2d_Curve) aC2dNew;
1501 if(aC3DE->IsPeriodic()) {
1502 BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, f, l, aC2d, aC2dNew, aContext);
1505 BOPTools_AlgoTools2D::AdjustPCurveOnFace(F2, aC3DETrim, aC2d, aC2dNew, aContext);
1509 BB.UpdateEdge(anEdge, aC2d, F2, aTolEdge);
1512 OrientSection (anEdge, F1, F2, O1, O2);
1513 if (Side == TopAbs_OUT) {
1514 O1 = TopAbs::Reverse(O1);
1515 O2 = TopAbs::Reverse(O2);
1518 L1.Append (anEdge.Oriented(O1));
1519 L2.Append (anEdge.Oriented(O2));
1524 sprintf(name,"EI_%d",NbNewEdges++);
1525 DBRep::Set(name,anEdge.Oriented(O1));
1533 Standard_Real aSameParTol = Precision::Confusion();
1534 Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
1536 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F1);
1537 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1538 aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
1539 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1540 addPCurve1 = Standard_False;
1541 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1542 isEl1 = Standard_True;
1544 aSurf = BRep_Tool::Surface(F2);
1545 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1546 aSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (aSurf)->BasisSurface();
1547 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1548 addPCurve2 = Standard_False;
1549 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1550 isEl2 = Standard_True;
1552 if (L1.Extent() > 1 && (!isEl1 || !isEl2) && !theRefFace1.IsNull())
1554 //remove excess edges that are out of range
1555 TopoDS_Vertex aV1, aV2;
1556 TopExp::Vertices (RefEdge, aV1, aV2);
1557 if (!aV1.IsSame(aV2)) //only if RefEdge is open
1559 Handle(Geom_Surface) aRefSurf1 = BRep_Tool::Surface (theRefFace1);
1560 Handle(Geom_Surface) aRefSurf2 = BRep_Tool::Surface (theRefFace2);
1561 if (aRefSurf1->IsUClosed() || aRefSurf1->IsVClosed() ||
1562 aRefSurf2->IsUClosed() || aRefSurf2->IsVClosed())
1564 TopoDS_Edge MinAngleEdge;
1565 Standard_Real MinAngle = Precision::Infinite();
1566 BRepAdaptor_Curve aRefBAcurve (RefEdge);
1567 gp_Pnt aRefPnt = aRefBAcurve.Value ((aRefBAcurve.FirstParameter() + aRefBAcurve.LastParameter())/2);
1569 TopTools_ListIteratorOfListOfShape itl (L1);
1570 for (; itl.More(); itl.Next())
1572 const TopoDS_Edge& anEdge = TopoDS::Edge (itl.Value());
1574 BRepAdaptor_Curve aBAcurve (anEdge);
1575 gp_Pnt aMidPntOnEdge = aBAcurve.Value ((aBAcurve.FirstParameter() + aBAcurve.LastParameter())/2);
1576 gp_Vec RefToMid (aRefPnt, aMidPntOnEdge);
1578 Extrema_ExtPC aProjector (aRefPnt, aBAcurve);
1579 if (aProjector.IsDone())
1581 Standard_Integer imin = 0;
1582 Standard_Real MinSqDist = Precision::Infinite();
1583 for (Standard_Integer ind = 1; ind <= aProjector.NbExt(); ind++)
1585 Standard_Real aSqDist = aProjector.SquareDistance(ind);
1586 if (aSqDist < MinSqDist)
1588 MinSqDist = aSqDist;
1594 gp_Pnt aProjectionOnEdge = aProjector.Point(imin).Value();
1595 gp_Vec RefToProj (aRefPnt, aProjectionOnEdge);
1596 Standard_Real anAngle = RefToProj.Angle(RefToMid);
1597 if (anAngle < MinAngle)
1600 MinAngleEdge = anEdge;
1606 if (!MinAngleEdge.IsNull())
1608 TopTools_ListIteratorOfListOfShape itlist1 (L1);
1609 TopTools_ListIteratorOfListOfShape itlist2 (L2);
1611 while (itlist1.More())
1613 const TopoDS_Shape& anEdge = itlist1.Value();
1614 if (anEdge.IsSame(MinAngleEdge))
1627 } //if (!aV1.IsSame(aV2))
1628 } //if (L1.Extent() > 1 && (!isEl1 || !isEl2) && !theRefFace1.IsNull())
1630 if (L1.Extent() > 1 && (!isEl1 || !isEl2)) {
1631 TopTools_SequenceOfShape eseq;
1632 TopTools_SequenceOfShape EdgesForConcat;
1634 if (!TrueEdges.IsEmpty())
1636 for (i = TrueEdges.Extent(); i >= 1; i--)
1637 EdgesForConcat.Append( TrueEdges(i) );
1638 TopoDS_Edge AssembledEdge =
1639 AssembleEdge( pDS, F1, F2, addPCurve1, addPCurve2, EdgesForConcat );
1640 if (AssembledEdge.IsNull())
1641 for (i = TrueEdges.Extent(); i >= 1; i--)
1642 eseq.Append( TrueEdges(i) );
1644 eseq.Append(AssembledEdge);
1648 TopTools_SequenceOfShape wseq;
1649 TopTools_SequenceOfShape edges;
1650 TopTools_ListIteratorOfListOfShape itl(L1);
1651 for (; itl.More(); itl.Next())
1652 edges.Append( itl.Value() );
1653 while (!edges.IsEmpty())
1655 TopoDS_Edge anEdge = TopoDS::Edge( edges.First() );
1656 TopoDS_Wire aWire, resWire;
1658 BB.Add( aWire, anEdge );
1659 TColStd_SequenceOfInteger Candidates;
1660 for (k = 1; k <= wseq.Length(); k++)
1662 resWire = TopoDS::Wire(wseq(k));
1663 if (AreConnex( resWire, aWire ))
1665 Candidates.Append( 1 );
1669 if (Candidates.IsEmpty())
1671 wseq.Append( aWire );
1676 for (j = 2; j <= edges.Length(); j++)
1678 anEdge = TopoDS::Edge( edges(j) );
1681 BB.Add( aWire, anEdge );
1682 if (AreConnex( resWire, aWire ))
1683 Candidates.Append( j );
1685 Standard_Integer minind = 1;
1686 if (Candidates.Length() > 1)
1688 Standard_Real MinAngle = RealLast();
1689 for (j = 1; j <= Candidates.Length(); j++)
1691 anEdge = TopoDS::Edge( edges(Candidates(j)) );
1692 Standard_Real anAngle = AngleWireEdge( resWire, anEdge );
1693 if (anAngle < MinAngle)
1700 BB.Add( resWire, TopoDS::Edge(edges(Candidates(minind))) );
1702 edges.Remove(Candidates(minind));
1704 } //end of while (!edges.IsEmpty())
1706 for (i = 1; i <= wseq.Length(); i++)
1708 TopoDS_Wire aWire = TopoDS::Wire(wseq(i));
1709 TopTools_SequenceOfShape aLocalEdgesForConcat;
1712 TopoDS_Vertex StartVertex;
1713 TopoDS_Edge StartEdge;
1714 Standard_Boolean StartFound = Standard_False;
1715 TopTools_ListOfShape Elist;
1717 TopoDS_Iterator itw(aWire);
1718 for (; itw.More(); itw.Next())
1720 TopoDS_Edge anEdge = TopoDS::Edge(itw.Value());
1722 Elist.Append(anEdge);
1725 TopoDS_Vertex V1, V2;
1726 TopExp::Vertices( anEdge, V1, V2 );
1727 if (!IsAutonomVertex( V1, pDS ))
1731 StartFound = Standard_True;
1733 else if (!IsAutonomVertex( V2, pDS ))
1737 StartFound = Standard_True;
1740 Elist.Append(anEdge);
1742 } //end of for (; itw.More(); itw.Next())
1745 itl.Initialize(Elist);
1746 StartEdge = TopoDS::Edge(itl.Value());
1748 TopoDS_Vertex V1, V2;
1749 TopExp::Vertices( StartEdge, V1, V2 );
1752 aLocalEdgesForConcat.Append( StartEdge );
1753 while (!Elist.IsEmpty())
1755 for (itl.Initialize(Elist); itl.More(); itl.Next())
1757 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
1758 TopoDS_Vertex V1, V2;
1759 TopExp::Vertices( anEdge, V1, V2 );
1760 if (V1.IsSame(StartVertex))
1763 aLocalEdgesForConcat.Append( anEdge );
1767 else if (V2.IsSame(StartVertex))
1770 aLocalEdgesForConcat.Append( anEdge );
1775 } //end of while (!Elist.IsEmpty())
1776 } //end of if (aWire.Closed())
1779 BRepTools_WireExplorer Wexp( aWire );
1780 for (; Wexp.More(); Wexp.Next())
1781 aLocalEdgesForConcat.Append( Wexp.Current() );
1784 TopoDS_Edge AssembledEdge =
1785 AssembleEdge( pDS, F1, F2, addPCurve1, addPCurve2, aLocalEdgesForConcat );
1786 if (AssembledEdge.IsNull())
1787 for (j = aLocalEdgesForConcat.Length(); j >= 1; j--)
1788 eseq.Append( aLocalEdgesForConcat(j) );
1790 eseq.Append( AssembledEdge );
1791 } //for (i = 1; i <= wseq.Length(); i++)
1792 } //end of else (when TrueEdges is empty)
1794 if (eseq.Length() < L1.Extent())
1798 for (i = 1; i <= eseq.Length(); i++)
1800 TopoDS_Shape aShape = eseq(i);
1801 TopoDS_Edge anEdge = TopoDS::Edge(eseq(i));
1802 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1803 Standard_Real EdgeTol = BRep_Tool::Tolerance(anEdge);
1805 std::cout<<"Tolerance of glued E = "<<EdgeTol<<std::endl;
1807 if (EdgeTol > 1.e-2)
1810 if (EdgeTol >= 1.e-4)
1812 ReconstructPCurves(anEdge);
1813 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1815 std::cout<<"After projection tol of E = "<<BRep_Tool::Tolerance(anEdge)<<std::endl;
1819 OrientSection( anEdge, F1, F2, O1, O2 );
1820 if (Side == TopAbs_OUT)
1822 O1 = TopAbs::Reverse(O1);
1823 O2 = TopAbs::Reverse(O2);
1826 L1.Append( anEdge.Oriented(O1) );
1827 L2.Append( anEdge.Oriented(O2) );
1830 } //end of if (L1.Extent() > 1)
1834 TopTools_ListIteratorOfListOfShape itl(L1);
1835 for (; itl.More(); itl.Next())
1837 const TopoDS_Edge& anEdge = TopoDS::Edge( itl.Value() );
1838 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1843 //=======================================================================
1844 //function : TryProject
1846 //=======================================================================
1848 Standard_Boolean BRepOffset_Tool::TryProject
1849 (const TopoDS_Face& F1,
1850 const TopoDS_Face& F2,
1851 const TopTools_ListOfShape& Edges,
1852 TopTools_ListOfShape& LInt1,
1853 TopTools_ListOfShape& LInt2,
1854 const TopAbs_State Side,
1855 const Standard_Real TolConf)
1860 sprintf(name,"FF_%d",NbFaces++);
1861 DBRep::Set(name,F1);
1862 sprintf(name,"FF_%d",NbFaces++);
1863 DBRep::Set(name,F2);
1867 // try to find if the edges <Edges> are laying on the face F1.
1868 LInt1.Clear(); LInt2.Clear();
1869 TopTools_ListIteratorOfListOfShape it(Edges);
1870 Standard_Boolean isOk = Standard_True;
1871 Standard_Boolean Ok = Standard_True;
1872 TopAbs_Orientation O1,O2;
1873 Handle(Geom_Surface) Bouchon = BRep_Tool::Surface(F1);
1876 for ( ; it.More(); it.Next()) {
1879 TopoDS_Edge CurE = TopoDS::Edge(it.Value());
1880 Handle(Geom_Curve) C = BRep_Tool::Curve(CurE,L,f,l);
1882 BRepLib::BuildCurve3d(CurE,BRep_Tool::Tolerance(CurE));
1883 C = BRep_Tool::Curve(CurE,L,f,l);
1885 C = new Geom_TrimmedCurve(C,f,l);
1886 if ( !L.IsIdentity()) C->Transform(L);
1887 Standard_Real TolReached;
1888 isOk = IsOnSurface(C,Bouchon,TolConf,TolReached);
1891 B.UpdateEdge(CurE,TolReached);
1892 BuildPCurves(CurE,F1);
1893 OrientSection (CurE,F1,F2,O1,O2);
1894 if (Side == TopAbs_OUT) {
1895 O1 = TopAbs::Reverse(O1);
1896 O2 = TopAbs::Reverse(O2);
1898 LInt1.Append (CurE.Oriented(O1));
1899 LInt2.Append (CurE.Oriented(O2));
1903 sprintf(name,"EI_%d",NbNewEdges++);
1904 DBRep::Set(name,CurE.Oriented(O1));
1909 Ok = Standard_False;
1915 //=======================================================================
1916 //function : InterOrExtent
1918 //=======================================================================
1920 void BRepOffset_Tool::InterOrExtent(const TopoDS_Face& F1,
1921 const TopoDS_Face& F2,
1922 TopTools_ListOfShape& L1,
1923 TopTools_ListOfShape& L2,
1924 const TopAbs_State Side)
1929 sprintf(name,"FF_%d",NbFaces++);
1930 DBRep::Set(name,F1);
1931 sprintf(name,"FF_%d",NbFaces++);
1932 DBRep::Set(name,F2);
1936 Handle (Geom_Curve) CI;
1937 TopAbs_Orientation O1,O2;
1938 L1.Clear(); L2.Clear();
1939 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
1940 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
1942 if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1943 Handle(Geom_RectangularTrimmedSurface) RTS ;
1944 RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S1);
1945 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
1946 S1 = RTS->BasisSurface();
1949 if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
1950 Handle(Geom_RectangularTrimmedSurface) RTS ;
1951 RTS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S2);
1952 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
1953 S2 = RTS->BasisSurface();
1957 GeomInt_IntSS Inter (S1,S2, Precision::Confusion());
1959 if (Inter.IsDone()) {
1960 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
1963 if (ToSmall(CI)) continue;
1964 TopoDS_Edge E = BRepLib_MakeEdge(CI);
1965 BuildPCurves (E,F1);
1966 BuildPCurves (E,F2);
1967 OrientSection (E,F1,F2,O1,O2);
1968 if (Side == TopAbs_OUT) {
1969 O1 = TopAbs::Reverse(O1);
1970 O2 = TopAbs::Reverse(O2);
1972 L1.Append (E.Oriented(O1));
1973 L2.Append (E.Oriented(O2));
1977 sprintf(name,"EI_%d",NbNewEdges++);
1978 DBRep::Set(name,E.Oriented(O1));
1985 //=======================================================================
1986 //function : ExtentEdge
1988 //=======================================================================
1990 static void ExtentEdge(const TopoDS_Face& F,
1991 const TopoDS_Face& EF,
1992 const TopoDS_Edge& E,
1995 BRepAdaptor_Curve CE(E);
1996 GeomAbs_CurveType Type = CE.GetType();
1997 TopoDS_Shape aLocalEdge = E.EmptyCopied();
1998 NE = TopoDS::Edge(aLocalEdge);
1999 // NE = TopoDS::Edge(E.EmptyCopied());
2001 if (Type == GeomAbs_Line || Type == GeomAbs_Circle || Type == GeomAbs_Ellipse ||
2002 Type == GeomAbs_Hyperbola || Type == GeomAbs_Parabola) {
2005 // Extension en tangence jusqu'au bord de la surface.
2006 Standard_Real PMax = 1.e2;
2008 Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
2009 Standard_Real umin,umax,vmin,vmax;
2011 S->Bounds(umin,umax,vmin,vmax);
2012 umin = Max(umin,-PMax);vmin = Max(vmin,-PMax);
2013 umax = Min(umax, PMax);vmax = Min(vmax, PMax);
2017 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f,l);
2019 //calcul point cible . ie point d'intersection du prolongement tangent et des bords.
2022 C2d->D1(CE.FirstParameter(),P,Tang);
2023 Standard_Real tx,ty,tmin;
2024 tx = ty = Precision::Infinite();
2025 if (Abs(Tang.X()) > Precision::Confusion())
2026 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
2027 if (Abs(Tang.Y()) > Precision::Confusion())
2028 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
2031 gp_Pnt2d PF2d (P.X() - Tang.X(),P.Y() - Tang.Y());
2033 C2d->D1(CE.LastParameter(),P,Tang);
2034 tx = ty = Precision::Infinite();
2035 if (Abs(Tang.X()) > Precision::Confusion())
2036 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
2037 if (Abs(Tang.Y()) > Precision::Confusion())
2038 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
2041 gp_Pnt2d PL2d (P.X() + Tang.X(),P.Y() + Tang.Y());
2043 Handle(Geom_Curve) CC = GeomAPI::To3d(C2d,gp_Pln(gp::XOY()));
2044 gp_Pnt PF(PF2d.X(),PF2d.Y(),0.);
2045 gp_Pnt PL(PL2d.X(),PL2d.Y(),0.);
2047 Handle(Geom_BoundedCurve) ExtC = Handle(Geom_BoundedCurve)::DownCast(CC);
2048 if (ExtC.IsNull()) return;
2050 GeomLib::ExtendCurveToPoint(ExtC,PF,1,0);
2051 GeomLib::ExtendCurveToPoint(ExtC,PL,1,1);
2053 Handle(Geom2d_Curve) CNE2d = GeomAPI::To2d(ExtC,gp_Pln(gp::XOY()));
2055 //Construction de la nouvelle arrete;
2058 // B.UpdateEdge (NE,CNE2d,F,BRep_Tool::Tolerance(E));
2059 B.UpdateEdge (NE,CNE2d,EF,BRep_Tool::Tolerance(E));
2060 B.Range (NE,CNE2d->FirstParameter(), CNE2d->LastParameter());
2061 NE.Orientation(E.Orientation());
2065 sprintf (name,"F_%d",NbExtE);
2066 DBRep::Set(name,EF);
2067 sprintf (name,"OE_%d",NbExtE);
2068 DBRep::Set (name,E);
2069 sprintf (name,"ExtE_%d",NbExtE++);
2070 DBRep::Set(name,NE);
2075 //=======================================================================
2076 //function : ProjectVertexOnEdge
2078 //=======================================================================
2080 static Standard_Boolean ProjectVertexOnEdge(TopoDS_Vertex& V,
2081 const TopoDS_Edge& E,
2082 Standard_Real TolConf)
2092 Standard_Real U = 0.;
2094 Standard_Boolean found = Standard_False;
2096 gp_Pnt P = BRep_Tool::Pnt (V);
2097 BRepAdaptor_Curve C = BRepAdaptor_Curve(E);
2098 f = C.FirstParameter(); l = C.LastParameter();
2100 if (V.Orientation() == TopAbs_FORWARD) {
2101 if (Abs(f) < Precision::Infinite()) {
2102 gp_Pnt PF = C.Value (f);
2103 if (PF.IsEqual(P,TolConf)) {
2105 found = Standard_True;
2109 if (V.Orientation() == TopAbs_REVERSED) {
2110 if (!found && Abs(l) < Precision::Infinite()) {
2111 gp_Pnt PL = C.Value (l);
2112 if (PL.IsEqual(P,TolConf)) {
2114 found = Standard_True;
2119 Extrema_ExtPC Proj(P,C);
2120 if (Proj.IsDone() && Proj.NbExt() > 0) {
2121 Standard_Real Dist2,Dist2Min = Proj.SquareDistance(1);
2122 U = Proj.Point(1).Parameter();
2123 for (Standard_Integer i = 2; i <= Proj.NbExt(); i++) {
2124 Dist2 = Proj.SquareDistance(i);
2125 if (Dist2 < Dist2Min) {
2127 U = Proj.Point(i).Parameter();
2130 found = Standard_True;
2136 Standard_Real Dist = P.Distance(C.Value(U));
2137 if (Dist > TolConf) {
2138 std::cout << " ProjectVertexOnEdge :distance vertex edge :"<<Dist<<std::endl;
2140 if (U < f - Precision::Confusion() ||
2141 U > l + Precision::Confusion()) {
2142 std::cout << " ProjectVertexOnEdge : hors borne :"<<std::endl;
2143 std::cout << " f = "<<f<<" l ="<<l<< " U ="<<U<<std::endl;
2147 std::cout <<"BRepOffset_Tool::ProjectVertexOnEdge Parameter no found"<<std::endl;
2148 if (Abs(f) < Precision::Infinite() &&
2149 Abs(l) < Precision::Infinite()) {
2157 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
2158 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
2159 aLocalShape = V.Oriented(TopAbs_INTERNAL);
2160 // TopoDS_Edge EE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
2161 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
2162 U,EE,BRep_Tool::Tolerance(E));
2168 //=======================================================================
2169 //function : Inter2d
2171 //=======================================================================
2173 void BRepOffset_Tool::Inter2d (const TopoDS_Face& F,
2174 const TopoDS_Edge& E1,
2175 const TopoDS_Edge& E2,
2176 TopTools_ListOfShape& LV,
2177 const Standard_Real TolConf)
2181 DBRep::Set("E1",E1);
2182 DBRep::Set("E2",E2);
2187 Standard_Real fl1[2],fl2[2];
2190 // Si l edge a ete etendu les pcurves ne sont pas forcement
2196 // Construction des curves 3d si elles n existent pas
2197 // utile pour coder correctement les parametres des vertex
2198 // d intersection sur les edges.
2199 //TopLoc_Location L;
2200 //Standard_Real f,l;
2201 //Handle(Geom_Curve) C3d1 = BRep_Tool::Curve(E1,L,f,l);
2202 //if (C3d1.IsNull()) {
2203 // BRepLib::BuildCurve3d(E1,BRep_Tool::Tolerance(E1));
2205 //Handle(Geom_Curve) C3d2 = BRep_Tool::Curve(E2,L,f,l);
2206 //if (C3d2.IsNull()) {
2207 // BRepLib::BuildCurve3d(E2,BRep_Tool::Tolerance(E2));
2210 Standard_Integer NbPC1 = 1, NbPC2 = 1;
2211 if (BRep_Tool::IsClosed(E1,F)) NbPC1++;
2212 if (BRep_Tool::IsClosed(E2,F)) NbPC2++;
2214 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
2215 Handle(Geom2d_Curve) C1, C2;
2216 Standard_Boolean YaSol = Standard_False;
2217 Standard_Integer itry = 0;
2219 while (!YaSol && itry < 2) {
2220 for ( Standard_Integer i = 1; i <= NbPC1 ; i++) {
2221 TopoDS_Shape aLocalEdgeReversedE1 = E1.Reversed();
2222 if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
2223 else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdgeReversedE1),
2225 // if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
2226 // else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E1.Reversed()),
2227 // F,fl1[0],fl1[1]);
2228 for ( Standard_Integer j = 1; j <= NbPC2; j++ ) {
2229 TopoDS_Shape aLocalEdge = E2.Reversed();
2230 if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2231 else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdge),
2233 // if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2234 // else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E2.Reversed()),
2235 // F,fl2[0],fl2[1]);
2237 if (C1.IsNull() || C2.IsNull()) {
2238 std::cout <<"Inter2d : Pas de pcurve"<<std::endl;
2240 DBRep::Set("E1",E1);
2241 DBRep::Set("E2",E2);
2247 Standard_Real U1 = 0.,U2 = 0.;
2249 Standard_Boolean aCurrentFind = Standard_False;
2251 fl1[0] = C1->FirstParameter(); fl1[1] = C1->LastParameter();
2252 fl2[0] = C2->FirstParameter(); fl2[1] = C2->LastParameter();
2254 Geom2dAdaptor_Curve AC1(C1,fl1[0],fl1[1]);
2255 Geom2dAdaptor_Curve AC2(C2,fl2[0],fl2[1]);
2258 gp_Pnt2d P1[2],P2[2];
2259 P1[0] = C1->Value(fl1[0]); P1[1] = C1->Value(fl1[1]);
2260 P2[0] = C2->Value(fl2[0]); P2[1] = C2->Value(fl2[1]);
2262 Standard_Integer i1 ;
2263 for ( i1 = 0; i1 < 2; i1++) {
2264 for (Standard_Integer i2 = 0; i2 < 2; i2++) {
2265 if (Abs(fl1[i1]) < Precision::Infinite() &&
2266 Abs(fl2[i2]) < Precision::Infinite() ) {
2267 if (P1[i1].IsEqual(P2[i2],TolConf)) {
2268 YaSol = Standard_True;
2269 aCurrentFind = Standard_True;
2270 U1 = fl1[i1]; U2 = fl2[i2];
2271 P2d = C1->Value(U1);
2277 for (i1 = 0; i1 < 2; i1++)
2279 Extrema_ExtPC2d extr( P1[i1], AC2 );
2280 if (extr.IsDone() && extr.NbExt() > 0)
2282 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2283 Standard_Integer IndexMin = 1;
2284 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2286 Dist2 = extr.SquareDistance(ind);
2287 if (Dist2 < Dist2Min)
2293 if (Dist2Min <= Precision::SquareConfusion())
2295 YaSol = Standard_True;
2296 aCurrentFind = Standard_True;
2299 U2 = (extr.Point(IndexMin)).Parameter();
2305 for (Standard_Integer i2 = 0; i2 < 2; i2++)
2307 Extrema_ExtPC2d extr( P2[i2], AC1 );
2308 if (extr.IsDone() && extr.NbExt() > 0)
2310 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2311 Standard_Integer IndexMin = 1;
2312 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2314 Dist2 = extr.SquareDistance(ind);
2315 if (Dist2 < Dist2Min)
2321 if (Dist2Min <= Precision::SquareConfusion())
2323 YaSol = Standard_True;
2324 aCurrentFind = Standard_True;
2327 U1 = (extr.Point(IndexMin)).Parameter();
2335 Geom2dInt_GInter Inter (AC1,AC2,TolConf,TolConf);
2337 if (!Inter.IsEmpty() && Inter.NbPoints() > 0) {
2338 YaSol = Standard_True;
2339 aCurrentFind = Standard_True;
2340 U1 = Inter.Point(1).ParamOnFirst();
2341 U2 = Inter.Point(1).ParamOnSecond();
2342 P2d = Inter.Point(1).Value();
2344 else if (!Inter.IsEmpty() && Inter.NbSegments() > 0) {
2345 YaSol = Standard_True;
2346 aCurrentFind = Standard_True;
2347 IntRes2d_IntersectionSegment Seg = Inter.Segment(1);
2348 IntRes2d_IntersectionPoint IntP1 = Seg.FirstPoint();
2349 IntRes2d_IntersectionPoint IntP2 = Seg.LastPoint();
2350 Standard_Real U1on1 = IntP1.ParamOnFirst();
2351 Standard_Real U1on2 = IntP2.ParamOnFirst();
2352 Standard_Real U2on1 = IntP1.ParamOnSecond();
2353 Standard_Real U2on2 = IntP2.ParamOnSecond();
2355 std::cout << " BRepOffset_Tool::Inter2d SEGMENT d intersection" << std::endl;
2356 std::cout << " ===> Parametres sur Curve1 : ";
2357 std::cout << U1on1 << " " << U1on2 << std::endl;
2358 std::cout << " ===> Parametres sur Curve2 : ";
2359 std::cout << U2on1 << " " << U2on2 << std::endl;
2361 U1 = (U1on1 + U1on2)/2.;
2362 U2 = (U2on1 + U2on2)/2.;
2363 gp_Pnt2d P2d1 = C1->Value(U1);
2364 gp_Pnt2d P2d2 = C2->Value(U2);
2365 P2d.SetX( (P2d1.X() + P2d2.X()) / 2.);
2366 P2d.SetY( (P2d1.Y() + P2d2.Y()) / 2.);
2370 gp_Pnt P = S->Value(P2d.X(),P2d.Y());
2371 TopoDS_Vertex V = BRepLib_MakeVertex(P);
2372 V.Orientation(TopAbs_INTERNAL);
2373 TopoDS_Shape aLocalEdgeOrientedE1 = E1.Oriented(TopAbs_FORWARD);
2374 B.UpdateVertex(V,U1,TopoDS::Edge(aLocalEdgeOrientedE1),TolConf);
2375 aLocalEdgeOrientedE1 = E2.Oriented(TopAbs_FORWARD);
2376 B.UpdateVertex(V,U2,TopoDS::Edge(aLocalEdgeOrientedE1),TolConf);
2377 // B.UpdateVertex(V,U1,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)),TolConf);
2378 // B.UpdateVertex(V,U2,TopoDS::Edge(E2.Oriented(TopAbs_FORWARD)),TolConf);
2386 if (LV.Extent() > 1) {
2387 //------------------------------------------------
2388 // garde seulement les vertex les plus proches du
2389 //debut et de la fin.
2390 //------------------------------------------------
2391 TopTools_ListIteratorOfListOfShape it(LV);
2392 TopoDS_Vertex VF,VL;
2393 Standard_Real UMin = Precision::Infinite();
2394 Standard_Real UMax = -Precision::Infinite();
2397 for ( ; it.More(); it.Next()) {
2398 TopoDS_Vertex CV = TopoDS::Vertex(it.Value());
2399 TopoDS_Shape aLocalEdge = E1.Oriented(TopAbs_FORWARD);
2400 U = BRep_Tool::Parameter(CV,TopoDS::Edge(aLocalEdge));
2401 // U = BRep_Tool::Parameter(CV,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)));
2409 LV.Clear();LV.Append(VF); LV.Append(VL);
2414 std::cout <<"Inter2d : Pas de solution"<<std::endl;
2416 DBRep::Set("E1",E1);
2417 DBRep::Set("E2",E2);
2424 //=======================================================================
2425 //function : SelectEdge
2427 //=======================================================================
2429 static void SelectEdge (const TopoDS_Face& /*F*/,
2430 const TopoDS_Face& /*EF*/,
2431 const TopoDS_Edge& E,
2432 TopTools_ListOfShape& LInt)
2434 //------------------------------------------------------------
2435 // detrompeur sur les intersections sur les faces periodiques
2436 //------------------------------------------------------------
2437 TopTools_ListIteratorOfListOfShape it(LInt);
2438 Standard_Real dU = 1.0e100;
2441 Standard_Real Fst, Lst, tmp;
2442 BRep_Tool::Range(E, Fst, Lst);
2443 BRepAdaptor_Curve Ad1(E);
2445 gp_Pnt PFirst = Ad1.Value( Fst );
2446 gp_Pnt PLast = Ad1.Value( Lst );
2448 //----------------------------------------------------------------------
2449 // Selection de l edge qui couvre le plus le domaine de l edge initiale.
2450 //----------------------------------------------------------------------
2451 for (; it.More(); it.Next()) {
2452 const TopoDS_Edge& EI = TopoDS::Edge(it.Value());
2454 BRep_Tool::Range(EI, Fst, Lst);
2455 BRepAdaptor_Curve Ad2(EI);
2456 gp_Pnt P1 = Ad2.Value(Fst);
2457 gp_Pnt P2 = Ad2.Value(Lst);
2459 tmp = P1.Distance(PFirst) + P2.Distance(PLast);
2471 //=======================================================================
2474 //=======================================================================
2476 static void MakeFace(const Handle(Geom_Surface)& S,
2477 const Standard_Real Um,
2478 const Standard_Real UM,
2479 const Standard_Real Vm,
2480 const Standard_Real VM,
2481 const Standard_Boolean uclosed,
2482 const Standard_Boolean vclosed,
2483 const Standard_Boolean isVminDegen,
2484 const Standard_Boolean isVmaxDegen,
2487 Standard_Real UMin = Um;
2488 Standard_Real UMax = UM;
2489 Standard_Real VMin = Vm;
2490 Standard_Real VMax = VM;
2492 // compute infinite flags
2493 Standard_Boolean umininf = Precision::IsNegativeInfinite(UMin);
2494 Standard_Boolean umaxinf = Precision::IsPositiveInfinite(UMax);
2495 Standard_Boolean vmininf = Precision::IsNegativeInfinite(VMin);
2496 Standard_Boolean vmaxinf = Precision::IsPositiveInfinite(VMax);
2498 // degenerated flags (for cones)
2499 Standard_Boolean vmindegen = isVminDegen, vmaxdegen = isVmaxDegen;
2500 Handle(Geom_Surface) theSurf = S;
2501 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
2502 theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
2503 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
2505 Handle(Geom_ConicalSurface) ConicalS = Handle(Geom_ConicalSurface)::DownCast (theSurf);
2506 gp_Cone theCone = ConicalS->Cone();
2507 gp_Pnt theApex = theCone.Apex();
2508 Standard_Real Uapex, Vapex;
2509 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
2510 if (Abs(VMin - Vapex) <= Precision::Confusion())
2511 vmindegen = Standard_True;
2512 if (Abs(VMax - Vapex) <= Precision::Confusion())
2513 vmaxdegen = Standard_True;
2518 Standard_Real tol = Precision::Confusion();
2520 TopoDS_Vertex V00,V10,V11,V01;
2523 if (!vmininf) B.MakeVertex(V00,S->Value(UMin,VMin),tol);
2524 if (!vmaxinf) B.MakeVertex(V01,S->Value(UMin,VMax),tol);
2527 if (!vmininf) B.MakeVertex(V10,S->Value(UMax,VMin),tol);
2528 if (!vmaxinf) B.MakeVertex(V11,S->Value(UMax,VMax),tol);
2547 Handle(Geom2d_Line) Lumin,Lumax,Lvmin,Lvmax;
2549 Lumin = new Geom2d_Line(gp_Pnt2d(UMin,0),gp_Dir2d(0,1));
2551 Lumax = new Geom2d_Line(gp_Pnt2d(UMax,0),gp_Dir2d(0,1));
2553 Lvmin = new Geom2d_Line(gp_Pnt2d(0,VMin),gp_Dir2d(1,0));
2555 Lvmax = new Geom2d_Line(gp_Pnt2d(0,VMax),gp_Dir2d(1,0));
2557 Handle(Geom_Curve) Cumin,Cumax,Cvmin,Cvmax;
2558 Standard_Real TolApex = 1.e-5;
2559 //Standard_Boolean hasiso = ! S->IsKind(STANDARD_TYPE(Geom_OffsetSurface));
2560 Standard_Boolean hasiso = S->IsKind(STANDARD_TYPE(Geom_ElementarySurface));
2563 Cumin = S->UIso(UMin);
2565 Cumax = S->UIso(UMax);
2568 Cvmin = S->VIso(VMin);
2569 if (BRepOffset_Tool::Gabarit( Cvmin ) <= TolApex)
2570 vmindegen = Standard_True;
2574 Cvmax = S->VIso(VMax);
2575 if (BRepOffset_Tool::Gabarit( Cvmax ) <= TolApex)
2576 vmaxdegen = Standard_True;
2581 B.MakeFace(F,S,tol);
2584 TopoDS_Edge eumin,eumax,evmin,evmax;
2588 B.MakeEdge(eumin,Cumin,tol);
2592 B.UpdateEdge(eumin,Lumax,Lumin,F,tol);
2594 B.UpdateEdge(eumin,Lumin,F,tol);
2596 V00.Orientation(TopAbs_FORWARD);
2600 V01.Orientation(TopAbs_REVERSED);
2603 B.Range(eumin,VMin,VMax);
2611 B.MakeEdge(eumax,Cumax,tol);
2614 B.UpdateEdge(eumax,Lumax,F,tol);
2616 V10.Orientation(TopAbs_FORWARD);
2620 V11.Orientation(TopAbs_REVERSED);
2623 B.Range(eumax,VMin,VMax);
2628 if (hasiso && !vmindegen)
2629 B.MakeEdge(evmin,Cvmin,tol);
2633 B.UpdateEdge(evmin,Lvmin,Lvmax,F,tol);
2635 B.UpdateEdge(evmin,Lvmin,F,tol);
2637 V00.Orientation(TopAbs_FORWARD);
2641 V10.Orientation(TopAbs_REVERSED);
2644 B.Range(evmin,UMin,UMax);
2646 B.Degenerated(evmin, Standard_True);
2653 if (hasiso && !vmaxdegen)
2654 B.MakeEdge(evmax,Cvmax,tol);
2657 B.UpdateEdge(evmax,Lvmax,F,tol);
2659 V01.Orientation(TopAbs_FORWARD);
2663 V11.Orientation(TopAbs_REVERSED);
2666 B.Range(evmax,UMin,UMax);
2668 B.Degenerated(evmax, Standard_True);
2672 // make the wires and add them to the face
2673 eumin.Orientation(TopAbs_REVERSED);
2674 evmax.Orientation(TopAbs_REVERSED);
2678 if (!umininf && !umaxinf && vmininf && vmaxinf) {
2689 else if (umininf && umaxinf && !vmininf && !vmaxinf) {
2700 else if (!umininf || !umaxinf || !vmininf || !vmaxinf) {
2703 if (!umininf) B.Add(W,eumin);
2704 if (!vmininf) B.Add(W,evmin);
2705 if (!umaxinf) B.Add(W,eumax);
2706 if (!vmaxinf) B.Add(W,evmax);
2708 W.Closed(!umininf && !umaxinf && !vmininf && !vmaxinf);
2709 F.Closed(uclosed && vclosed);
2713 //=======================================================================
2714 //function : EnLargeGeometry
2716 //=======================================================================
2718 static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S,
2723 Standard_Boolean& IsV1degen,
2724 Standard_Boolean& IsV2degen,
2725 const Standard_Real uf1,
2726 const Standard_Real uf2,
2727 const Standard_Real vf1,
2728 const Standard_Real vf2,
2729 const Standard_Real coeff,
2730 const Standard_Boolean theGlobalEnlargeU,
2731 const Standard_Boolean theGlobalEnlargeVfirst,
2732 const Standard_Boolean theGlobalEnlargeVlast,
2733 const Standard_Real theLenBeforeUfirst,
2734 const Standard_Real theLenAfterUlast,
2735 const Standard_Real theLenBeforeVfirst,
2736 const Standard_Real theLenAfterVlast)
2738 const Standard_Real TolApex = 1.e-5;
2740 Standard_Boolean SurfaceChange = Standard_False;
2741 if ( S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2742 Handle(Geom_Surface) BS = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
2743 EnlargeGeometry(BS,U1,U2,V1,V2,IsV1degen,IsV2degen,
2744 uf1,uf2,vf1,vf2,coeff,
2745 theGlobalEnlargeU, theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
2746 theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
2747 if (!theGlobalEnlargeVfirst)
2749 if (!theGlobalEnlargeVlast)
2751 if (!theGlobalEnlargeVfirst || !theGlobalEnlargeVlast)
2752 //Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->SetTrim( U1, U2, V1, V2 );
2753 S = new Geom_RectangularTrimmedSurface( BS, U1, U2, V1, V2 );
2756 SurfaceChange = Standard_True;
2758 else if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)) {
2759 Handle(Geom_Surface) Surf = Handle(Geom_OffsetSurface)::DownCast (S)->BasisSurface();
2760 SurfaceChange = EnlargeGeometry(Surf,U1,U2,V1,V2,IsV1degen,IsV2degen,
2761 uf1,uf2,vf1,vf2,coeff,
2762 theGlobalEnlargeU, theGlobalEnlargeVfirst, theGlobalEnlargeVlast,
2763 theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
2764 Handle(Geom_OffsetSurface)::DownCast(S)->SetBasisSurface(Surf);
2766 else if (S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
2767 S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution))
2769 Standard_Real du_first = 0., du_last = 0.,
2770 dv_first = 0., dv_last = 0.;
2771 Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
2772 Standard_Real u1, u2, v1, v2;
2773 Standard_Boolean enlargeU = theGlobalEnlargeU, enlargeV = Standard_True;
2774 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2775 Standard_Boolean enlargeVfirst = theGlobalEnlargeVfirst, enlargeVlast = theGlobalEnlargeVlast;
2776 S->Bounds( u1, u2, v1, v2 );
2777 if (Precision::IsInfinite(u1) || Precision::IsInfinite(u2))
2779 du_first = du_last = uf2-uf1;
2780 u1 = uf1 - du_first;
2782 enlargeU = Standard_False;
2784 else if (S->IsUClosed())
2785 enlargeU = Standard_False;
2788 viso = S->VIso( vf1 );
2789 GeomAdaptor_Curve gac( viso );
2790 Standard_Real du_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
2791 du_first = (theLenBeforeUfirst == -1)? du_default : theLenBeforeUfirst;
2792 du_last = (theLenAfterUlast == -1)? du_default : theLenAfterUlast;
2793 uiso1 = S->UIso( uf1 );
2794 uiso2 = S->UIso( uf2 );
2795 if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
2796 enlargeUfirst = Standard_False;
2797 if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
2798 enlargeUlast = Standard_False;
2800 if (Precision::IsInfinite(v1) || Precision::IsInfinite(v2))
2802 dv_first = dv_last = vf2-vf1;
2803 v1 = vf1 - dv_first;
2805 enlargeV = Standard_False;
2807 else if (S->IsVClosed())
2808 enlargeV = Standard_False;
2811 uiso = S->UIso( uf1 );
2812 GeomAdaptor_Curve gac( uiso );
2813 Standard_Real dv_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
2814 dv_first = (theLenBeforeVfirst == -1)? dv_default : theLenBeforeVfirst;
2815 dv_last = (theLenAfterVlast == -1)? dv_default : theLenAfterVlast;
2816 viso1 = S->VIso( vf1 );
2817 viso2 = S->VIso( vf2 );
2818 if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
2820 enlargeVfirst = Standard_False;
2821 IsV1degen = Standard_True;
2823 if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
2825 enlargeVlast = Standard_False;
2826 IsV2degen = Standard_True;
2829 Handle(Geom_BoundedSurface) aSurf = new Geom_RectangularTrimmedSurface( S, u1, u2, v1, v2 );
2832 if (enlargeUfirst && du_first != 0.)
2833 GeomLib::ExtendSurfByLength (aSurf, du_first, 1, Standard_True, Standard_False);
2834 if (enlargeUlast && du_last != 0.)
2835 GeomLib::ExtendSurfByLength (aSurf, du_last, 1, Standard_True, Standard_True);
2839 if (enlargeVfirst && dv_first != 0.)
2840 GeomLib::ExtendSurfByLength (aSurf, dv_first, 1, Standard_False, Standard_False);
2841 if (enlargeVlast && dv_last != 0.)
2842 GeomLib::ExtendSurfByLength (aSurf, dv_last, 1, Standard_False, Standard_True);
2845 S->Bounds( U1, U2, V1, V2 );
2846 SurfaceChange = Standard_True;
2848 else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
2849 S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
2851 Standard_Boolean enlargeU = theGlobalEnlargeU, enlargeV = Standard_True;
2852 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2853 Standard_Boolean enlargeVfirst = theGlobalEnlargeVfirst, enlargeVlast = theGlobalEnlargeVlast;
2855 enlargeU = Standard_False;
2857 enlargeV = Standard_False;
2859 Standard_Real duf = uf2-uf1, dvf = vf2-vf1;
2860 Standard_Real u1, u2, v1, v2;
2861 S->Bounds( u1, u2, v1, v2 );
2863 Standard_Real du_first = 0., du_last = 0.,
2864 dv_first = 0., dv_last = 0.;
2865 Handle( Geom_Curve ) uiso1, uiso2, viso1, viso2;
2866 Standard_Real gabarit_uiso1, gabarit_uiso2, gabarit_viso1, gabarit_viso2;
2868 uiso1 = S->UIso( u1 );
2869 uiso2 = S->UIso( u2 );
2870 viso1 = S->VIso( v1 );
2871 viso2 = S->VIso( v2 );
2872 gabarit_uiso1 = BRepOffset_Tool::Gabarit( uiso1 );
2873 gabarit_uiso2 = BRepOffset_Tool::Gabarit( uiso2 );
2874 gabarit_viso1 = BRepOffset_Tool::Gabarit( viso1 );
2875 gabarit_viso2 = BRepOffset_Tool::Gabarit( viso2 );
2876 if (gabarit_viso1 <= TolApex ||
2877 gabarit_viso2 <= TolApex)
2878 enlargeU = Standard_False;
2879 if (gabarit_uiso1 <= TolApex ||
2880 gabarit_uiso2 <= TolApex)
2881 enlargeV = Standard_False;
2883 GeomAdaptor_Curve gac;
2887 Standard_Real du_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
2888 du_first = (theLenBeforeUfirst == -1)? du_default : theLenBeforeUfirst;
2889 du_last = (theLenAfterUlast == -1)? du_default : theLenAfterUlast;
2890 if (gabarit_uiso1 <= TolApex)
2891 enlargeUfirst = Standard_False;
2892 if (gabarit_uiso2 <= TolApex)
2893 enlargeUlast = Standard_False;
2898 Standard_Real dv_default = GCPnts_AbscissaPoint::Length( gac ) * coeff;
2899 dv_first = (theLenBeforeVfirst == -1)? dv_default : theLenBeforeVfirst;
2900 dv_last = (theLenAfterVlast == -1)? dv_default : theLenAfterVlast;
2901 if (gabarit_viso1 <= TolApex)
2903 enlargeVfirst = Standard_False;
2904 IsV1degen = Standard_True;
2906 if (gabarit_viso2 <= TolApex)
2908 enlargeVlast = Standard_False;
2909 IsV2degen = Standard_True;
2913 Handle(Geom_BoundedSurface) aSurf = Handle(Geom_BoundedSurface)::DownCast (S);
2916 if (enlargeUfirst && uf1-u1 < duf && du_first != 0.)
2917 GeomLib::ExtendSurfByLength (aSurf, du_first, 1, Standard_True, Standard_False);
2918 if (enlargeUlast && u2-uf2 < duf && du_last != 0.)
2919 GeomLib::ExtendSurfByLength (aSurf, du_last, 1, Standard_True, Standard_True);
2923 if (enlargeVfirst && vf1-v1 < dvf && dv_first != 0.)
2924 GeomLib::ExtendSurfByLength (aSurf, dv_first, 1, Standard_False, Standard_False);
2925 if (enlargeVlast && v2-vf2 < dvf && dv_last != 0.)
2926 GeomLib::ExtendSurfByLength (aSurf, dv_last, 1, Standard_False, Standard_True);
2930 S->Bounds( U1, U2, V1, V2 );
2931 SurfaceChange = Standard_True;
2934 Standard_Real UU1,UU2,VV1,VV2;
2935 S->Bounds(UU1,UU2,VV1,VV2);
2936 // Pas d extension au dela des bornes de la surface.
2942 return SurfaceChange;
2945 //=======================================================================
2946 //function : UpDatePCurve
2947 //purpose : Mise a jour des pcurves de F sur la surface de de BF.
2948 // F and BF has to be FORWARD,
2949 //=======================================================================
2951 static void UpdatePCurves (const TopoDS_Face& F,
2957 TopTools_IndexedMapOfShape Emap;
2958 Handle(Geom2d_Curve) NullPCurve;
2960 TopExp::MapShapes( F, TopAbs_EDGE, Emap );
2962 for (i = 1; i <= Emap.Extent(); i++)
2964 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
2965 CE.Orientation( TopAbs_FORWARD );
2966 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface( CE, F, f, l );
2969 if (BRep_Tool::IsClosed( CE, F ))
2972 Handle(Geom2d_Curve) C2R = BRep_Tool::CurveOnSurface( CE, F, f, l );
2973 B.UpdateEdge( CE, NullPCurve, NullPCurve, F, BRep_Tool::Tolerance(CE) );
2974 B.UpdateEdge( CE, C2, C2R, BF, BRep_Tool::Tolerance(CE) );
2978 B.UpdateEdge( CE, NullPCurve, F, BRep_Tool::Tolerance(CE) );
2979 B.UpdateEdge( CE, C2, BF, BRep_Tool::Tolerance(CE) );
2987 //=======================================================================
2988 //function :CompactUVBounds
2990 //=======================================================================
2992 static void CompactUVBounds (const TopoDS_Face& F,
2993 Standard_Real& UMin,
2994 Standard_Real& UMax,
2995 Standard_Real& VMin,
2996 Standard_Real& VMax)
2998 // Calcul serre pour que les bornes ne couvrent pas plus d une periode
2999 Standard_Real U1,U2;
3000 Standard_Real N = 33;
3003 TopExp_Explorer exp;
3004 for (exp.Init(F, TopAbs_EDGE); exp.More(); exp.Next()) {
3005 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3006 BRepAdaptor_Curve2d C(E,F);
3007 BRep_Tool::Range(E,U1,U2);
3009 Standard_Real U = U1;
3010 Standard_Real DU = (U2-U1)/(N-1);
3011 for (Standard_Integer j=1;j<N;j++) {
3021 B.Get(UMin,VMin,UMax,VMax);
3023 BRep_Tool::Surface(F)->Bounds (UMin, UMax, VMin, VMax);
3026 //=======================================================================
3027 //function : CheckBounds
3029 //=======================================================================
3031 void BRepOffset_Tool::CheckBounds(const TopoDS_Face& F,
3032 const BRepOffset_Analyse& Analyse,
3033 Standard_Boolean& enlargeU,
3034 Standard_Boolean& enlargeVfirst,
3035 Standard_Boolean& enlargeVlast)
3037 enlargeU = Standard_True;
3038 enlargeVfirst = Standard_True; enlargeVlast = Standard_True;
3040 Standard_Integer Ubound = 0, Vbound = 0;
3041 Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
3042 Standard_Real Vfirst = RealLast(), Vlast = RealFirst();
3044 Standard_Real UF1,UF2,VF1,VF2;
3045 CompactUVBounds(F,UF1,UF2,VF1,VF2);
3047 Handle(Geom_Surface) theSurf = BRep_Tool::Surface(F);
3048 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
3049 theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (theSurf)->BasisSurface();
3051 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
3052 theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution) ||
3053 theSurf->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
3054 theSurf->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
3056 TopExp_Explorer Explo(F, TopAbs_EDGE);
3057 for (; Explo.More(); Explo.Next())
3059 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
3060 const BRepOffset_ListOfInterval& L = Analyse.Type(anEdge);
3061 if (!L.IsEmpty() || BRep_Tool::Degenerated(anEdge))
3063 ChFiDS_TypeOfConcavity OT = L.First().Type();
3064 if (OT == ChFiDS_Tangential || BRep_Tool::Degenerated(anEdge))
3066 Standard_Real fpar, lpar;
3067 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, F, fpar, lpar);
3068 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
3069 aCurve = Handle(Geom2d_TrimmedCurve)::DownCast (aCurve)->BasisCurve();
3071 Handle(Geom2d_Line) theLine;
3072 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_Line))
3073 theLine = Handle(Geom2d_Line)::DownCast (aCurve);
3074 else if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BezierCurve) ||
3075 aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BSplineCurve))
3077 Standard_Real newFpar, newLpar, deviation;
3078 theLine = ShapeCustom_Curve2d::ConvertToLine2d(aCurve, fpar, lpar, Precision::Confusion(),
3079 newFpar, newLpar, deviation);
3082 if (!theLine.IsNull())
3084 gp_Dir2d theDir = theLine->Direction();
3085 if (theDir.IsParallel( gp::DX2d(), Precision::Angular() ))
3088 if (BRep_Tool::Degenerated(anEdge))
3090 if (Abs(theLine->Location().Y() - VF1) <= Precision::Confusion())
3091 enlargeVfirst = Standard_False;
3092 else //theLine->Location().Y() is near VF2
3093 enlargeVlast = Standard_False;
3097 if (theLine->Location().Y() < Vfirst)
3098 Vfirst = theLine->Location().Y();
3099 if (theLine->Location().Y() > Vlast)
3100 Vlast = theLine->Location().Y();
3103 else if (theDir.IsParallel( gp::DY2d(), Precision::Angular() ))
3106 if (theLine->Location().X() < Ufirst)
3107 Ufirst = theLine->Location().X();
3108 if (theLine->Location().X() > Ulast)
3109 Ulast = theLine->Location().X();
3117 if (Ubound >= 2 || Vbound >= 2)
3120 Abs(UF1-Ufirst) <= Precision::Confusion() &&
3121 Abs(UF2-Ulast) <= Precision::Confusion())
3122 enlargeU = Standard_False;
3124 Abs(VF1-Vfirst) <= Precision::Confusion() &&
3125 Abs(VF2-Vlast) <= Precision::Confusion())
3127 enlargeVfirst = Standard_False;
3128 enlargeVlast = Standard_False;
3133 //=======================================================================
3134 //function : EnLargeFace
3136 //=======================================================================
3138 Standard_Boolean BRepOffset_Tool::EnLargeFace
3139 (const TopoDS_Face& F,
3141 const Standard_Boolean CanExtentSurface,
3142 const Standard_Boolean UpdatePCurve,
3143 const Standard_Boolean theEnlargeU,
3144 const Standard_Boolean theEnlargeVfirst,
3145 const Standard_Boolean theEnlargeVlast,
3146 const Standard_Integer theExtensionMode,
3147 const Standard_Real theLenBeforeUfirst,
3148 const Standard_Real theLenAfterUlast,
3149 const Standard_Real theLenBeforeVfirst,
3150 const Standard_Real theLenAfterVlast)
3152 //---------------------------
3153 // extension de la geometrie.
3154 //---------------------------
3156 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
3157 Standard_Real UU1,VV1,UU2,VV2;
3158 Standard_Boolean uperiodic = Standard_False, vperiodic = Standard_False;
3159 Standard_Boolean isVV1degen = Standard_False, isVV2degen = Standard_False;
3160 Standard_Real US1,VS1,US2,VS2;
3161 Standard_Real UF1,VF1,UF2,VF2;
3162 Standard_Boolean SurfaceChange = Standard_False;
3164 if (S->IsUPeriodic() || S->IsVPeriodic()) {
3165 // Calcul serre pour que les bornes ne couvre pas plus d une periode
3166 CompactUVBounds(F,UF1,UF2,VF1,VF2);
3169 BRepTools::UVBounds(F,UF1,UF2,VF1,VF2);
3172 S->Bounds (US1,US2,VS1,VS2);
3173 Standard_Real coeff;
3174 if (theExtensionMode == 1)
3176 UU1 = VV1 = - TheInfini;
3177 UU2 = VV2 = TheInfini;
3182 Standard_Real FaceDU = UF2 - UF1;
3183 Standard_Real FaceDV = VF2 - VF1;
3184 UU1 = UF1 - 10*FaceDU;
3185 UU2 = UF2 + 10*FaceDU;
3186 VV1 = VF1 - 10*FaceDV;
3187 VV2 = VF2 + 10*FaceDV;
3191 if (CanExtentSurface) {
3192 SurfaceChange = EnlargeGeometry(S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2, coeff,
3193 theEnlargeU, theEnlargeVfirst, theEnlargeVlast,
3194 theLenBeforeUfirst, theLenAfterUlast, theLenBeforeVfirst, theLenAfterVlast);
3197 UU1 = Max(US1,UU1); UU2 = Min(UU2,US2);
3198 VV1 = Max(VS1,VV1); VV2 = Min(VS2,VV2);
3201 if (S->IsUPeriodic()) {
3202 uperiodic = Standard_True;
3203 Standard_Real Period = S->UPeriod();
3204 Standard_Real Delta = Period - (UF2 - UF1);
3205 Standard_Real alpha = 0.1;
3206 UU1 = UF1 - alpha*Delta; UU2 = UF2 + alpha*Delta;
3207 if ((UU2 - UU1) > Period) {
3211 if (S->IsVPeriodic()) {
3212 vperiodic = Standard_True;
3213 Standard_Real Period = S->VPeriod();
3214 Standard_Real Delta = Period - (VF2 - VF1);
3215 Standard_Real alpha = 0.1;
3216 VV1 = VF1 - alpha*Delta; VV2 = VF2 + alpha*Delta;
3217 if ((VV2 - VV1) > Period) {
3222 //Special treatment for conical surfaces
3223 Handle(Geom_Surface) theSurf = S;
3224 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
3225 theSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast (S)->BasisSurface();
3226 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
3228 Handle(Geom_ConicalSurface) ConicalS = Handle(Geom_ConicalSurface)::DownCast (theSurf);
3229 gp_Cone theCone = ConicalS->Cone();
3230 gp_Pnt theApex = theCone.Apex();
3231 Standard_Real Uapex, Vapex;
3232 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
3233 if (VV1 < Vapex && Vapex < VV2)
3235 //consider that VF1 and VF2 are on the same side from apex
3236 Standard_Real TolApex = 1.e-5;
3237 if (Vapex - VF1 >= TolApex ||
3238 Vapex - VF2 >= TolApex) //if (VF1 < Vapex || VF2 < Vapex)
3247 UU1 = UF1; UU2 = UF2;
3249 if (!theEnlargeVfirst)
3251 if (!theEnlargeVlast)
3254 //Detect closedness in U and V directions
3255 Standard_Boolean uclosed = Standard_False, vclosed = Standard_False;
3256 BRepTools::DetectClosedness(F, uclosed, vclosed);
3257 if (uclosed && !uperiodic &&
3258 (theLenBeforeUfirst != 0. || theLenAfterUlast != 0.))
3259 uclosed = Standard_False;
3260 if (vclosed && !vperiodic &&
3261 (theLenBeforeVfirst != 0. && theLenAfterVlast != 0.))
3262 vclosed = Standard_False;
3264 MakeFace(S,UU1,UU2,VV1,VV2,uclosed,vclosed,isVV1degen,isVV2degen,BF);
3267 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
3269 //----------------------------------------------------------------
3270 // utile pour les bouchons on ne doit pas changer leur geometrie.
3271 // (Ce que fait BRepLib_MakeFace si S est restreinte).
3272 // On remet S et on update les pcurves.
3273 //----------------------------------------------------------------
3274 TopExp_Explorer exp;
3275 exp.Init(BF,TopAbs_EDGE);
3276 Standard_Real f=0.,l=0.;
3277 for (; exp.More(); exp.Next()) {
3278 TopoDS_Edge CE = TopoDS::Edge(exp.Current());
3279 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,BF,f,l);
3280 B.UpdateEdge (CE,C2,S,L,BRep_Tool::Tolerance(CE));
3282 B.UpdateFace(BF,S,L,BRep_Tool::Tolerance(F));
3285 if (SurfaceChange && UpdatePCurve) {
3286 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3287 UpdatePCurves(TopoDS::Face(aLocalFace),BF);
3288 //UpdatePCurves(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),BF);
3290 BB.UpdateFace( F, S, L, BRep_Tool::Tolerance(F) );
3293 BF.Orientation(F.Orientation());
3294 return SurfaceChange;
3297 //=======================================================================
3298 //function : TryParameter
3300 //=======================================================================
3302 static Standard_Boolean TryParameter (const TopoDS_Edge& OE,
3304 const TopoDS_Edge& NE,
3305 Standard_Real TolConf)
3307 BRepAdaptor_Curve OC(OE);
3308 BRepAdaptor_Curve NC(NE);
3309 Standard_Real Of = OC.FirstParameter(); Standard_Real Ol = OC.LastParameter();
3310 Standard_Real Nf = NC.FirstParameter(); Standard_Real Nl = NC.LastParameter();
3311 Standard_Real U = 0.;
3312 gp_Pnt P = BRep_Tool::Pnt(V);
3313 Standard_Boolean OK = Standard_False;
3315 if (P.Distance(OC.Value(Of)) < TolConf) {
3316 if (Of > Nf && Of < Nl && P.Distance(NC.Value(Of)) < TolConf) {
3321 if (P.Distance(OC.Value(Ol)) < TolConf) {
3322 if (Ol > Nf && Ol < Nl && P.Distance(NC.Value(Ol)) < TolConf) {
3329 TopoDS_Shape aLocalShape = NE.Oriented(TopAbs_FORWARD);
3330 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
3331 // TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD));
3332 aLocalShape = V.Oriented(TopAbs_INTERNAL);
3333 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
3334 U,NE,BRep_Tool::Tolerance(NE));
3335 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
3336 // U,NE,BRep_Tool::Tolerance(NE));
3341 //=======================================================================
3344 //=======================================================================
3346 void BRepOffset_Tool::MapVertexEdges (const TopoDS_Shape& S,
3347 TopTools_DataMapOfShapeListOfShape& MEV)
3349 TopExp_Explorer exp;
3350 exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3351 TopTools_MapOfShape DejaVu;
3352 for ( ; exp.More(); exp.Next()) {
3353 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3354 if (DejaVu.Add(E)) {
3355 TopoDS_Vertex V1,V2;
3356 TopExp::Vertices (E,V1,V2);
3357 if (!MEV.IsBound(V1)) {
3358 TopTools_ListOfShape empty;
3362 if (!V1.IsSame(V2)) {
3363 if (!MEV.IsBound(V2)) {
3364 TopTools_ListOfShape empty;
3373 //=======================================================================
3376 //=======================================================================
3378 void BRepOffset_Tool::BuildNeighbour (const TopoDS_Wire& W,
3379 const TopoDS_Face& F,
3380 TopTools_DataMapOfShapeShape& NOnV1,
3381 TopTools_DataMapOfShapeShape& NOnV2)
3383 TopoDS_Vertex V1,V2,VP1,VP2,FV1,FV2;
3384 TopoDS_Edge CurE,FirstE,PrecE;
3385 BRepTools_WireExplorer wexp;
3387 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3388 TopoDS_Shape aLocalWire = W.Oriented(TopAbs_FORWARD);
3389 wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
3390 // wexp.Init(TopoDS::Wire(W.Oriented(TopAbs_FORWARD)),
3391 // TopoDS::Face(F.Oriented(TopAbs_FORWARD)));
3392 CurE = FirstE = PrecE = wexp.Current();
3393 TopExp::Vertices(CurE,V1,V2);
3394 FV1 = VP1 = V1; FV2 = VP2 = V2;
3396 while (wexp.More()) {
3397 CurE = wexp.Current();
3398 TopExp::Vertices(CurE,V1,V2);
3399 if (V1.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3400 if (V1.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3401 if (V2.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3402 if (V2.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3407 if (V1.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3408 if (V1.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3409 if (V2.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3410 if (V2.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3413 //=======================================================================
3414 //function : ExtentFace
3416 //=======================================================================
3418 void BRepOffset_Tool::ExtentFace (const TopoDS_Face& F,
3419 TopTools_DataMapOfShapeShape& ConstShapes,
3420 TopTools_DataMapOfShapeShape& ToBuild,
3421 const TopAbs_State Side,
3422 const Standard_Real TolConf,
3428 sprintf(name,"FTE_%d",NbFTE++);
3433 TopExp_Explorer exp,exp2;
3434 TopTools_DataMapOfShapeShape Build;
3435 TopTools_DataMapOfShapeShape Extent;
3436 TopoDS_Edge FirstE,PrecE,CurE,NE;
3440 // Construction de la boite englobante de la face a etendre et des bouchons pour
3441 // limiter les extensions.
3442 //Bnd_Box ContextBox;
3443 //BRepBndLib::Add(F,B);
3444 //TopTools_DataMapIteratorOfDataMapOfShape itTB(ToBuild);
3445 //for (; itTB.More(); itTB.Next()) {
3446 //BRepBndLib::Add(TopBuild.Value(), ContextBox);
3450 Standard_Boolean SurfaceChange;
3451 SurfaceChange = EnLargeFace (F,EF,Standard_True);
3453 TopoDS_Shape aLocalShape = EF.EmptyCopied();
3454 NF = TopoDS::Face(aLocalShape);
3455 // NF = TopoDS::Face(EF.EmptyCopied());
3456 NF.Orientation(TopAbs_FORWARD);
3458 if (SurfaceChange) {
3459 //------------------------------------------------
3460 // Mise a jour des pcurves sur la surface de base.
3461 //------------------------------------------------
3462 TopoDS_Face Fforward = F;
3463 Fforward.Orientation(TopAbs_FORWARD);
3464 TopTools_IndexedMapOfShape Emap;
3465 TopExp::MapShapes( Fforward, TopAbs_EDGE, Emap );
3467 for (Standard_Integer i = 1; i <= Emap.Extent(); i++) {
3468 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
3469 CE.Orientation(TopAbs_FORWARD);
3470 TopoDS_Edge Ecs; //patch
3471 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,Fforward,f,l);
3473 if (ConstShapes.IsBound(CE)) {
3474 Ecs = TopoDS::Edge(ConstShapes(CE));
3475 BRep_Tool::Range(Ecs,f,l);
3477 if (BRep_Tool::IsClosed(CE,Fforward)) {
3478 TopoDS_Shape aLocalShapeReversedCE = CE.Reversed();
3479 Handle(Geom2d_Curve) C2R =
3480 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShapeReversedCE),Fforward,f,l);
3481 // Handle(Geom2d_Curve) C2R =
3482 // BRep_Tool::CurveOnSurface(TopoDS::Edge(CE.Reversed()),F,f,l);
3483 B.UpdateEdge (CE,C2,C2R,EF,BRep_Tool::Tolerance(CE));
3485 B.UpdateEdge (Ecs,C2,C2R,EF,BRep_Tool::Tolerance(CE));
3488 B.UpdateEdge (CE,C2,EF,BRep_Tool::Tolerance(CE));
3490 B.UpdateEdge (Ecs,C2,EF,BRep_Tool::Tolerance(CE));
3499 for (exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
3502 const TopoDS_Wire& W = TopoDS::Wire(exp.Current());
3503 TopTools_DataMapOfShapeListOfShape MVE; // Vertex -> Edges incidentes.
3504 TopTools_DataMapOfShapeShape NOnV1;
3505 TopTools_DataMapOfShapeShape NOnV2;
3507 MapVertexEdges (W,MVE);
3508 BuildNeighbour (W,F,NOnV1,NOnV2);
3510 TopTools_ListOfShape LInt1,LInt2;
3511 TopoDS_Face StopFace;
3512 //------------------------------------------------
3513 // Construction edges
3514 //------------------------------------------------
3515 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3516 exp2.More(); exp2.Next()) {
3517 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3518 if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
3519 if (ToBuild.IsBound(E)) {
3520 TopTools_ListOfShape LOE;
3522 BRepOffset_Tool::TryProject (TopoDS::Face(ToBuild(E)),
3523 EF,LOE,LInt2,LInt1,Side,TolConf);
3524 if (!LInt1.IsEmpty())
3529 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3530 exp2.More(); exp2.Next()) {
3531 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3532 if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
3533 if (ToBuild.IsBound(E)) {
3534 EnLargeFace(TopoDS::Face(ToBuild(E)),StopFace,Standard_False);
3535 TopoDS_Face NullFace;
3536 BRepOffset_Tool::Inter3D (EF,StopFace,LInt1,LInt2,Side,E,NullFace,NullFace);
3537 // No intersection, it may happen for example for a chosen (non-offsetted) planar face and
3538 // its neighbour offseted cylindrical face, if the offset is directed so that
3539 // the radius of the cylinder becomes smaller.
3540 if (LInt1.IsEmpty())
3542 if (LInt1.Extent() > 1) {
3543 // l intersection est en plusieurs edges (franchissement de couture)
3544 SelectEdge (F,EF,E,LInt1);
3546 NE = TopoDS::Edge(LInt1.First());
3547 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &NE.TShape());
3548 TE->Tolerance( TE->Tolerance()*10. ); //????
3549 if (NE.Orientation() == E.Orientation()) {
3550 Build.Bind(E,NE.Oriented(TopAbs_FORWARD));
3553 Build.Bind(E,NE.Oriented(TopAbs_REVERSED));
3555 const TopoDS_Edge& EOnV1 = TopoDS::Edge(NOnV1(E));
3556 if (!ToBuild .IsBound(EOnV1) &&
3557 !ConstShapes.IsBound(EOnV1) &&
3558 !Build .IsBound(EOnV1)) {
3559 ExtentEdge (F,EF,EOnV1,NE);
3560 Build.Bind (EOnV1,NE.Oriented(TopAbs_FORWARD));
3562 const TopoDS_Edge& EOnV2 = TopoDS::Edge(NOnV2(E));
3563 if (!ToBuild .IsBound(EOnV2) &&
3564 !ConstShapes.IsBound(EOnV2) &&
3565 !Build .IsBound(EOnV2)) {
3566 ExtentEdge (F,EF,EOnV2,NE);
3567 Build.Bind (EOnV2,NE.Oriented (TopAbs_FORWARD));
3572 //------------------------------------------------
3573 // Construction Vertex.
3574 //------------------------------------------------
3575 TopTools_ListOfShape LV;
3578 TopoDS_Vertex V1,V2;
3580 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE); exp2.More(); exp2.Next())
3582 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3583 TopExp::Vertices (E,V1,V2);
3584 BRep_Tool::Range (E,f,l);
3586 if (Build.IsBound(E))
3588 const TopoDS_Edge& NEOnV1 = TopoDS::Edge(NOnV1(E));
3589 if (Build.IsBound(NEOnV1) && (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV1)))
3591 if (E.IsSame(NEOnV1))
3592 V = TopExp::FirstVertex(TopoDS::Edge(Build(E)));
3598 if (!Build.IsBound(V1))
3600 Inter2d (EF,TopoDS::Edge(Build(E)), TopoDS::Edge(Build(NEOnV1)),LV,/*TolConf*/Precision::Confusion());
3604 if (Build(E).Orientation() == TopAbs_FORWARD)
3606 V = TopoDS::Vertex(LV.First());
3610 V = TopoDS::Vertex(LV.Last());
3620 V = TopoDS::Vertex(Build(V1));
3621 if (MVE (V1).Extent() > 2)
3623 V.Orientation(TopAbs_FORWARD);
3624 if (Build(E).Orientation() == TopAbs_REVERSED)
3625 V.Orientation(TopAbs_REVERSED);
3627 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3638 if (ConstShapes.IsBound(V1)) V = TopoDS::Vertex(ConstShapes(V1));
3639 V.Orientation(TopAbs_FORWARD);
3640 if (Build(E).Orientation() == TopAbs_REVERSED)
3641 V.Orientation(TopAbs_REVERSED);
3642 if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
3643 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3646 ConstShapes.Bind(V1,V);
3648 const TopoDS_Edge& NEOnV2 = TopoDS::Edge(NOnV2(E));
3649 if (Build.IsBound(NEOnV2) && (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV2)))
3651 if (E.IsSame(NEOnV2))
3652 V = TopExp::LastVertex(TopoDS::Edge(Build(E)));
3659 if (!Build.IsBound(V2))
3661 Inter2d (EF,TopoDS::Edge(Build(E)), TopoDS::Edge(Build(NEOnV2)),LV,/*TolConf*/Precision::Confusion());
3665 if (Build(E).Orientation() == TopAbs_FORWARD)
3667 V = TopoDS::Vertex(LV.Last());
3671 V = TopoDS::Vertex(LV.First());
3681 V = TopoDS::Vertex(Build(V2));
3682 if (MVE (V2).Extent() > 2)
3684 V.Orientation(TopAbs_REVERSED);
3685 if (Build(E).Orientation() == TopAbs_REVERSED)
3686 V.Orientation(TopAbs_FORWARD);
3688 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3699 if (ConstShapes.IsBound(V2))
3700 V = TopoDS::Vertex(ConstShapes(V2));
3701 V.Orientation(TopAbs_REVERSED);
3702 if (Build(E).Orientation() == TopAbs_REVERSED)
3703 V.Orientation(TopAbs_FORWARD);
3704 if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
3705 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3707 ConstShapes.Bind(V2,V);
3713 TopoDS_Vertex NV1,NV2;
3714 TopAbs_Orientation Or;
3715 Standard_Real U1,U2;
3716 Standard_Real eps = Precision::Confusion();
3726 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3727 exp2.More(); exp2.Next()) {
3728 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3729 TopExp::Vertices (E,V1,V2);
3730 if (Build.IsBound(E)) {
3731 NE = TopoDS::Edge(Build(E));
3732 BRep_Tool::Range(NE,f,l);
3733 Or = NE.Orientation();
3734 //-----------------------------------------------------
3735 // Copy pour virer les vertex deja sur la nouvelle edge.
3736 //-----------------------------------------------------
3737 NV1 = TopoDS::Vertex(ConstShapes(V1));
3738 NV2 = TopoDS::Vertex(ConstShapes(V2));
3740 TopoDS_Shape aLocalVertexOrientedNV1 = NV1.Oriented(TopAbs_INTERNAL);
3741 TopoDS_Shape aLocalEdge = NE.Oriented(TopAbs_INTERNAL);
3743 U1 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalVertexOrientedNV1),
3744 TopoDS::Edge (aLocalEdge));
3745 aLocalVertexOrientedNV1 = NV2.Oriented(TopAbs_INTERNAL);
3746 aLocalEdge = NE.Oriented(TopAbs_FORWARD);
3747 U2 = BRep_Tool::Parameter (TopoDS::Vertex(aLocalVertexOrientedNV1),TopoDS::Edge (aLocalEdge));
3748 // U1 = BRep_Tool::Parameter
3749 // (TopoDS::Vertex(NV1.Oriented(TopAbs_INTERNAL)),
3750 // TopoDS::Edge (NE .Oriented(TopAbs_FORWARD)));
3751 // U2 = BRep_Tool::Parameter
3752 // (TopoDS::Vertex(NV2.Oriented(TopAbs_INTERNAL)),
3753 // TopoDS::Edge (NE.Oriented(TopAbs_FORWARD)));
3754 aLocalEdge = NE.EmptyCopied();
3755 NE = TopoDS::Edge(aLocalEdge);
3756 NE.Orientation(TopAbs_FORWARD);
3757 if (NV1.IsSame(NV2))
3762 if (Or == TopAbs_FORWARD) {U1 = f; U2 = l;}
3763 else {U1 = l; U2 = f;}
3764 if (Or == TopAbs_FORWARD)
3768 if (Abs(U1-l) < eps) U1 = f;
3769 if (Abs(U2-f) < eps) U2 = l;
3771 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3772 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3773 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3774 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3775 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3776 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3778 ConstShapes.Bind(E,NE);
3779 NE.Orientation(E.Orientation());
3785 if (Abs(U2-l) < eps) U2 = f;
3786 if (Abs(U1-f) < eps) U1 = l;
3788 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3789 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3790 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3791 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3792 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3793 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3795 ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
3796 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3801 //-------------------
3802 // edge is not ferme.
3803 //-------------------
3804 if (Or == TopAbs_FORWARD) {
3806 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3807 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3808 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3809 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3810 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3811 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3816 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3817 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3818 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3819 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3820 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3821 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3824 ConstShapes.Bind(E,NE);
3825 NE.Orientation(E.Orientation());
3829 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3830 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3831 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3832 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3833 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3834 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3836 ConstShapes.Bind(E,NE);
3837 NE.Orientation(E.Orientation());
3841 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3842 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3843 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3844 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3845 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3846 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3848 ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
3849 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3854 } // Build.IsBound(E)
3855 else if (ConstShapes.IsBound(E)) { // !Build.IsBound(E)
3856 NE = TopoDS::Edge(ConstShapes(E));
3857 BuildPCurves(NE,NF);
3858 Or = NE.Orientation();
3859 if (Or == TopAbs_REVERSED) {
3860 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3863 NE.Orientation(E.Orientation());
3868 ConstShapes.Bind(E,NE.Oriented(TopAbs_FORWARD));
3872 B.Add(NF,NW.Oriented(W.Orientation()));
3874 NF.Orientation(F.Orientation());
3875 BRepTools::Update(NF); // Maj des UVPoints
3880 sprintf(name,"FOB_%d",NbFOB++);
3881 DBRep::Set(name,NF);
3887 //=======================================================================
3888 //function : Deboucle3D
3890 //=======================================================================
3891 TopoDS_Shape BRepOffset_Tool::Deboucle3D(const TopoDS_Shape& S,
3892 const TopTools_MapOfShape& Boundary)
3895 switch (S.ShapeType())
3899 // if the shell contains free borders that do not belong to the
3900 // free borders of caps ( Boundary) it is removed.
3901 TopTools_IndexedDataMapOfShapeListOfShape Map;
3902 TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, Map);
3904 Standard_Boolean JeGarde = Standard_True;
3905 for (Standard_Integer i = 1; i <= Map.Extent() && JeGarde; i++) {
3906 const TopTools_ListOfShape& aLF = Map(i);
3907 if (aLF.Extent() < 2) {
3908 const TopoDS_Edge& anEdge = TopoDS::Edge(Map.FindKey(i));
3909 if (anEdge.Orientation() == TopAbs_INTERNAL) {
3910 const TopoDS_Face& aFace = TopoDS::Face(aLF.First());
3911 if (aFace.Orientation() != TopAbs_INTERNAL) {
3915 if (!Boundary.Contains(anEdge) &&
3916 !BRep_Tool::Degenerated(anEdge))
3917 JeGarde = Standard_False;
3920 if (JeGarde) SS = S;
3924 case TopAbs_COMPOUND:
3927 // iterate on sub-shapes and add non-empty.
3928 TopoDS_Iterator it(S);
3929 TopoDS_Shape SubShape;
3930 Standard_Integer NbSub = 0;
3932 if (S.ShapeType() == TopAbs_COMPOUND) {
3933 B.MakeCompound(TopoDS::Compound(SS));
3936 B.MakeSolid(TopoDS::Solid(SS));
3938 for (; it.More(); it.Next()) {
3939 const TopoDS_Shape& CurS = it.Value();
3940 SubShape = Deboucle3D(CurS, Boundary);
3941 if (!SubShape.IsNull()) {
3942 B.Add(SS, SubShape);
3948 SS = TopoDS_Shape();
3960 //=======================================================================
3961 //function : IsInOut
3963 //=======================================================================
3965 static Standard_Boolean IsInOut (BRepTopAdaptor_FClass2d& FC,
3966 Geom2dAdaptor_Curve AC,
3967 const TopAbs_State& S )
3969 Standard_Real Def = 100*Precision::Confusion();
3970 GCPnts_QuasiUniformDeflection QU(AC,Def);
3972 for (Standard_Integer i = 1; i <= QU.NbPoints(); i++) {
3973 gp_Pnt2d P = AC.Value(QU.Parameter(i));
3974 if (FC.Perform(P) != S) {
3975 return Standard_False;
3978 return Standard_True;
3981 //=======================================================================
3982 //function : CorrectOrientation
3984 //=======================================================================
3986 void BRepOffset_Tool::CorrectOrientation(const TopoDS_Shape& SI,
3987 const TopTools_IndexedMapOfShape& NewEdges,
3988 Handle(BRepAlgo_AsDes)& AsDes,
3989 BRepAlgo_Image& InitOffset,
3990 const Standard_Real Offset)
3993 TopExp_Explorer exp;
3994 exp.Init(SI,TopAbs_FACE);
3995 Standard_Real f=0.,l=0.;
3997 for (; exp.More(); exp.Next()) {
3999 const TopoDS_Face& FI = TopoDS::Face(exp.Current());
4000 const TopTools_ListOfShape& LOF = InitOffset.Image(FI);
4001 TopTools_ListIteratorOfListOfShape it(LOF);
4002 for (; it.More(); it.Next()) {
4003 const TopoDS_Face& OF = TopoDS::Face(it.Value());
4004 TopTools_ListOfShape& LOE = AsDes->ChangeDescendant(OF);
4005 TopTools_ListIteratorOfListOfShape itE(LOE);
4007 Standard_Boolean YaInt = Standard_False;
4008 for (; itE.More(); itE.Next()) {
4009 const TopoDS_Edge& OE = TopoDS::Edge(itE.Value());
4010 if (NewEdges.Contains(OE)) {YaInt = Standard_True; break;}
4013 TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
4014 BRepTopAdaptor_FClass2d FC (TopoDS::Face(aLocalFace),
4015 Precision::Confusion());
4016 // BRepTopAdaptor_FClass2d FC (TopoDS::Face(FI.Oriented(TopAbs_FORWARD)),
4017 // Precision::Confusion());
4018 for (itE.Initialize(LOE); itE.More(); itE.Next()) {
4019 TopoDS_Shape& OE = itE.Value();
4020 if (NewEdges.Contains(OE)) {
4021 Handle(Geom2d_Curve) CO2d =
4022 BRep_Tool::CurveOnSurface(TopoDS::Edge(OE),OF,f,l);
4023 Geom2dAdaptor_Curve AC(CO2d,f,l);
4026 if (IsInOut(FC,AC,TopAbs_OUT)) OE.Reverse();
4029 // if (IsInOut(FC,AC,TopAbs_IN)) OE.Reverse();
4039 //=======================================================================
4040 //function : CheckNormals
4042 //=======================================================================
4043 Standard_Boolean BRepOffset_Tool::CheckPlanesNormals(const TopoDS_Face& theFace1,
4044 const TopoDS_Face& theFace2,
4045 const Standard_Real theTolAng)
4047 BRepAdaptor_Surface aBAS1(theFace1, Standard_False), aBAS2(theFace2, Standard_False);
4048 if (aBAS1.GetType() != GeomAbs_Plane ||
4049 aBAS2.GetType() != GeomAbs_Plane) {
4050 return Standard_False;
4053 gp_Dir aDN1 = aBAS1.Plane().Position().Direction();
4054 if (theFace1.Orientation() == TopAbs_REVERSED) {
4058 gp_Dir aDN2 = aBAS2.Plane().Position().Direction();
4059 if (theFace2.Orientation() == TopAbs_REVERSED) {
4063 Standard_Real anAngle = aDN1.Angle(aDN2);
4064 return (anAngle < theTolAng);
4067 //=======================================================================
4068 //function : PerformPlanes
4070 //=======================================================================
4071 void PerformPlanes(const TopoDS_Face& theFace1,
4072 const TopoDS_Face& theFace2,
4073 const TopAbs_State theSide,
4074 TopTools_ListOfShape& theL1,
4075 TopTools_ListOfShape& theL2)
4079 // Intersect the planes using IntTools_FaceFace directly
4080 IntTools_FaceFace aFF;
4081 aFF.SetParameters(Standard_True, Standard_True, Standard_True, Precision::Confusion());
4082 aFF.Perform(theFace1, theFace2);
4084 if (!aFF.IsDone()) {
4088 const IntTools_SequenceOfCurves& aSC = aFF.Lines();
4089 if (aSC.IsEmpty()) {
4093 // In Plane/Plane intersection only one curve is always produced.
4094 // Make the edge from this section curve.
4098 const IntTools_Curve& aIC = aSC(1);
4099 const Handle(Geom_Curve)& aC3D = aIC.Curve();
4100 aBB.MakeEdge(aE, aC3D, aIC.Tolerance());
4101 // Get bounds of the curve
4102 Standard_Real aTF, aTL;
4104 aIC.Bounds(aTF, aTL, aPF, aPL);
4105 // Make the bounding vertices
4106 TopoDS_Vertex aVF, aVL;
4107 aBB.MakeVertex(aVF, aPF, aIC.Tolerance());
4108 aBB.MakeVertex(aVL, aPL, aIC.Tolerance());
4109 aVL.Orientation(TopAbs_REVERSED);
4110 // Add vertices to the edge
4113 // Add 2D curves to the edge
4114 aBB.UpdateEdge(aE, aIC.FirstCurve2d(), theFace1, aIC.Tolerance());
4115 aBB.UpdateEdge(aE, aIC.SecondCurve2d(), theFace2, aIC.Tolerance());
4116 // Update range of the new edge
4117 aBB.Range(aE, aTF, aTL);
4121 TopAbs_Orientation O1, O2;
4122 BRepOffset_Tool::OrientSection(aE, theFace1, theFace2, O1, O2);
4123 if (theSide == TopAbs_OUT) {
4124 O1 = TopAbs::Reverse(O1);
4125 O2 = TopAbs::Reverse(O2);
4128 BRepLib::SameParameter(aE, Precision::Confusion(), Standard_True);
4130 // Add edge to result
4131 theL1.Append(aE.Oriented(O1));
4132 theL2.Append(aE.Oriented(O2));
4135 //=======================================================================
4137 //purpose : Checks if the given value is close to infinite (TheInfini)
4138 //=======================================================================
4139 Standard_Boolean IsInf(const Standard_Real theVal)
4141 return (theVal > TheInfini*0.9);
4144 static void UpdateVertexTolerances(const TopoDS_Face& theFace)
4147 TopTools_IndexedDataMapOfShapeListOfShape VEmap;
4148 TopExp::MapShapesAndAncestors(theFace, TopAbs_VERTEX, TopAbs_EDGE, VEmap);
4150 for (Standard_Integer i = 1; i <= VEmap.Extent(); i++)
4152 const TopoDS_Vertex& aVertex = TopoDS::Vertex(VEmap.FindKey(i));
4153 const TopTools_ListOfShape& Elist = VEmap(i);
4154 gp_Pnt PntVtx = BRep_Tool::Pnt(aVertex);
4155 TopTools_ListIteratorOfListOfShape itl(Elist);
4156 for (; itl.More(); itl.Next())
4158 const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value());
4159 TopoDS_Vertex V1, V2;
4160 TopExp::Vertices(anEdge, V1, V2);
4161 Standard_Real fpar, lpar;
4162 BRep_Tool::Range(anEdge, fpar, lpar);
4163 Standard_Real aParam = (V1.IsSame(aVertex))? fpar : lpar;
4164 if (!BRep_Tool::Degenerated(anEdge))
4166 BRepAdaptor_Curve BAcurve(anEdge);
4167 gp_Pnt aPnt = BAcurve.Value(aParam);
4168 Standard_Real aDist = PntVtx.Distance(aPnt);
4169 BB.UpdateVertex(aVertex, aDist);
4172 aPnt = BAcurve.Value(lpar);
4173 aDist = PntVtx.Distance(aPnt);
4174 BB.UpdateVertex(aVertex, aDist);
4177 BRepAdaptor_Curve BAcurveonsurf(anEdge, theFace);
4178 gp_Pnt aPnt = BAcurveonsurf.Value(aParam);
4179 Standard_Real aDist = PntVtx.Distance(aPnt);
4180 BB.UpdateVertex(aVertex, aDist);
4183 aPnt = BAcurveonsurf.Value(lpar);
4184 aDist = PntVtx.Distance(aPnt);
4185 BB.UpdateVertex(aVertex, aDist);