1 // Created on: 1995-10-23
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
24 #include <BRepOffset_Tool.ixx>
26 #include <BRepAlgo_Tool.hxx>
28 #include <BRepAdaptor_Curve.hxx>
29 #include <BRepAdaptor_Surface.hxx>
30 #include <BRepAdaptor_HCurve.hxx>
31 #include <BRepAdaptor_HSurface.hxx>
33 #include <BRepBndLib.hxx>
35 #include <Bnd_Box2d.hxx>
36 #include <BndLib_Add3dCurve.hxx>
37 #include <BRep_Tool.hxx>
38 #include <BRepLib.hxx>
39 #include <BRepLib_MakeEdge.hxx>
40 #include <BRepLib_MakeVertex.hxx>
41 #include <BRepLib_MakePolygon.hxx>
42 #include <BRepLib_MakeFace.hxx>
43 #include <BRepLib_MakeWire.hxx>
44 #include <BRepTools.hxx>
45 #include <BRepTools_WireExplorer.hxx>
47 #include <BRepTools_Modifier.hxx>
48 #include <BRepTools_TrsfModification.hxx>
49 #include <BRepTopAdaptor_FClass2d.hxx>
50 #include <BRepAdaptor_Curve.hxx>
51 #include <BRepAdaptor_Curve2d.hxx>
53 #include <IntRes2d_IntersectionPoint.hxx>
54 #include <IntRes2d_IntersectionSegment.hxx>
55 #include <Extrema_ExtPC.hxx>
58 #include <TopExp_Explorer.hxx>
60 #include <Standard_ConstructionError.hxx>
62 #include <TopOpeBRepBuild_Builder.hxx>
63 #include <TopOpeBRepDS_HDataStructure.hxx>
64 #include <TopOpeBRepDS_CurveExplorer.hxx>
65 #include <TopOpeBRep_DSFiller.hxx>
66 #include <TopOpeBRepTool_GeomTool.hxx>
67 #include <TopOpeBRep_ShapeIntersector.hxx>
68 #include <TopOpeBRep_FacesFiller.hxx>
69 #include <TopOpeBRep_GeomTool.hxx>
71 #include <TopoDS_Iterator.hxx>
72 #include <TopTools_ListIteratorOfListOfShape.hxx>
73 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
75 #include <Geom_Surface.hxx>
76 #include <Geom_RectangularTrimmedSurface.hxx>
77 #include <Geom_OffsetSurface.hxx>
78 #include <Geom_BezierSurface.hxx>
79 #include <Geom_BSplineSurface.hxx>
80 #include <Geom_ConicalSurface.hxx>
81 #include <Geom_Curve.hxx>
82 #include <Geom_Line.hxx>
83 #include <Geom_Conic.hxx>
84 #include <Geom_TrimmedCurve.hxx>
85 #include <GCPnts_QuasiUniformDeflection.hxx>
87 #include <GeomLib.hxx>
88 #include <GeomAPI.hxx>
89 #include <GeomAPI_ProjectPointOnCurve.hxx>
90 #include <Geom2d_TrimmedCurve.hxx>
91 #include <Geom2d_Line.hxx>
92 #include <Geom2d_Curve.hxx>
93 #include <Geom2d_Circle.hxx>
94 #include <Geom2d_Ellipse.hxx>
95 #include <Geom2d_Parabola.hxx>
96 #include <Geom2d_Hyperbola.hxx>
97 #include <Geom2d_BezierCurve.hxx>
98 #include <Geom2d_BSplineCurve.hxx>
100 #include <Geom2dAdaptor_Curve.hxx>
101 #include <Geom2dInt_GInter.hxx>
103 #include <GeomAdaptor_Surface.hxx>
104 #include <GeomProjLib.hxx>
105 #include <GeomInt_IntSS.hxx>
106 #include <ProjLib_ProjectedCurve.hxx>
107 #include <ProjLib_HProjectedCurve.hxx>
109 #include <ElSLib.hxx>
110 #include <ElCLib.hxx>
113 #include <gp_Pnt.hxx>
114 #include <gp_Vec.hxx>
117 #include <Precision.hxx>
118 #include <Standard_ConstructionError.hxx>
120 #include <BRep_TEdge.hxx>
121 #include <Extrema_ExtPC2d.hxx>
123 #include <Geom_SurfaceOfLinearExtrusion.hxx>
124 #include <Geom_SurfaceOfRevolution.hxx>
125 #include <GCPnts_AbscissaPoint.hxx>
127 //tma: for new boolean operation
128 #include <TopTools_SequenceOfShape.hxx>
129 #include <BOPTools_DSFiller.hxx>
130 #include <Geom_BSplineCurve.hxx>
131 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
132 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
133 #include <GeomConvert_ApproxCurve.hxx>
134 #include <Geom2dConvert_ApproxCurve.hxx>
135 //#include <BRepAlgoAPI_Section.hxx>
136 #include <BooleanOperations_ShapesDataStructure.hxx>
137 #include <BOPTools_InterferencePool.hxx>
138 #include <BOPTools_SSInterference.hxx>
139 #include <BOPTools_SequenceOfCurves.hxx>
140 #include <BOPTools_Curve.hxx>
141 #include <BOPTools_ListOfPaveBlock.hxx>
142 #include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
143 #include <BOPTools_PaveBlock.hxx>
144 #include <BRepAlgoAPI_Section.hxx>
145 #include <BOPTools_SSIntersectionAttribute.hxx>
146 #include <BOPTools_PaveFiller.hxx>
147 #include <BOPTools_Tools2D.hxx>
148 #include <BOPTools_ListIteratorOfListOfPave.hxx>
149 #include <TopoDS_Compound.hxx>
150 #include <GCPnts_UniformAbscissa.hxx>
151 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
152 #include <BRep_CurveRepresentation.hxx>
154 #include <BRepOffset_ListOfInterval.hxx>
155 #include <BRepOffset_Interval.hxx>
156 #include <TColgp_Array1OfPnt2d.hxx>
157 #include <ShapeCustom_Curve2d.hxx>
158 #include <GeomAPI_ExtremaCurveCurve.hxx>
166 Standard_Boolean AffichInter = Standard_False;
167 static Standard_Boolean AffichExtent = Standard_False;
168 static Standard_Integer NbNewEdges = 1;
169 static Standard_Integer NbFaces = 1;
170 static Standard_Integer NbFOB = 1;
171 static Standard_Integer NbFTE = 1;
172 static Standard_Integer NbExtE = 1;
174 //char* name = new char[100];
178 //=======================================================================
179 //function : EdgeVertices
181 //=======================================================================
183 void BRepOffset_Tool::EdgeVertices (const TopoDS_Edge& E,
187 if (E.Orientation() == TopAbs_REVERSED) {
188 TopExp::Vertices(E,V2,V1);
191 TopExp::Vertices(E,V1,V2);
195 //=======================================================================
196 //function : OriEdgeInFace
198 //=======================================================================
200 TopAbs_Orientation BRepOffset_Tool::OriEdgeInFace (const TopoDS_Edge& E,
201 const TopoDS_Face& F )
205 Exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
207 for (; Exp.More() ;Exp.Next()) {
208 if (Exp.Current().IsSame(E)) {
209 return Exp.Current().Orientation();
212 Standard_ConstructionError::Raise("BRepOffset_Tool::OriEdgeInFace");
213 return E.Orientation();
217 //=======================================================================
218 //function : FindPeriod
220 //=======================================================================
222 static void FindPeriod (const TopoDS_Face& F,
231 for (exp.Init(F,TopAbs_EDGE); exp.More(); exp.Next()) {
232 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
235 const Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,pf,pl);
236 if (C.IsNull()) return;
237 Geom2dAdaptor_Curve PC(C,pf,pl);
238 Standard_Real i, nbp = 20;
239 if (PC.GetType() == GeomAbs_Line) nbp = 2;
240 Standard_Real step = (pl - pf) / nbp;
244 for (i = 2; i < nbp; i++) {
251 B.Get(umin,vmin,umax,vmax);
255 //=======================================================================
256 //function : PutInBounds
257 //purpose : Recadre la courbe 2d dans les bounds de la face
258 //=======================================================================
260 static void PutInBounds (const TopoDS_Face& F,
261 const TopoDS_Edge& E,
262 Handle(Geom2d_Curve)& C2d)
264 Standard_Real umin,umax,vmin,vmax;
266 BRep_Tool::Range(E,f,l);
268 TopLoc_Location L; // Recup S avec la location pour eviter la copie.
269 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
271 if (S->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
272 S = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface();
277 if (!S->IsUPeriodic() && !S->IsVPeriodic()) return;
279 FindPeriod (F,umin,umax,vmin,vmax);
281 if (S->IsUPeriodic()) {
282 Standard_Real period = S->UPeriod();
283 Standard_Real eps = period*1.e-6;
284 gp_Pnt2d Pf = C2d->Value(f);
285 gp_Pnt2d Pl = C2d->Value(l);
286 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
287 Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
288 Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
289 Standard_Real du = 0.;
290 if (minC< umin - eps) {
291 du = (int((umin - minC)/period) + 1)*period;
293 if (minC > umax + eps) {
294 du = -(int((minC - umax)/period) + 1)*period;
299 minC += du; maxC += du;
301 // Ajuste au mieux la courbe dans le domaine.
302 if (maxC > umax +100*eps) {
303 Standard_Real d1 = maxC - umax;
304 Standard_Real d2 = umin - minC + period;
305 if (d2 < d1) du =-period;
315 if (S->IsVPeriodic()) {
316 Standard_Real period = S->VPeriod();
317 Standard_Real eps = period*1.e-6;
318 gp_Pnt2d Pf = C2d->Value(f);
319 gp_Pnt2d Pl = C2d->Value(l);
320 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
321 Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
322 Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
323 Standard_Real dv = 0.;
324 if (minC< vmin - eps) {
325 dv = (int((vmin - minC)/period) + 1)*period;
327 if (minC > vmax + eps) {
328 dv = -(int((minC - vmax)/period) + 1)*period;
333 minC += dv; maxC += dv;
335 // Ajuste au mieux la courbe dans le domaine.
336 if (maxC > vmax +100*eps) {
337 Standard_Real d1 = maxC - vmax;
338 Standard_Real d2 = vmin - minC + period;
339 if (d2 < d1) dv =-period;
348 //=======================================================================
351 //=======================================================================
353 Standard_Real BRepOffset_Tool::Gabarit(const Handle(Geom_Curve)& aCurve)
355 GeomAdaptor_Curve GC( aCurve );
357 BndLib_Add3dCurve::Add( GC, Precision::Confusion(), aBox );
358 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dist;
359 aBox.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
360 dist = Max( (aXmax-aXmin), (aYmax-aYmin) );
361 dist = Max( dist, (aZmax-aZmin) );
365 //=======================================================================
366 //function : BuildPCurves
368 //=======================================================================
370 static void BuildPCurves (const TopoDS_Edge& E,
371 const TopoDS_Face& F)
374 Handle (Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E,F,ff,ll);
375 if (!C2d.IsNull()) return;
377 //Standard_Real Tolerance = Max(Precision::Confusion(),BRep_Tool::Tolerance(E));
378 Standard_Real Tolerance = Precision::Confusion();
380 BRepAdaptor_Surface AS(F,0);
381 BRepAdaptor_Curve AC(E);
383 //Try to find pcurve on a bound of BSpline or Bezier surface
384 Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( F );
385 Handle( Standard_Type ) typS = theSurf->DynamicType();
386 if (typS == STANDARD_TYPE(Geom_OffsetSurface))
387 typS = (*((Handle(Geom_OffsetSurface)*)&theSurf))->BasisSurface()->DynamicType();
388 if (typS == STANDARD_TYPE(Geom_BezierSurface) || typS == STANDARD_TYPE(Geom_BSplineSurface))
390 gp_Pnt fpoint = AC.Value( AC.FirstParameter() );
391 gp_Pnt lpoint = AC.Value( AC.LastParameter() );
392 TopoDS_Face theFace = BRepLib_MakeFace( theSurf, Precision::Confusion() );
393 Standard_Real U1 = 0., U2 = 0., TolProj = 1.e-4; //1.e-5;
395 TopExp_Explorer Explo;
396 Explo.Init( theFace, TopAbs_EDGE );
397 for (; Explo.More(); Explo.Next())
399 TopoDS_Edge anEdge = TopoDS::Edge( Explo.Current() );
400 BRepAdaptor_Curve aCurve( anEdge );
401 Extrema_ExtPC fextr( fpoint, aCurve );
402 if (!fextr.IsDone() || fextr.NbExt() < 1)
404 Standard_Real dist2, dist2min = RealLast();
406 for (i = 1; i <= fextr.NbExt(); i++)
408 dist2 = fextr.SquareDistance(i);
409 if (dist2 < dist2min)
412 U1 = fextr.Point(i).Parameter();
415 if (dist2min > TolProj * TolProj)
417 Extrema_ExtPC lextr( lpoint, aCurve );
418 if (!lextr.IsDone() || lextr.NbExt() <1)
420 dist2min = RealLast();
421 for (i = 1; i <= lextr.NbExt(); i++)
423 dist2 = lextr.SquareDistance(i);
424 if (dist2 < dist2min)
427 U2 = lextr.Point(i).Parameter();
430 if (dist2min <= TolProj * TolProj)
435 } // for (; Explo.More(); Explo.Current())
437 if (! theEdge.IsNull())
439 //Construction of pcurve
442 Standard_Real temp = U1;
447 C2d = BRep_Tool::CurveOnSurface( theEdge, theFace, f, l );
448 C2d = new Geom2d_TrimmedCurve( C2d, U1, U2 );
450 if (theSurf->IsUPeriodic() || theSurf->IsVPeriodic())
451 PutInBounds( F, E, C2d );
454 B.UpdateEdge( E, C2d, F, BRep_Tool::Tolerance(E) );
455 BRepLib::SameRange( E );
461 Handle(BRepAdaptor_HSurface) HS = new BRepAdaptor_HSurface(AS);
462 Handle(BRepAdaptor_HCurve) HC = new BRepAdaptor_HCurve(AC);
464 ProjLib_ProjectedCurve Proj(HS,HC,Tolerance);
466 switch ( Proj.GetType()) {
469 C2d = new Geom2d_Line(Proj.Line());
473 C2d = new Geom2d_Circle(Proj.Circle());
476 case GeomAbs_Ellipse:
477 C2d = new Geom2d_Ellipse(Proj.Ellipse());
480 case GeomAbs_Parabola:
481 C2d = new Geom2d_Parabola(Proj.Parabola());
484 case GeomAbs_Hyperbola:
485 C2d = new Geom2d_Hyperbola(Proj.Hyperbola());
488 case GeomAbs_BezierCurve:
492 case GeomAbs_BSplineCurve:
493 C2d = Proj.BSpline();
501 if (AS.IsUPeriodic() || AS.IsVPeriodic()) {
502 PutInBounds(F,E,C2d);
506 B.UpdateEdge (E,C2d,F,BRep_Tool::Tolerance(E));
509 Standard_ConstructionError::Raise("BRepOffset_Tool::BuildPCurves");
510 cout <<"Echec ProjLib"<<endl;
514 //=======================================================================
517 //=======================================================================
519 void BRepOffset_Tool::OrientSection (const TopoDS_Edge& E,
520 const TopoDS_Face& F1,
521 const TopoDS_Face& F2,
522 TopAbs_Orientation& O1,
523 TopAbs_Orientation& O2)
528 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
529 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
530 Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l);
531 Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l);
532 Handle (Geom_Curve) C = BRep_Tool::Curve(E,L,f,l);
534 BRepAdaptor_Curve BAcurve( E );
535 GCPnts_UniformAbscissa Distribution( BAcurve, 3 );
536 Standard_Real ParOnC = Distribution.Parameter(2); //0.5*(f+l);
538 gp_Vec T1 = C->DN(ParOnC,1).Transformed(L.Transformation());
539 if (T1.SquareMagnitude() > gp::Resolution()) {
543 gp_Pnt2d P = C1->Value(ParOnC);
547 S1->D1(P.X(),P.Y(),P3,D1U,D1V);
549 if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse();
551 P = C2->Value(ParOnC);
552 S2->D1(P.X(),P.Y(),P3,D1U,D1V);
554 if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse();
556 gp_Vec ProVec = DN2^T1;
557 Standard_Real Prod = DN1.Dot(ProVec);
562 O1 = TopAbs_REVERSED;
565 Prod = DN2.Dot(ProVec);
570 O2 = TopAbs_REVERSED;
572 if (F1.Orientation() == TopAbs_REVERSED) O1 = TopAbs::Reverse(O1);
573 if (F2.Orientation() == TopAbs_REVERSED) O2 = TopAbs::Reverse(O2);
576 //=======================================================================
577 //function : HasCommonShape
579 //=======================================================================
581 Standard_Boolean BRepOffset_Tool::HasCommonShapes (const TopoDS_Face& F1,
582 const TopoDS_Face& F2,
583 TopTools_ListOfShape& LE,
584 TopTools_ListOfShape& LV)
586 Standard_Boolean Common = Standard_False;
587 LE.Clear(); LV.Clear();
589 TopExp_Explorer exp1;
590 exp1.Init(F1,TopAbs_EDGE);
592 for (; exp1.More(); exp1.Next()) {
593 TopExp_Explorer exp2;
594 exp2.Init(F2,TopAbs_EDGE);
595 for (; exp2.More(); exp2.Next()) {
596 if (exp1.Current().IsSame(exp2.Current())) {
597 Common = Standard_True;
598 LE.Append(exp1.Current());
602 for (exp1.Init(F1,TopAbs_VERTEX); exp1.More(); exp1.Next()) {
603 TopExp_Explorer exp2;
604 exp2.Init(F2,TopAbs_EDGE);
605 for (exp2.Init(F2,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
606 if (exp1.Current().IsSame(exp2.Current())) {
607 Common = Standard_True;
608 LV.Append(exp1.Current());
615 //=======================================================================
618 //=======================================================================
620 static Standard_Boolean ToSmall (const Handle(Geom_Curve)& C)
622 Standard_Real Tol = 10*Precision::Confusion();
623 Standard_Real m = (C->FirstParameter()*0.668 + C->LastParameter()*0.332);
624 gp_Pnt P1 = C->Value(C->FirstParameter());
625 gp_Pnt P2 = C->Value(C->LastParameter());
626 gp_Pnt P3 = C->Value(m);
627 if (P1.Distance(P2) > Tol) return Standard_False;
628 if (P2.Distance(P3) > Tol) return Standard_False;
629 return Standard_True;
633 //=======================================================================
634 //function : IsOnSurface
636 //=======================================================================
638 static Standard_Boolean IsOnSurface(const Handle(Geom_Curve)& C,
639 const Handle(Geom_Surface)& S,
640 Standard_Real TolConf,
641 Standard_Real& TolReached)
643 Standard_Real f = C->FirstParameter();
644 Standard_Real l = C->LastParameter();
645 Standard_Integer n = 5;
646 Standard_Real du = (f-l)/(n-1);
652 GeomAdaptor_Surface AS(S);
654 switch ( AS.GetType()) {
657 gp_Ax3 Ax = AS.Plane().Position();
658 for ( Standard_Integer i = 0; i < n; i++) {
659 P = C->Value(f+i*du);
660 ElSLib::PlaneParameters(Ax,P,U,V);
661 TolReached = P.Distance(ElSLib::PlaneValue(U,V,Ax));
662 if ( TolReached > TolConf)
663 return Standard_False;
667 case GeomAbs_Cylinder:
669 gp_Ax3 Ax = AS.Cylinder().Position();
670 Standard_Real Rad = AS.Cylinder().Radius();
671 for ( Standard_Integer i = 0; i < n; i++) {
672 P = C->Value(f+i*du);
673 ElSLib::CylinderParameters(Ax,Rad,P,U,V);
674 TolReached = P.Distance(ElSLib::CylinderValue(U,V,Ax,Rad));
675 if ( TolReached > TolConf)
676 return Standard_False;
682 gp_Ax3 Ax = AS.Cone().Position();
683 Standard_Real Rad = AS.Cone().RefRadius();
684 Standard_Real Alp = AS.Cone().SemiAngle();
685 for ( Standard_Integer i = 0; i < n; i++) {
686 P = C->Value(f+i*du);
687 ElSLib::ConeParameters(Ax,Rad,Alp,P,U,V);
688 TolReached = P.Distance(ElSLib::ConeValue(U,V,Ax,Rad,Alp));
689 if ( TolReached > TolConf)
690 return Standard_False;
696 gp_Ax3 Ax = AS.Sphere().Position();
697 Standard_Real Rad = AS.Sphere().Radius();
698 for ( Standard_Integer i = 0; i < n; i++) {
699 P = C->Value(f+i*du);
700 ElSLib::SphereParameters(Ax,Rad,P,U,V);
701 TolReached = P.Distance(ElSLib::SphereValue(U,V,Ax,Rad));
702 if ( TolReached > TolConf)
703 return Standard_False;
709 gp_Ax3 Ax = AS.Torus().Position();
710 Standard_Real R1 = AS.Torus().MajorRadius();
711 Standard_Real R2 = AS.Torus().MinorRadius();
712 for ( Standard_Integer i = 0; i < n; i++) {
713 P = C->Value(f+i*du);
714 ElSLib::TorusParameters(Ax,R1,R2,P,U,V);
715 TolReached = P.Distance(ElSLib::TorusValue(U,V,Ax,R1,R2));
716 if ( TolReached > TolConf)
717 return Standard_False;
724 return Standard_False;
728 return Standard_True;
732 //=======================================================================
733 //function : PipeInter
735 //=======================================================================
737 void BRepOffset_Tool::PipeInter(const TopoDS_Face& F1,
738 const TopoDS_Face& F2,
739 TopTools_ListOfShape& L1,
740 TopTools_ListOfShape& L2,
741 const TopAbs_State Side)
746 char* name = new char[100];
747 sprintf(name,"FF_%d",NbFaces++);
749 sprintf(name,"FF_%d",NbFaces++);
754 Handle (Geom_Curve) CI;
756 TopAbs_Orientation O1,O2;
757 L1.Clear(); L2.Clear();
759 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
760 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
762 GeomInt_IntSS Inter (S1,S2, Precision::Confusion(),1,1,1);
764 if (Inter.IsDone()) {
765 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
767 if (ToSmall(CI)) continue;
768 TopoDS_Edge E = BRepLib_MakeEdge(CI);
769 if (Inter.HasLineOnS1(i)) {
770 Handle(Geom2d_Curve) C2 = Inter.LineOnS1(i);
771 PutInBounds (F1,E,C2);
772 B.UpdateEdge (E,C2,F1,BRep_Tool::Tolerance(E));
777 if (Inter.HasLineOnS2(i)) {
778 Handle(Geom2d_Curve) C2 = Inter.LineOnS2(i);
779 PutInBounds (F2,E,C2);
780 B.UpdateEdge (E,C2,F2,BRep_Tool::Tolerance(E));
785 OrientSection (E,F1,F2,O1,O2);
786 if (Side == TopAbs_OUT) {
787 O1 = TopAbs::Reverse(O1);
788 O2 = TopAbs::Reverse(O2);
790 L1.Append (E.Oriented(O1));
791 L2.Append (E.Oriented(O2));
795 char* name = new char[100];
796 sprintf(name,"EI_%d",NbNewEdges++);
797 DBRep::Set(name,E.Oriented(O1));
805 //=======================================================================
806 //function : IsAutonomVertex
807 //purpose : Checks wether a vertex is "autonom" or not
808 //=======================================================================
810 static Standard_Boolean IsAutonomVertex(const TopoDS_Shape& aVertex,
811 const TopoDS_Shape& F1,
812 const TopoDS_Shape& F2,
813 const BooleanOperations_ShapesDataStructure& theDS,
814 const BOPTools_PaveFiller& thePaveFiller)
816 Standard_Integer i, index = theDS.ShapeIndex( aVertex, 1 );
819 index = theDS.ShapeIndex( aVertex, 2 );
822 for (i = theDS.NumberOfSourceShapes()+1; i <= theDS.NumberOfInsertedShapes(); i++)
824 const TopoDS_Shape& aShape = theDS.GetShape(i);
825 if (aVertex.IsSame(aShape))
834 Standard_Integer indF1 = theDS.ShapeIndex( F1, 1 );
835 Standard_Integer indF2 = theDS.ShapeIndex( F2, 2 );
837 BooleanOperations_KindOfInterference theTypeInterf;
838 const BOPTools_PavePool& thePavePool = thePaveFiller.PavePool();
839 BOPTools_ListIteratorOfListOfPave itpave;
840 for (i = 1; i <= thePavePool.Length(); i++)
842 const BOPTools_ListOfPave& aPaveList = thePavePool(i).Set();
843 for (itpave.Initialize( aPaveList ); itpave.More(); itpave.Next())
845 BOPTools_Pave aPave = itpave.Value();
846 if (aPave.Index() == index)
848 theTypeInterf = aPave.Type();
849 if (theTypeInterf != BooleanOperations_SurfaceSurface &&
850 theTypeInterf != BooleanOperations_UnknownInterference)
851 return Standard_False;
856 BOPTools_PaveFiller * pPF = (BOPTools_PaveFiller*) &thePaveFiller;
857 BOPTools_PaveFiller& thePF = *pPF;
858 BOPTools_CArray1OfSSInterference& aFFs = thePF.InterfPool()->SSInterferences();
859 Standard_Integer aNbFFs=aFFs.Extent();
860 for (i = 1; i <= aNbFFs; i++)
862 BOPTools_SSInterference& aFFi = aFFs(i);
864 if (aFFi.Index1() == indF1 && aFFi.Index2() == indF2)
866 const BOPTools_ListOfPave& aPaveList = aFFi.NewPaveSet().Set();
867 for (itpave.Initialize( aPaveList ); itpave.More(); itpave.Next())
869 BOPTools_Pave aPave = itpave.Value();
870 if (aPave.Index() == index)
872 theTypeInterf = aPave.Type();
873 if (theTypeInterf != BooleanOperations_SurfaceSurface &&
874 theTypeInterf != BooleanOperations_UnknownInterference)
875 return Standard_False;
881 return Standard_True;
885 //=======================================================================
886 //function : AreConnex
887 //purpose : define if two shapes are connex by a vertex (vertices)
888 //=======================================================================
890 static Standard_Boolean AreConnex(const TopoDS_Wire& W1,
891 const TopoDS_Wire& W2,
892 const TopoDS_Shape& F1,
893 const TopoDS_Shape& F2,
894 const BOPTools_DSFiller* pDF)
896 TopoDS_Vertex V11, V12, V21, V22;
897 TopExp::Vertices( W1, V11, V12 );
898 TopExp::Vertices( W2, V21, V22 );
900 if (V11.IsSame(V21) || V11.IsSame(V22) ||
901 V12.IsSame(V21) || V12.IsSame(V22))
903 Standard_Boolean isCV1 = V11.IsSame(V21) || V11.IsSame(V22);
904 Standard_Boolean isCV2 = V12.IsSame(V21) || V12.IsSame(V22);
905 if (isCV1 && !IsAutonomVertex(V11, F1, F2, pDF->DS(), pDF->PaveFiller()))
908 return Standard_False;
909 if (!IsAutonomVertex(V12, F1, F2, pDF->DS(), pDF->PaveFiller()))
910 return Standard_False;
912 if (!isCV1 && !IsAutonomVertex(V12, F1, F2, pDF->DS(), pDF->PaveFiller()))
913 return Standard_False;
915 TopoDS_Vertex CV = (V11.IsSame(V21) || V11.IsSame(V22))? V11 : V12;
917 TopoDS_Iterator itw( W1 );
918 for (; itw.More(); itw.Next())
920 E1 = TopoDS::Edge(itw.Value());
921 TopoDS_Vertex V1, V2;
922 TopExp::Vertices( E1, V1, V2 );
923 if (V1.IsSame(CV) || V2.IsSame(CV))
926 itw.Initialize( W2 );
927 E2 = TopoDS::Edge(itw.Value());
930 Handle(Geom_Curve) C1 = BRep_Tool::Curve( E1, f, l );
931 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
932 C1 = (*((Handle(Geom_TrimmedCurve)*)&C1))->BasisCurve();
934 Handle(Geom_Curve) C2 = BRep_Tool::Curve( E2, f, l );
935 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
936 C2 = (*((Handle(Geom_TrimmedCurve)*)&C2))->BasisCurve();
938 if (C1->IsInstance(STANDARD_TYPE(Geom_Line)) &&
939 C2->IsInstance(STANDARD_TYPE(Geom_Line)))
941 Handle(Geom_Line) L1 = *((Handle(Geom_Line)*) &C1);
942 gp_Ax1 Axis1 = L1->Position();
943 Handle(Geom_Line) L2 = *((Handle(Geom_Line)*) &C2);
944 gp_Ax1 Axis2 = L2->Position();
945 if (! Axis1.IsParallel( Axis2, Precision::Angular() ))
946 return Standard_False;
949 return Standard_True;
952 return Standard_False;
955 //=======================================================================
956 //function : AreClosed
957 //purpose : define if two edges are connex by two vertices
958 //=======================================================================
960 static Standard_Boolean AreClosed(const TopoDS_Edge& E1,
961 const TopoDS_Edge& E2)
963 TopoDS_Vertex V11, V12, V21, V22;
964 TopExp::Vertices( E1, V11, V12 );
965 TopExp::Vertices( E2, V21, V22 );
967 if (V11.IsSame(V21) && V12.IsSame(V22) ||
968 V11.IsSame(V22) && V12.IsSame(V21))
969 return Standard_True;
971 return Standard_False;
974 //=======================================================================
975 //function : BSplineEdges
977 //=======================================================================
979 static Standard_Boolean BSplineEdges(const TopoDS_Edge& E1,
980 const TopoDS_Edge& E2,
981 const Standard_Integer par1,
982 const Standard_Integer par2,
983 Standard_Real& angle)
985 Standard_Real first1, last1, first2, last2, Param1, Param2;
987 Handle(Geom_Curve) C1 = BRep_Tool::Curve( E1, first1, last1 );
988 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
989 C1 = (*((Handle(Geom_TrimmedCurve)*)&C1))->BasisCurve();
991 Handle(Geom_Curve) C2 = BRep_Tool::Curve( E2, first2, last2 );
992 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
993 C2 = (*((Handle(Geom_TrimmedCurve)*)&C2))->BasisCurve();
995 if (!C1->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)) ||
996 !C2->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)))
997 return Standard_False;
999 Param1 = (par1 == 0)? first1 : last1;
1000 Param2 = (par2 == 0)? first2 : last2;
1004 C1->D1( Param1, Pnt1, Der1 );
1005 C2->D1( Param2, Pnt2, Der2 );
1007 if (Der1.Magnitude() <= gp::Resolution() ||
1008 Der2.Magnitude() <= gp::Resolution())
1011 angle = Der1.Angle(Der2);
1013 return Standard_True;
1016 //=======================================================================
1017 //function : AngleWireEdge
1019 //=======================================================================
1021 static Standard_Real AngleWireEdge(const TopoDS_Wire& aWire,
1022 const TopoDS_Edge& anEdge)
1024 TopoDS_Vertex V11, V12, V21, V22, CV;
1025 TopExp::Vertices( aWire, V11, V12 );
1026 TopExp::Vertices( anEdge, V21, V22 );
1027 CV = (V11.IsSame(V21) || V11.IsSame(V22))? V11 : V12;
1028 TopoDS_Edge FirstEdge;
1029 TopoDS_Iterator itw(aWire);
1030 for (; itw.More(); itw.Next())
1032 FirstEdge = TopoDS::Edge(itw.Value());
1033 TopoDS_Vertex v1, v2;
1034 TopExp::Vertices( FirstEdge, v1, v2 );
1035 if (v1.IsSame(CV) || v2.IsSame(CV))
1042 Standard_Real Angle;
1043 if (V11.IsSame(CV) && V21.IsSame(CV))
1045 BSplineEdges( FirstEdge, anEdge, 0, 0, Angle );
1046 Angle = M_PI - Angle;
1048 else if (V11.IsSame(CV) && V22.IsSame(CV))
1049 BSplineEdges( FirstEdge, anEdge, 0, 1, Angle );
1050 else if (V12.IsSame(CV) && V21.IsSame(CV))
1051 BSplineEdges( FirstEdge, anEdge, 1, 0, Angle );
1054 BSplineEdges( FirstEdge, anEdge, 1, 1, Angle );
1055 Angle = M_PI - Angle;
1061 //=======================================================================
1062 //function : ReconstructPCurves
1064 //=======================================================================
1066 static void ReconstructPCurves(const TopoDS_Edge& anEdge)
1069 Handle(Geom_Curve) C3d = BRep_Tool::Curve(anEdge, f, l);
1071 BRep_ListIteratorOfListOfCurveRepresentation
1072 itcr( (Handle(BRep_TEdge)::DownCast(anEdge.TShape()))->ChangeCurves() );
1073 for (; itcr.More(); itcr.Next())
1075 Handle( BRep_CurveRepresentation ) CurveRep = itcr.Value();
1076 if (CurveRep->IsCurveOnSurface())
1078 Handle(Geom_Surface) theSurf = CurveRep->Surface();
1079 TopLoc_Location theLoc = CurveRep->Location();
1080 theLoc = anEdge.Location() * theLoc;
1081 theSurf = Handle(Geom_Surface)::DownCast
1082 (theSurf->Transformed(theLoc.Transformation()));
1083 Handle(Geom2d_Curve) ProjPCurve =
1084 GeomProjLib::Curve2d( C3d, f, l, theSurf );
1085 CurveRep->PCurve( ProjPCurve );
1090 //=======================================================================
1091 //function : ConcatPCurves
1093 //=======================================================================
1095 static Handle(Geom2d_Curve) ConcatPCurves(const TopoDS_Edge& E1,
1096 const TopoDS_Edge& E2,
1097 const TopoDS_Face& F,
1098 const Standard_Boolean After,
1099 Standard_Real& newFirst,
1100 Standard_Real& newLast)
1102 Standard_Real Tol = 1.e-7;
1103 GeomAbs_Shape Continuity = GeomAbs_C1;
1104 Standard_Integer MaxDeg = 14;
1105 Standard_Integer MaxSeg = 16;
1107 Standard_Real first1, last1, first2, last2;
1108 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1110 PCurve1 = BRep_Tool::CurveOnSurface( E1, F, first1, last1 );
1111 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
1112 PCurve1 = (*((Handle(Geom2d_TrimmedCurve)*)&PCurve1))->BasisCurve();
1114 PCurve2 = BRep_Tool::CurveOnSurface( E2, F, first2, last2 );
1115 if (PCurve2->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
1116 PCurve2 = (*((Handle(Geom2d_TrimmedCurve)*)&PCurve2))->BasisCurve();
1118 if (PCurve1 == PCurve2)
1120 newPCurve = PCurve1;
1121 newFirst = Min( first1, first2 );
1122 newLast = Max( last1, last2 );
1124 else if (PCurve1->DynamicType() == PCurve2->DynamicType() &&
1125 (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)) ||
1126 PCurve1->IsKind(STANDARD_TYPE(Geom2d_Conic))))
1128 newPCurve = PCurve1;
1130 P1 = PCurve2->Value( first2 );
1131 P2 = PCurve2->Value( last2 );
1132 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)))
1134 Handle(Geom2d_Line) Lin1 = *((Handle(Geom2d_Line)*) &PCurve1);
1135 gp_Lin2d theLin = Lin1->Lin2d();
1136 first2 = ElCLib::Parameter( theLin, P1 );
1137 last2 = ElCLib::Parameter( theLin, P2 );
1139 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Circle)))
1141 Handle(Geom2d_Circle) Circ1 = *((Handle(Geom2d_Circle)*) &PCurve1);
1142 gp_Circ2d theCirc = Circ1->Circ2d();
1143 first2 = ElCLib::Parameter( theCirc, P1 );
1144 last2 = ElCLib::Parameter( theCirc, P2 );
1146 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Ellipse)))
1148 Handle(Geom2d_Ellipse) Ell1 = *((Handle(Geom2d_Ellipse)*) &PCurve1);
1149 gp_Elips2d theElips = Ell1->Elips2d();
1150 first2 = ElCLib::Parameter( theElips, P1 );
1151 last2 = ElCLib::Parameter( theElips, P2 );
1153 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Parabola)))
1155 Handle(Geom2d_Parabola) Parab1 = *((Handle(Geom2d_Parabola)*) &PCurve1);
1156 gp_Parab2d theParab = Parab1->Parab2d();
1157 first2 = ElCLib::Parameter( theParab, P1 );
1158 last2 = ElCLib::Parameter( theParab, P2 );
1160 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Hyperbola)))
1162 Handle(Geom2d_Hyperbola) Hypr1 = *((Handle(Geom2d_Hyperbola)*) &PCurve1);
1163 gp_Hypr2d theHypr = Hypr1->Hypr2d();
1164 first2 = ElCLib::Parameter( theHypr, P1 );
1165 last2 = ElCLib::Parameter( theHypr, P2 );
1167 newFirst = Min( first1, first2 );
1168 newLast = Max( last1, last2 );
1172 Handle(Geom2d_TrimmedCurve) TC1 = new Geom2d_TrimmedCurve( PCurve1, first1, last1 );
1173 Handle(Geom2d_TrimmedCurve) TC2 = new Geom2d_TrimmedCurve( PCurve2, first2, last2 );
1174 Geom2dConvert_CompCurveToBSplineCurve Concat2d( TC1 );
1175 Concat2d.Add( TC2, Precision::Confusion(), After );
1176 newPCurve = Concat2d.BSplineCurve();
1177 if (newPCurve->Continuity() < GeomAbs_C1)
1179 Geom2dConvert_ApproxCurve Approx2d( newPCurve, Tol, Continuity, MaxSeg, MaxDeg );
1180 if (Approx2d.HasResult())
1181 newPCurve = Approx2d.Curve();
1183 newFirst = newPCurve->FirstParameter();
1184 newLast = newPCurve->LastParameter();
1190 //=======================================================================
1192 //purpose : glue two edges.
1193 //=======================================================================
1195 static TopoDS_Edge Glue(const TopoDS_Edge& E1,
1196 const TopoDS_Edge& E2,
1197 const TopoDS_Vertex& Vfirst,
1198 const TopoDS_Vertex& Vlast,
1199 const Standard_Boolean After,
1200 const TopoDS_Face& F1,
1201 const Standard_Boolean addPCurve1,
1202 const TopoDS_Face& F2,
1203 const Standard_Boolean addPCurve2)
1205 Standard_Real Tol = 1.e-7;
1206 GeomAbs_Shape Continuity = GeomAbs_C1;
1207 Standard_Integer MaxDeg = 14;
1208 Standard_Integer MaxSeg = 16;
1210 Handle(Geom_Curve) C1, C2, newCurve;
1211 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1212 Standard_Real first1, last1, first2, last2, fparam=0., lparam=0.;
1213 Standard_Boolean IsCanonic = Standard_False;
1215 C1 = BRep_Tool::Curve( E1, first1, last1 );
1216 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
1217 C1 = (*((Handle(Geom_TrimmedCurve)*)&C1))->BasisCurve();
1219 C2 = BRep_Tool::Curve( E2, first2, last2 );
1220 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
1221 C2 = (*((Handle(Geom_TrimmedCurve)*)&C2))->BasisCurve();
1226 fparam = Min( first1, first2 );
1227 lparam = Max( last1, last2 );
1229 else if (C1->DynamicType() == C2->DynamicType() &&
1230 (C1->IsInstance(STANDARD_TYPE(Geom_Line)) ||
1231 C1->IsKind(STANDARD_TYPE(Geom_Conic))))
1233 IsCanonic = Standard_True;
1238 Handle(Geom_TrimmedCurve) TC1 = new Geom_TrimmedCurve( C1, first1, last1 );
1239 Handle(Geom_TrimmedCurve) TC2 = new Geom_TrimmedCurve( C2, first2, last2 );
1240 GeomConvert_CompCurveToBSplineCurve Concat( TC1 );
1241 Concat.Add( TC2, Precision::Confusion(), After );
1242 newCurve = Concat.BSplineCurve();
1243 if (newCurve->Continuity() < GeomAbs_C1)
1245 GeomConvert_ApproxCurve Approx3d( newCurve, Tol, Continuity, MaxSeg, MaxDeg );
1246 if (Approx3d.HasResult())
1247 newCurve = Approx3d.Curve();
1249 fparam = newCurve->FirstParameter();
1250 lparam = newCurve->LastParameter();
1253 TopoDS_Edge newEdge;
1257 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast );
1259 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast, fparam, lparam );
1261 Standard_Real newFirst, newLast;
1264 newPCurve = ConcatPCurves( E1, E2, F1, After, newFirst, newLast );
1265 BB.UpdateEdge( newEdge, newPCurve, F1, 0. );
1266 BB.Range( newEdge, F1, newFirst, newLast );
1270 newPCurve = ConcatPCurves( E1, E2, F2, After, newFirst, newLast );
1271 BB.UpdateEdge( newEdge, newPCurve, F2, 0. );
1272 BB.Range( newEdge, F2, newFirst, newLast );
1279 //=======================================================================
1280 //function : FindNewVerticesOnBoundsOfFace
1282 //=======================================================================
1284 static void FindNewVerticesOnBoundsOfFace(const BOPTools_DSFiller& pDF,
1285 const TopoDS_Face& aFace,
1286 const Standard_Integer iFace,
1287 TopTools_DataMapOfShapeShape& VEmap)
1289 TopTools_IndexedMapOfShape OldVertices;
1290 TopExp::MapShapes( aFace, TopAbs_VERTEX, OldVertices );
1292 const BOPTools_SplitShapesPool& aPool = pDF.SplitShapesPool();
1294 TopExp_Explorer Explo( aFace, TopAbs_EDGE );
1295 for (; Explo.More(); Explo.Next())
1297 TopoDS_Shape anEdge = Explo.Current();
1298 Standard_Integer eind = pDF.DS().ShapeIndex(anEdge,iFace);
1299 const BOPTools_ListOfPaveBlock& aSplitEdges = aPool( pDF.DS().RefEdge(eind) );
1300 BOPTools_ListIteratorOfListOfPaveBlock itpb( aSplitEdges );
1301 for (; itpb.More(); itpb.Next())
1303 BOPTools_PaveBlock& aPaveBlock = itpb.Value();
1304 TopoDS_Shape aSplit = pDF.DS().GetShape( aPaveBlock.Edge() );
1305 TopoDS_Edge aNewEdge = TopoDS::Edge(aSplit);
1306 TopoDS_Vertex V1, V2;
1307 TopExp::Vertices( aNewEdge, V1, V2 );
1308 if (!OldVertices.Contains( V1 ))
1309 VEmap.Bind( V1, anEdge );
1310 if (!OldVertices.Contains( V2 ))
1311 VEmap.Bind( V2, anEdge );
1316 //=======================================================================
1317 //function : CheckIntersFF
1319 //=======================================================================
1321 static Standard_Boolean CheckIntersFF(const BOPTools_DSFiller& pDF,
1322 const TopoDS_Edge& RefEdge,
1323 const TopoDS_Face& F1,
1324 const TopoDS_Face& F2,
1325 TopTools_IndexedMapOfShape& TrueEdges)
1327 Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
1328 Standard_Boolean isPlane1 = Standard_False, isPlane2 = Standard_False;
1330 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F1);
1331 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1332 aSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&aSurf))->BasisSurface();
1333 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1334 isPlane1 = Standard_True;
1335 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1336 isEl1 = Standard_True;
1338 aSurf = BRep_Tool::Surface(F2);
1339 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1340 aSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&aSurf))->BasisSurface();
1341 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1342 isPlane2 = Standard_True;
1343 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1344 isEl2 = Standard_True;
1346 if (isPlane1 || isPlane2)
1347 return Standard_True;
1350 return Standard_True;
1352 const BooleanOperations_ShapesDataStructure& aDS = pDF.DS();
1353 BOPTools_InterferencePool* anIntrPool = (BOPTools_InterferencePool*)&pDF.InterfPool();
1354 BOPTools_CArray1OfSSInterference& aFFs = anIntrPool->SSInterferences();
1355 Standard_Integer aNb = aFFs.Extent();
1356 Standard_Integer i, j, nbe = 0;
1358 TopTools_SequenceOfShape Edges;
1360 for (i = 1; i <= aNb; i++)
1362 BOPTools_SSInterference& aFFi = aFFs(i);
1363 BOPTools_SequenceOfCurves& aBCurves = aFFi.Curves();
1364 Standard_Integer aNbCurves = aBCurves.Length();
1366 for (j = 1; j <= aNbCurves; j++)
1368 BOPTools_Curve& aBC = aBCurves(j);
1369 const BOPTools_ListOfPaveBlock& aSectEdges = aBC.NewPaveBlocks();
1371 BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSectEdges);
1373 for (; aPBIt.More(); aPBIt.Next())
1375 BOPTools_PaveBlock& aPB=aPBIt.Value();
1376 Standard_Integer nSect = aPB.Edge();
1377 TopoDS_Edge anEdge = TopoDS::Edge(aDS.Shape(nSect));
1378 Edges.Append( anEdge );
1385 return Standard_True;
1387 //define tangents of RefEdge on start and on end
1388 BRepAdaptor_Curve cref(RefEdge);
1389 gp_Vec RefTangFirst = cref.DN(cref.FirstParameter(), 1);
1390 gp_Vec RefTangLast = cref.DN(cref.LastParameter(), 1);
1392 //find the start edge and take it from Edges
1393 TopoDS_Edge StartEdge; //, StartEonF1, StartEonF2, EndEonF1, EndEonF2;
1395 TopTools_DataMapOfShapeShape VEmapF1, VEmapF2;
1396 FindNewVerticesOnBoundsOfFace( pDF, F1, 1, VEmapF1 );
1397 FindNewVerticesOnBoundsOfFace( pDF, F2, 2, VEmapF2 );
1399 Standard_Real AngTol = 0.1;
1400 Standard_Boolean V1onBound = Standard_False;
1401 Standard_Boolean V2onBound = Standard_False;
1402 TopoDS_Vertex V1, V2, Vcur;
1403 gp_Vec TangFirst, TangLast, TangCur;
1404 for (i = 1; i <= Edges.Length(); i++)
1406 StartEdge = TopoDS::Edge(Edges(i));
1407 TopExp::Vertices( StartEdge, V1, V2 );
1408 V1onBound = VEmapF1.IsBound(V1) || VEmapF2.IsBound(V1); // && ?
1409 V2onBound = VEmapF1.IsBound(V2) || VEmapF2.IsBound(V2); // && ?
1410 if (V1onBound || V2onBound)
1412 BRepAdaptor_Curve CE(StartEdge);
1413 TangFirst = CE.DN( CE.FirstParameter(), 1 );
1414 TangLast = CE.DN( CE.LastParameter(), 1 );
1417 if (TangFirst.IsParallel( RefTangFirst, AngTol ) ||
1418 TangFirst.IsParallel( RefTangLast, AngTol ))
1419 break; //start edged found
1423 if (TangLast.IsParallel( RefTangLast, AngTol ) ||
1424 TangLast.IsParallel( RefTangFirst, AngTol ))
1425 break; //start edged found
1430 if (i > Edges.Length()) //start edged not found
1431 return Standard_False;
1433 if (V1onBound && V2onBound)
1435 if (TangFirst.IsParallel(RefTangFirst,AngTol) && TangLast.IsParallel(RefTangLast,AngTol) ||
1436 TangFirst.IsParallel(RefTangLast,AngTol) && TangLast.IsParallel(RefTangFirst,AngTol))
1438 TrueEdges.Add( Edges(i) );
1439 return Standard_True;
1442 return Standard_False;
1445 //StartEonF1 = (V1onBound)? VEmapF1( V1 ) : VEmapF1( V2 );
1446 //StartEonF2 = (V1onBound)? VEmapF2( V1 ) : VEmapF2( V2 );
1448 TrueEdges.Add( Edges(i) );
1450 Vcur = (V1onBound)? V2 : V1;
1451 TangCur = (V1onBound)? TangLast : TangFirst;
1455 //build the chain from StartEdge till the opposite bound of face
1458 TColStd_SequenceOfInteger Candidates;
1459 for (i = 1; i <= Edges.Length(); i++)
1461 TopoDS_Edge anEdge = TopoDS::Edge(Edges(i));
1462 TopExp::Vertices( anEdge, V1, V2 );
1463 if (V1.IsSame(Vcur) || V2.IsSame(Vcur))
1464 Candidates.Append(i);
1466 if (Candidates.IsEmpty())
1469 return Standard_False;
1472 Standard_Integer minind = 1;
1473 if (Candidates.Length() > 1)
1475 Standard_Real MinAngle = RealLast();
1476 for (i = 1; i <= Candidates.Length(); i++)
1478 TopoDS_Edge anEdge = TopoDS::Edge(Edges(Candidates(i)));
1479 TopExp::Vertices( anEdge, V1, V2 );
1480 Standard_Boolean ConnectByFirst = (Vcur.IsSame(V1))? Standard_True : Standard_False;
1481 BRepAdaptor_Curve CE(anEdge);
1482 gp_Vec aTang = (ConnectByFirst)?
1483 CE.DN( CE.FirstParameter(), 1 ) : CE.DN( CE.LastParameter(), 1 );
1484 if (!ConnectByFirst)
1486 Standard_Real anAngle = TangCur.Angle(aTang);
1487 if (anAngle < MinAngle)
1494 TopoDS_Edge CurEdge = TopoDS::Edge(Edges(Candidates(minind)));
1495 TrueEdges.Add( CurEdge );
1496 Edges.Remove(Candidates(minind));
1497 TopExp::Vertices( CurEdge, V1, V2 );
1498 Standard_Boolean ConnectByFirst = (Vcur.IsSame(V1))? Standard_True : Standard_False;
1499 Vcur = (ConnectByFirst)? V2 : V1;
1500 BRepAdaptor_Curve CE(CurEdge);
1501 TangCur = (ConnectByFirst)? CE.DN( CE.LastParameter(), 1 ) : CE.DN( CE.FirstParameter(), 1 );
1502 if (!ConnectByFirst)
1504 //check if Vcur is on bounds of faces
1505 if (VEmapF1.IsBound(Vcur) || VEmapF2.IsBound(Vcur))
1509 if (TangCur.IsParallel( RefTangFirst, AngTol ) ||
1510 TangCur.IsParallel( RefTangLast, AngTol ))
1511 return Standard_True;
1514 return Standard_False;
1517 //=======================================================================
1518 //function : AssembleEdge
1520 //=======================================================================
1522 static TopoDS_Edge AssembleEdge(const BOPTools_DSFiller* pDF,
1523 const TopoDS_Face& F1,
1524 const TopoDS_Face& F2,
1525 const Standard_Boolean addPCurve1,
1526 const Standard_Boolean addPCurve2,
1527 const TopTools_SequenceOfShape& EdgesForConcat)
1529 TopoDS_Edge CurEdge = TopoDS::Edge( EdgesForConcat(1) );
1530 for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
1532 TopoDS_Edge anEdge = TopoDS::Edge( EdgesForConcat(j) );
1533 Standard_Boolean After = Standard_False;
1534 TopoDS_Vertex Vfirst, Vlast;
1535 if (AreClosed( CurEdge, anEdge ))
1537 TopoDS_Vertex V1, V2;
1538 TopExp::Vertices( CurEdge, V1, V2 );
1539 if (IsAutonomVertex( V1, F1, F2, pDF->DS(), pDF->PaveFiller() ))
1541 After = Standard_False;
1542 Vfirst = Vlast = V2;
1546 After = Standard_True;
1547 Vfirst = Vlast = V1;
1552 TopoDS_Vertex CV, V11, V12, V21, V22;
1553 TopExp::CommonVertex( CurEdge, anEdge, CV );
1554 TopExp::Vertices( CurEdge, V11, V12 );
1555 TopExp::Vertices( anEdge, V21, V22 );
1556 if (V11.IsSame(CV) && V21.IsSame(CV))
1561 else if (V11.IsSame(CV) && V22.IsSame(CV))
1566 else if (V12.IsSame(CV) && V21.IsSame(CV))
1576 } //end of else (open wire)
1578 TopoDS_Edge NewEdge = Glue(CurEdge, anEdge,
1579 Vfirst, Vlast, After,
1580 F1, addPCurve1, F2, addPCurve2);
1582 } //end of for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
1587 //=======================================================================
1588 //function : Inter3D
1590 //=======================================================================
1592 void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1,
1593 const TopoDS_Face& F2,
1594 TopTools_ListOfShape& L1,
1595 TopTools_ListOfShape& L2,
1596 const TopAbs_State Side,
1597 const TopoDS_Edge& RefEdge,
1598 const Standard_Boolean IsRefEdgeDefined)
1603 char* name = new char[100];
1604 sprintf(name,"FF_%d",NbFaces++);
1605 DBRep::Set(name,F1);
1606 sprintf(name,"FF_%d",NbFaces++);
1607 DBRep::Set(name,F2);
1611 TopoDS_Face cpF1=F1;
1612 TopoDS_Face cpF2=F2;
1613 // create 3D curves on faces
1614 BRepLib::BuildCurves3d(cpF1);
1615 BRepLib::BuildCurves3d(cpF2);
1617 BOPTools_DSFiller pDF1, pDF2;
1618 pDF1.SetShapes(cpF1, cpF2);
1622 BOPTools_DSFiller * pDF = &pDF1;
1623 TopTools_IndexedMapOfShape TrueEdges;
1624 if (IsRefEdgeDefined && !CheckIntersFF( pDF1, RefEdge, cpF1, cpF2, TrueEdges ))
1628 pDF2.SetShapes(cpF1, cpF2);
1630 CheckIntersFF( pDF2, RefEdge, cpF1, cpF2, TrueEdges );
1634 Standard_Boolean addPCurve1 = pDF->PaveFiller().SectionAttribute().PCurveOnS1();
1635 Standard_Boolean addPCurve2 = pDF->PaveFiller().SectionAttribute().PCurveOnS2();
1637 const BooleanOperations_ShapesDataStructure& aDS = pDF->DS();
1638 BOPTools_InterferencePool* anIntrPool = (BOPTools_InterferencePool*)& pDF->InterfPool();
1639 BOPTools_CArray1OfSSInterference& aFFs = anIntrPool->SSInterferences();
1640 Standard_Integer aNb = aFFs.Extent();
1641 Standard_Integer i = 0, j = 0, k;
1643 L1.Clear(); L2.Clear();
1644 TopAbs_Orientation O1,O2;
1646 for (i = 1; i <= aNb; i++) {
1647 BOPTools_SSInterference& aFFi = aFFs(i);
1648 BOPTools_SequenceOfCurves& aBCurves = aFFi.Curves();
1649 Standard_Integer aNbCurves = aBCurves.Length();
1651 for (j = 1; j <= aNbCurves; j++) {
1652 BOPTools_Curve& aBC = aBCurves(j);
1653 const BOPTools_ListOfPaveBlock& aSectEdges = aBC.NewPaveBlocks();
1655 BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSectEdges);
1657 for (; aPBIt.More(); aPBIt.Next()) {
1658 BOPTools_PaveBlock& aPB=aPBIt.Value();
1659 Standard_Integer nSect = aPB.Edge();
1660 TopoDS_Edge anEdge = TopoDS::Edge(aDS.Shape(nSect));
1661 if (!TrueEdges.IsEmpty() && !TrueEdges.Contains(anEdge))
1665 const Handle(Geom_Curve)& aC3DE = BRep_Tool::Curve(anEdge, f, l);
1666 Handle(Geom_TrimmedCurve) aC3DETrim;
1669 aC3DETrim = new Geom_TrimmedCurve(aC3DE, f, l);
1672 Standard_Real aTolEdge = BRep_Tool::Tolerance(anEdge);
1674 if (!BOPTools_Tools2D::HasCurveOnSurface(anEdge, cpF1)) {
1675 Handle(Geom2d_Curve) aC2d = aBC.Curve().FirstCurve2d();
1676 if(!aC3DETrim.IsNull()) {
1677 Handle(Geom2d_Curve) aC2dNew;
1679 if(aC3DE->IsPeriodic()) {
1680 BOPTools_Tools2D::AdjustPCurveOnFace(cpF1, f, l, aC2d, aC2dNew);
1683 BOPTools_Tools2D::AdjustPCurveOnFace(cpF1, aC3DETrim, aC2d, aC2dNew);
1687 aBB.UpdateEdge(anEdge, aC2d, cpF1, aTolEdge);
1690 if (!BOPTools_Tools2D::HasCurveOnSurface(anEdge, cpF2)) {
1691 Handle(Geom2d_Curve) aC2d = aBC.Curve().SecondCurve2d();
1692 if(!aC3DETrim.IsNull()) {
1693 Handle(Geom2d_Curve) aC2dNew;
1695 if(aC3DE->IsPeriodic()) {
1696 BOPTools_Tools2D::AdjustPCurveOnFace(cpF2, f, l, aC2d, aC2dNew);
1699 BOPTools_Tools2D::AdjustPCurveOnFace(cpF2, aC3DETrim, aC2d, aC2dNew);
1703 aBB.UpdateEdge(anEdge, aC2d, cpF2, aTolEdge);
1706 OrientSection (anEdge, F1, F2, O1, O2);
1707 if (Side == TopAbs_OUT) {
1708 O1 = TopAbs::Reverse(O1);
1709 O2 = TopAbs::Reverse(O2);
1712 L1.Append (anEdge.Oriented(O1));
1713 L2.Append (anEdge.Oriented(O2));
1717 char* name = new char[100];
1718 sprintf(name,"EI_%d",NbNewEdges++);
1719 DBRep::Set(name,anEdge.Oriented(O1));
1727 Standard_Real aSameParTol = Precision::Confusion();
1728 Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
1730 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(cpF1);
1731 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1732 aSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&aSurf))->BasisSurface();
1733 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1734 addPCurve1 = Standard_False;
1735 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1736 isEl1 = Standard_True;
1738 aSurf = BRep_Tool::Surface(cpF2);
1739 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1740 aSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&aSurf))->BasisSurface();
1741 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1742 addPCurve2 = Standard_False;
1743 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1744 isEl2 = Standard_True;
1746 if (L1.Extent() > 1 && (!isEl1 || !isEl2)) {
1747 TopTools_SequenceOfShape eseq;
1748 TopTools_SequenceOfShape EdgesForConcat;
1750 if (!TrueEdges.IsEmpty())
1752 for (i = TrueEdges.Extent(); i >= 1; i--)
1753 EdgesForConcat.Append( TrueEdges(i) );
1754 TopoDS_Edge theEdge =
1755 AssembleEdge( pDF, cpF1, cpF2, addPCurve1, addPCurve2, EdgesForConcat );
1756 eseq.Append(theEdge);
1760 const BOPTools_PaveFiller& thePaveFiller = pDF->PaveFiller();
1762 TopTools_SequenceOfShape wseq;
1763 TopTools_SequenceOfShape edges;
1764 TopTools_ListIteratorOfListOfShape itl(L1);
1765 for (; itl.More(); itl.Next())
1766 edges.Append( itl.Value() );
1767 while (!edges.IsEmpty())
1769 TopoDS_Edge anEdge = TopoDS::Edge( edges.First() );
1770 TopoDS_Wire aWire = BRepLib_MakeWire( anEdge ), resWire;
1771 TColStd_SequenceOfInteger Candidates;
1772 for (k = 1; k <= wseq.Length(); k++)
1774 resWire = TopoDS::Wire(wseq(k));
1775 if (AreConnex( resWire, aWire, cpF1, cpF2, pDF ))
1777 Candidates.Append( 1 );
1781 if (Candidates.IsEmpty())
1783 wseq.Append( aWire );
1788 for (j = 2; j <= edges.Length(); j++)
1790 anEdge = TopoDS::Edge( edges(j) );
1791 //if (anEdge.IsSame(edges(Candidates.First())))
1793 aWire = BRepLib_MakeWire( anEdge );
1794 if (AreConnex( resWire, aWire, cpF1, cpF2, pDF ))
1795 Candidates.Append( j );
1797 Standard_Integer minind = 1;
1798 if (Candidates.Length() > 1)
1800 Standard_Real MinAngle = RealLast();
1801 for (j = 1; j <= Candidates.Length(); j++)
1803 anEdge = TopoDS::Edge( edges(Candidates(j)) );
1804 Standard_Real anAngle = AngleWireEdge( resWire, anEdge );
1805 if (anAngle < MinAngle)
1812 TopoDS_Wire NewWire = BRepLib_MakeWire( resWire, TopoDS::Edge(edges(Candidates(minind))) );
1814 edges.Remove(Candidates(minind));
1816 } //end of while (!edges.IsEmpty())
1818 for (i = 1; i <= wseq.Length(); i++)
1820 TopoDS_Wire aWire = TopoDS::Wire(wseq(i));
1821 TopTools_SequenceOfShape EdgesForConcat;
1824 TopoDS_Vertex StartVertex;
1825 TopoDS_Edge StartEdge;
1826 Standard_Boolean StartFound = Standard_False;
1827 TopTools_ListOfShape Elist;
1829 TopoDS_Iterator itw(aWire);
1830 for (; itw.More(); itw.Next())
1832 TopoDS_Edge anEdge = TopoDS::Edge(itw.Value());
1834 Elist.Append(anEdge);
1837 TopoDS_Vertex V1, V2;
1838 TopExp::Vertices( anEdge, V1, V2 );
1839 if (!IsAutonomVertex( V1, cpF1, cpF2, aDS, thePaveFiller ))
1843 StartFound = Standard_True;
1845 else if (!IsAutonomVertex( V2, cpF1, cpF2, aDS, thePaveFiller ))
1849 StartFound = Standard_True;
1852 Elist.Append(anEdge);
1854 } //end of for (; itw.More(); itw.Next())
1857 itl.Initialize(Elist);
1858 StartEdge = TopoDS::Edge(itl.Value());
1860 TopoDS_Vertex V1, V2;
1861 TopExp::Vertices( StartEdge, V1, V2 );
1864 EdgesForConcat.Append( StartEdge );
1865 while (!Elist.IsEmpty())
1867 for (itl.Initialize(Elist); itl.More(); itl.Next())
1869 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
1870 TopoDS_Vertex V1, V2;
1871 TopExp::Vertices( anEdge, V1, V2 );
1872 if (V1.IsSame(StartVertex))
1875 EdgesForConcat.Append( anEdge );
1879 else if (V2.IsSame(StartVertex))
1882 EdgesForConcat.Append( anEdge );
1887 } //end of while (!Elist.IsEmpty())
1888 } //end of if (aWire.Closed())
1891 BRepTools_WireExplorer Wexp( aWire );
1892 for (; Wexp.More(); Wexp.Next())
1893 EdgesForConcat.Append( Wexp.Current() );
1896 TopoDS_Edge theEdge =
1897 AssembleEdge( pDF, cpF1, cpF2, addPCurve1, addPCurve2, EdgesForConcat );
1898 eseq.Append( theEdge );
1900 } //end of else (when TrueEdges is empty)
1902 if (eseq.Length() < L1.Extent())
1906 for (i = 1; i <= eseq.Length(); i++)
1908 TopoDS_Edge anEdge = TopoDS::Edge(eseq(i));
1909 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1910 Standard_Real EdgeTol = BRep_Tool::Tolerance(anEdge);
1912 cout<<"Tolerance of glued E = "<<EdgeTol<<endl;
1914 if (EdgeTol > 1.e-2)
1917 if (EdgeTol >= 1.e-4)
1919 ReconstructPCurves(anEdge);
1920 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1922 cout<<"After projection tol of E = "<<BRep_Tool::Tolerance(anEdge)<<endl;
1926 OrientSection( anEdge, F1, F2, O1, O2 );
1927 if (Side == TopAbs_OUT)
1929 O1 = TopAbs::Reverse(O1);
1930 O2 = TopAbs::Reverse(O2);
1933 L1.Append( anEdge.Oriented(O1) );
1934 L2.Append( anEdge.Oriented(O2) );
1937 } //end of if (L1.Extent() > 1)
1941 TopTools_ListIteratorOfListOfShape itl(L1);
1942 for (; itl.More(); itl.Next())
1944 const TopoDS_Edge& anEdge = TopoDS::Edge( itl.Value() );
1945 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1950 //=======================================================================
1951 //function : TryProject
1953 //=======================================================================
1955 Standard_Boolean BRepOffset_Tool::TryProject
1956 (const TopoDS_Face& F1,
1957 const TopoDS_Face& F2,
1958 const TopTools_ListOfShape& Edges,
1959 TopTools_ListOfShape& LInt1,
1960 TopTools_ListOfShape& LInt2,
1961 const TopAbs_State Side,
1962 const Standard_Real TolConf)
1967 char* name = new char[100];
1968 sprintf(name,"FF_%d",NbFaces++);
1969 DBRep::Set(name,F1);
1970 sprintf(name,"FF_%d",NbFaces++);
1971 DBRep::Set(name,F2);
1975 // try to find if the edges <Edges> are laying on the face F1.
1976 LInt1.Clear(); LInt2.Clear();
1977 TopTools_ListIteratorOfListOfShape it(Edges);
1978 Standard_Boolean isOk = Standard_True;
1979 Standard_Boolean Ok = Standard_True;
1980 TopAbs_Orientation O1,O2;
1981 Handle(Geom_Surface) Bouchon = BRep_Tool::Surface(F1);
1984 for ( ; it.More(); it.Next()) {
1987 TopoDS_Edge CurE = TopoDS::Edge(it.Value());
1988 Handle(Geom_Curve) C = BRep_Tool::Curve(CurE,L,f,l);
1990 BRepLib::BuildCurve3d(CurE,BRep_Tool::Tolerance(CurE));
1991 C = BRep_Tool::Curve(CurE,L,f,l);
1993 C = new Geom_TrimmedCurve(C,f,l);
1994 if ( !L.IsIdentity()) C->Transform(L);
1995 Standard_Real TolReached;
1996 isOk = IsOnSurface(C,Bouchon,TolConf,TolReached);
1999 B.UpdateEdge(CurE,TolReached);
2000 BuildPCurves(CurE,F1);
2001 OrientSection (CurE,F1,F2,O1,O2);
2002 if (Side == TopAbs_OUT) {
2003 O1 = TopAbs::Reverse(O1);
2004 O2 = TopAbs::Reverse(O2);
2006 LInt1.Append (CurE.Oriented(O1));
2007 LInt2.Append (CurE.Oriented(O2));
2011 char* name = new char[100];
2012 sprintf(name,"EI_%d",NbNewEdges++);
2013 DBRep::Set(name,CurE.Oriented(O1));
2018 Ok = Standard_False;
2024 //=======================================================================
2025 //function : InterOrExtent
2027 //=======================================================================
2029 void BRepOffset_Tool::InterOrExtent(const TopoDS_Face& F1,
2030 const TopoDS_Face& F2,
2031 TopTools_ListOfShape& L1,
2032 TopTools_ListOfShape& L2,
2033 const TopAbs_State Side)
2038 char* name = new char[100];
2039 sprintf(name,"FF_%d",NbFaces++);
2040 DBRep::Set(name,F1);
2041 sprintf(name,"FF_%d",NbFaces++);
2042 DBRep::Set(name,F2);
2046 Handle (Geom_Curve) CI;
2048 TopAbs_Orientation O1,O2;
2049 L1.Clear(); L2.Clear();
2050 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
2051 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
2053 if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2054 Handle(Geom_RectangularTrimmedSurface) RTS ;
2055 RTS = *((Handle(Geom_RectangularTrimmedSurface)*) &S1);
2056 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
2057 S1 = RTS->BasisSurface();
2060 if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2061 Handle(Geom_RectangularTrimmedSurface) RTS ;
2062 RTS = *((Handle(Geom_RectangularTrimmedSurface)*) &S2);
2063 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
2064 S2 = RTS->BasisSurface();
2068 GeomInt_IntSS Inter (S1,S2, Precision::Confusion());
2070 if (Inter.IsDone()) {
2071 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
2074 if (ToSmall(CI)) continue;
2075 TopoDS_Edge E = BRepLib_MakeEdge(CI);
2076 BuildPCurves (E,F1);
2077 BuildPCurves (E,F2);
2078 OrientSection (E,F1,F2,O1,O2);
2079 if (Side == TopAbs_OUT) {
2080 O1 = TopAbs::Reverse(O1);
2081 O2 = TopAbs::Reverse(O2);
2083 L1.Append (E.Oriented(O1));
2084 L2.Append (E.Oriented(O2));
2088 char* name = new char[100];
2089 sprintf(name,"EI_%d",NbNewEdges++);
2090 DBRep::Set(name,E.Oriented(O1));
2097 //=======================================================================
2098 //function : ExtentEdge
2100 //=======================================================================
2102 static void ExtentEdge(const TopoDS_Face& F,
2103 const TopoDS_Face& EF,
2104 const TopoDS_Edge& E,
2107 BRepAdaptor_Curve CE(E);
2108 GeomAbs_CurveType Type = CE.GetType();
2109 TopoDS_Shape aLocalEdge = E.EmptyCopied();
2110 NE = TopoDS::Edge(aLocalEdge);
2111 // NE = TopoDS::Edge(E.EmptyCopied());
2113 if (Type == GeomAbs_Line || Type == GeomAbs_Circle || Type == GeomAbs_Ellipse ||
2114 Type == GeomAbs_Hyperbola || Type == GeomAbs_Parabola) {
2117 // Extension en tangence jusqu'au bord de la surface.
2118 Standard_Real PMax = 1.e2;
2120 Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
2121 Standard_Real umin,umax,vmin,vmax;
2123 S->Bounds(umin,umax,vmin,vmax);
2124 umin = Max(umin,-PMax);vmin = Max(vmin,-PMax);
2125 umax = Min(umax, PMax);vmax = Min(vmax, PMax);
2129 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f,l);
2131 //calcul point cible . ie point d'intersection du prolongement tangent et des bords.
2134 C2d->D1(CE.FirstParameter(),P,Tang);
2135 Standard_Real tx,ty,tmin;
2136 tx = ty = Precision::Infinite();
2137 if (Abs(Tang.X()) > Precision::Confusion())
2138 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
2139 if (Abs(Tang.Y()) > Precision::Confusion())
2140 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
2143 gp_Pnt2d PF2d (P.X() - Tang.X(),P.Y() - Tang.Y());
2145 C2d->D1(CE.LastParameter(),P,Tang);
2146 tx = ty = Precision::Infinite();
2147 if (Abs(Tang.X()) > Precision::Confusion())
2148 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
2149 if (Abs(Tang.Y()) > Precision::Confusion())
2150 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
2153 gp_Pnt2d PL2d (P.X() + Tang.X(),P.Y() + Tang.Y());
2155 Handle(Geom_Curve) CC = GeomAPI::To3d(C2d,gp_Pln(gp::XOY()));
2156 gp_Pnt PF(PF2d.X(),PF2d.Y(),0.);
2157 gp_Pnt PL(PL2d.X(),PL2d.Y(),0.);
2159 Handle(Geom_BoundedCurve) ExtC = Handle(Geom_BoundedCurve)::DownCast(CC);
2160 if (ExtC.IsNull()) return;
2162 GeomLib::ExtendCurveToPoint(ExtC,PF,1,0);
2163 GeomLib::ExtendCurveToPoint(ExtC,PL,1,1);
2165 Handle(Geom2d_Curve) CNE2d = GeomAPI::To2d(ExtC,gp_Pln(gp::XOY()));
2167 //Construction de la nouvelle arrete;
2170 // B.UpdateEdge (NE,CNE2d,F,BRep_Tool::Tolerance(E));
2171 B.UpdateEdge (NE,CNE2d,EF,BRep_Tool::Tolerance(E));
2172 B.Range (NE,CNE2d->FirstParameter(), CNE2d->LastParameter());
2173 NE.Orientation(E.Orientation());
2176 char* name = new char[100];
2177 sprintf (name,"F_%d",NbExtE);
2178 DBRep::Set(name,EF);
2179 sprintf (name,"OE_%d",NbExtE);
2180 DBRep::Set (name,E);
2181 sprintf (name,"ExtE_%d",NbExtE++);
2182 DBRep::Set(name,NE);
2187 //=======================================================================
2188 //function : ProjectVertexOnEdge
2190 //=======================================================================
2192 static Standard_Boolean ProjectVertexOnEdge(TopoDS_Vertex& V,
2193 const TopoDS_Edge& E,
2194 Standard_Real TolConf)
2205 Standard_Real U = 0.;
2210 Standard_Boolean found = Standard_False;
2212 gp_Pnt P = BRep_Tool::Pnt (V);
2213 BRepAdaptor_Curve C = BRepAdaptor_Curve(E);
2214 f = C.FirstParameter(); l = C.LastParameter();
2216 if (V.Orientation() == TopAbs_FORWARD) {
2217 if (Abs(f) < Precision::Infinite()) {
2218 gp_Pnt PF = C.Value (f);
2219 if (PF.IsEqual(P,TolConf)) {
2221 found = Standard_True;
2225 if (V.Orientation() == TopAbs_REVERSED) {
2226 if (!found && Abs(l) < Precision::Infinite()) {
2227 gp_Pnt PL = C.Value (l);
2228 if (PL.IsEqual(P,TolConf)) {
2230 found = Standard_True;
2235 Extrema_ExtPC Proj(P,C);
2236 if (Proj.IsDone() && Proj.NbExt() > 0) {
2237 Standard_Real Dist2,Dist2Min = Proj.SquareDistance(1);
2238 U = Proj.Point(1).Parameter();
2239 for (Standard_Integer i = 2; i <= Proj.NbExt(); i++) {
2240 Dist2 = Proj.SquareDistance(i);
2241 if (Dist2 < Dist2Min) {
2243 U = Proj.Point(i).Parameter();
2246 found = Standard_True;
2252 Standard_Real Dist = P.Distance(C.Value(U));
2253 if (Dist > TolConf) {
2254 cout << " ProjectVertexOnEdge :distance vertex edge :"<<Dist<<endl;
2256 if (U < f - Precision::Confusion() ||
2257 U > l + Precision::Confusion()) {
2258 cout << " ProjectVertexOnEdge : hors borne :"<<endl;
2259 cout << " f = "<<f<<" l ="<<l<< " U ="<<U<<endl;
2263 cout <<"BRepOffset_Tool::ProjectVertexOnEdge Parameter no found"<<endl;
2264 if (Abs(f) < Precision::Infinite() &&
2265 Abs(l) < Precision::Infinite()) {
2273 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
2274 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
2275 aLocalShape = V.Oriented(TopAbs_INTERNAL);
2276 // TopoDS_Edge EE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
2277 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
2278 U,EE,BRep_Tool::Tolerance(E));
2284 //=======================================================================
2285 //function : Inter2d
2287 //=======================================================================
2289 void BRepOffset_Tool::Inter2d (const TopoDS_Face& F,
2290 const TopoDS_Edge& E1,
2291 const TopoDS_Edge& E2,
2292 TopTools_ListOfShape& LV,
2293 const Standard_Real TolConf)
2297 DBRep::Set("E1",E1);
2298 DBRep::Set("E2",E2);
2303 Standard_Real fl1[2],fl2[2];
2306 // Si l edge a ete etendu les pcurves ne sont pas forcement
2312 // Construction des curves 3d si elles n existent pas
2313 // utile pour coder correctement les parametres des vertex
2314 // d intersection sur les edges.
2315 //TopLoc_Location L;
2316 //Standard_Real f,l;
2317 //Handle(Geom_Curve) C3d1 = BRep_Tool::Curve(E1,L,f,l);
2318 //if (C3d1.IsNull()) {
2319 // BRepLib::BuildCurve3d(E1,BRep_Tool::Tolerance(E1));
2321 //Handle(Geom_Curve) C3d2 = BRep_Tool::Curve(E2,L,f,l);
2322 //if (C3d2.IsNull()) {
2323 // BRepLib::BuildCurve3d(E2,BRep_Tool::Tolerance(E2));
2326 Standard_Integer NbPC1 = 1, NbPC2 = 1;
2327 if (BRep_Tool::IsClosed(E1,F)) NbPC1++;
2328 if (BRep_Tool::IsClosed(E2,F)) NbPC2++;
2330 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
2331 Handle(Geom2d_Curve) C1, C2;
2332 Standard_Boolean YaSol = Standard_False;
2333 Standard_Integer itry = 0;
2335 while (!YaSol && itry < 2) {
2336 for ( Standard_Integer i = 1; i <= NbPC1 ; i++) {
2337 TopoDS_Shape aLocalEdge = E1.Reversed();
2338 if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
2339 else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdge),
2341 // if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
2342 // else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E1.Reversed()),
2343 // F,fl1[0],fl1[1]);
2344 for ( Standard_Integer j = 1; j <= NbPC2; j++ ) {
2345 TopoDS_Shape aLocalEdge = E2.Reversed();
2346 if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2347 else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdge),
2349 // if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2350 // else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E2.Reversed()),
2351 // F,fl2[0],fl2[1]);
2353 if (C1.IsNull() || C2.IsNull()) {
2354 cout <<"Inter2d : Pas de pcurve"<<endl;
2356 DBRep::Set("E1",E1);
2357 DBRep::Set("E2",E2);
2364 Standard_Real U1 = 0.,U2 = 0.;
2366 Standard_Real U1,U2;
2370 fl1[0] = C1->FirstParameter(); fl1[1] = C1->LastParameter();
2371 fl2[0] = C2->FirstParameter(); fl2[1] = C2->LastParameter();
2373 Geom2dAdaptor_Curve AC1(C1,fl1[0],fl1[1]);
2374 Geom2dAdaptor_Curve AC2(C2,fl2[0],fl2[1]);
2377 gp_Pnt2d P1[2],P2[2];
2378 P1[0] = C1->Value(fl1[0]); P1[1] = C1->Value(fl1[1]);
2379 P2[0] = C2->Value(fl2[0]); P2[1] = C2->Value(fl2[1]);
2381 Standard_Integer i1 ;
2382 for ( i1 = 0; i1 < 2; i1++) {
2383 for (Standard_Integer i2 = 0; i2 < 2; i2++) {
2384 if (Abs(fl1[i1]) < Precision::Infinite() &&
2385 Abs(fl2[i2]) < Precision::Infinite() ) {
2386 if (P1[i1].IsEqual(P2[i2],TolConf)) {
2387 YaSol = Standard_True;
2388 U1 = fl1[i1]; U2 = fl2[i2];
2389 P2d = C1->Value(U1);
2395 for (i1 = 0; i1 < 2; i1++)
2397 Extrema_ExtPC2d extr( P1[i1], AC2 );
2398 if (extr.IsDone() && extr.NbExt() > 0)
2400 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2401 Standard_Integer IndexMin = 1;
2402 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2404 Dist2 = extr.SquareDistance(ind);
2405 if (Dist2 < Dist2Min)
2411 if (Dist2Min <= Precision::Confusion() * Precision::Confusion())
2413 YaSol = Standard_True;
2416 U2 = (extr.Point(IndexMin)).Parameter();
2422 for (Standard_Integer i2 = 0; i2 < 2; i2++)
2424 Extrema_ExtPC2d extr( P2[i2], AC1 );
2425 if (extr.IsDone() && extr.NbExt() > 0)
2427 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2428 Standard_Integer IndexMin = 1;
2429 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2431 Dist2 = extr.SquareDistance(ind);
2432 if (Dist2 < Dist2Min)
2438 if (Dist2Min <= Precision::Confusion() * Precision::Confusion())
2440 YaSol = Standard_True;
2443 U1 = (extr.Point(IndexMin)).Parameter();
2451 Geom2dInt_GInter Inter (AC1,AC2,TolConf,TolConf);
2453 if (!Inter.IsEmpty() && Inter.NbPoints() > 0) {
2454 YaSol = Standard_True;
2455 U1 = Inter.Point(1).ParamOnFirst();
2456 U2 = Inter.Point(1).ParamOnSecond();
2457 P2d = Inter.Point(1).Value();
2459 else if (!Inter.IsEmpty() && Inter.NbSegments() > 0) {
2460 YaSol = Standard_True;
2461 IntRes2d_IntersectionSegment Seg = Inter.Segment(1);
2462 IntRes2d_IntersectionPoint IntP1 = Seg.FirstPoint();
2463 IntRes2d_IntersectionPoint IntP2 = Seg.LastPoint();
2464 Standard_Real U1on1 = IntP1.ParamOnFirst();
2465 Standard_Real U1on2 = IntP2.ParamOnFirst();
2466 Standard_Real U2on1 = IntP1.ParamOnSecond();
2467 Standard_Real U2on2 = IntP2.ParamOnSecond();
2469 cout << " BRepOffset_Tool::Inter2d SEGMENT d intersection" << endl;
2470 cout << " ===> Parametres sur Curve1 : ";
2471 cout << U1on1 << " " << U1on2 << endl;
2472 cout << " ===> Parametres sur Curve2 : ";
2473 cout << U2on1 << " " << U2on2 << endl;
2475 U1 = (U1on1 + U1on2)/2.;
2476 U2 = (U2on1 + U2on2)/2.;
2477 gp_Pnt2d P2d1 = C1->Value(U1);
2478 gp_Pnt2d P2d2 = C2->Value(U2);
2479 P2d.SetX( (P2d1.X() + P2d2.X()) / 2.);
2480 P2d.SetY( (P2d1.Y() + P2d2.Y()) / 2.);
2484 gp_Pnt P = S->Value(P2d.X(),P2d.Y());
2485 TopoDS_Vertex V = BRepLib_MakeVertex(P);
2486 V.Orientation(TopAbs_INTERNAL);
2487 TopoDS_Shape aLocalEdge = E1.Oriented(TopAbs_FORWARD);
2488 B.UpdateVertex(V,U1,TopoDS::Edge(aLocalEdge),TolConf);
2489 aLocalEdge = E2.Oriented(TopAbs_FORWARD);
2490 B.UpdateVertex(V,U2,TopoDS::Edge(aLocalEdge),TolConf);
2491 // B.UpdateVertex(V,U1,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)),TolConf);
2492 // B.UpdateVertex(V,U2,TopoDS::Edge(E2.Oriented(TopAbs_FORWARD)),TolConf);
2500 if (LV.Extent() > 1) {
2501 //------------------------------------------------
2502 // garde seulement les vertex les plus proches du
2503 //debut et de la fin.
2504 //------------------------------------------------
2505 TopTools_ListIteratorOfListOfShape it(LV);
2506 TopoDS_Vertex VF,VL;
2507 Standard_Real UMin = Precision::Infinite();
2508 Standard_Real UMax = -Precision::Infinite();
2511 for ( ; it.More(); it.Next()) {
2512 TopoDS_Vertex CV = TopoDS::Vertex(it.Value());
2513 TopoDS_Shape aLocalEdge = E1.Oriented(TopAbs_FORWARD);
2514 U = BRep_Tool::Parameter(CV,TopoDS::Edge(aLocalEdge));
2515 // U = BRep_Tool::Parameter(CV,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)));
2523 LV.Clear();LV.Append(VF); LV.Append(VL);
2528 cout <<"Inter2d : Pas de solution"<<endl;
2530 DBRep::Set("E1",E1);
2531 DBRep::Set("E2",E2);
2538 //=======================================================================
2539 //function : SelectEdge
2541 //=======================================================================
2543 static void SelectEdge (const TopoDS_Face& F,
2544 const TopoDS_Face& EF,
2545 const TopoDS_Edge& E,
2546 TopTools_ListOfShape& LInt)
2548 //------------------------------------------------------------
2549 // detrompeur sur les intersections sur les faces periodiques
2550 //------------------------------------------------------------
2551 TopTools_ListIteratorOfListOfShape it(LInt);
2552 Standard_Real dU = 1.0e100;
2555 Standard_Real Fst, Lst, tmp;
2556 BRep_Tool::Range(E, Fst, Lst);
2557 BRepAdaptor_Curve Ad1(E);
2559 gp_Pnt PFirst = Ad1.Value( Fst );
2560 gp_Pnt PLast = Ad1.Value( Lst );
2562 //----------------------------------------------------------------------
2563 // Selection de l edge qui couvre le plus le domaine de l edge initiale.
2564 //----------------------------------------------------------------------
2565 for (; it.More(); it.Next()) {
2566 const TopoDS_Edge& EI = TopoDS::Edge(it.Value());
2568 BRep_Tool::Range(EI, Fst, Lst);
2569 BRepAdaptor_Curve Ad2(EI);
2570 gp_Pnt P1 = Ad2.Value(Fst);
2571 gp_Pnt P2 = Ad2.Value(Lst);
2573 tmp = P1.Distance(PFirst) + P2.Distance(PLast);
2585 //=======================================================================
2588 //=======================================================================
2590 static void MakeFace(const Handle(Geom_Surface)& S,
2591 const Standard_Real Um,
2592 const Standard_Real UM,
2593 const Standard_Real Vm,
2594 const Standard_Real VM,
2595 const Standard_Boolean isVminDegen,
2596 const Standard_Boolean isVmaxDegen,
2599 Standard_Real UMin = Um;
2600 Standard_Real UMax = UM;
2601 Standard_Real VMin = Vm;
2602 Standard_Real VMax = VM;
2603 Standard_Real epsilon = Precision::Confusion();
2605 Standard_Real umin,umax,vmin,vmax;
2606 S->Bounds(umin,umax,vmin,vmax);
2609 // compute infinite flags
2610 Standard_Boolean umininf = Precision::IsNegativeInfinite(UMin);
2611 Standard_Boolean umaxinf = Precision::IsPositiveInfinite(UMax);
2612 Standard_Boolean vmininf = Precision::IsNegativeInfinite(VMin);
2613 Standard_Boolean vmaxinf = Precision::IsPositiveInfinite(VMax);
2616 Standard_Boolean IsSuclosed = S->IsUClosed(), IsSvclosed = S->IsVClosed();
2617 if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2619 Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&S))->BasisSurface();
2620 IsSuclosed = BasisSurf->IsUClosed();
2621 IsSvclosed = BasisSurf->IsVClosed();
2624 Standard_Boolean uclosed =
2626 Abs(UMin - umin) < epsilon &&
2627 Abs(UMax - umax) < epsilon;
2629 Standard_Boolean vclosed =
2631 Abs(VMin - vmin) < epsilon &&
2632 Abs(VMax - vmax) < epsilon;
2634 // degenerated flags (for cones)
2635 Standard_Boolean vmindegen = isVminDegen, vmaxdegen = isVmaxDegen;
2636 Handle(Geom_Surface) theSurf = S;
2637 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
2638 theSurf = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface();
2639 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
2641 Handle(Geom_ConicalSurface) ConicalS = *((Handle(Geom_ConicalSurface)*) &theSurf);
2642 gp_Cone theCone = ConicalS->Cone();
2643 gp_Pnt theApex = theCone.Apex();
2644 Standard_Real Uapex, Vapex;
2645 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
2646 if (Abs(VMin - Vapex) <= Precision::Confusion())
2647 vmindegen = Standard_True;
2648 if (Abs(VMax - Vapex) <= Precision::Confusion())
2649 vmaxdegen = Standard_True;
2654 Standard_Real tol = Precision::Confusion();
2656 TopoDS_Vertex V00,V10,V11,V01;
2659 if (!vmininf) B.MakeVertex(V00,S->Value(UMin,VMin),tol);
2660 if (!vmaxinf) B.MakeVertex(V01,S->Value(UMin,VMax),tol);
2663 if (!vmininf) B.MakeVertex(V10,S->Value(UMax,VMin),tol);
2664 if (!vmaxinf) B.MakeVertex(V11,S->Value(UMax,VMax),tol);
2683 Handle(Geom2d_Line) Lumin,Lumax,Lvmin,Lvmax;
2685 Lumin = new Geom2d_Line(gp_Pnt2d(UMin,0),gp_Dir2d(0,1));
2687 Lumax = new Geom2d_Line(gp_Pnt2d(UMax,0),gp_Dir2d(0,1));
2689 Lvmin = new Geom2d_Line(gp_Pnt2d(0,VMin),gp_Dir2d(1,0));
2691 Lvmax = new Geom2d_Line(gp_Pnt2d(0,VMax),gp_Dir2d(1,0));
2693 Handle(Geom_Curve) Cumin,Cumax,Cvmin,Cvmax;
2694 Standard_Real TolApex = 1.e-5;
2695 //Standard_Boolean hasiso = ! S->IsKind(STANDARD_TYPE(Geom_OffsetSurface));
2696 Standard_Boolean hasiso = S->IsKind(STANDARD_TYPE(Geom_ElementarySurface));
2699 Cumin = S->UIso(UMin);
2701 Cumax = S->UIso(UMax);
2704 Cvmin = S->VIso(VMin);
2705 if (BRepOffset_Tool::Gabarit( Cvmin ) <= TolApex)
2706 vmindegen = Standard_True;
2710 Cvmax = S->VIso(VMax);
2711 if (BRepOffset_Tool::Gabarit( Cvmax ) <= TolApex)
2712 vmaxdegen = Standard_True;
2717 B.MakeFace(F,S,tol);
2720 TopoDS_Edge eumin,eumax,evmin,evmax;
2724 B.MakeEdge(eumin,Cumin,tol);
2728 B.UpdateEdge(eumin,Lumax,Lumin,F,tol);
2730 B.UpdateEdge(eumin,Lumin,F,tol);
2732 V00.Orientation(TopAbs_FORWARD);
2736 V01.Orientation(TopAbs_REVERSED);
2739 B.Range(eumin,VMin,VMax);
2747 B.MakeEdge(eumax,Cumax,tol);
2750 B.UpdateEdge(eumax,Lumax,F,tol);
2752 V10.Orientation(TopAbs_FORWARD);
2756 V11.Orientation(TopAbs_REVERSED);
2759 B.Range(eumax,VMin,VMax);
2764 if (hasiso && !vmindegen)
2765 B.MakeEdge(evmin,Cvmin,tol);
2769 B.UpdateEdge(evmin,Lvmin,Lvmax,F,tol);
2771 B.UpdateEdge(evmin,Lvmin,F,tol);
2773 V00.Orientation(TopAbs_FORWARD);
2777 V10.Orientation(TopAbs_REVERSED);
2780 B.Range(evmin,UMin,UMax);
2782 B.Degenerated(evmin, Standard_True);
2789 if (hasiso && !vmaxdegen)
2790 B.MakeEdge(evmax,Cvmax,tol);
2793 B.UpdateEdge(evmax,Lvmax,F,tol);
2795 V01.Orientation(TopAbs_FORWARD);
2799 V11.Orientation(TopAbs_REVERSED);
2802 B.Range(evmax,UMin,UMax);
2804 B.Degenerated(evmax, Standard_True);
2808 // make the wires and add them to the face
2809 eumin.Orientation(TopAbs_REVERSED);
2810 evmax.Orientation(TopAbs_REVERSED);
2814 if (!umininf && !umaxinf && vmininf && vmaxinf) {
2825 else if (umininf && umaxinf && !vmininf && !vmaxinf) {
2836 else if (!umininf || !umaxinf || !vmininf || !vmaxinf) {
2839 if (!umininf) B.Add(W,eumin);
2840 if (!vmininf) B.Add(W,evmin);
2841 if (!umaxinf) B.Add(W,eumax);
2842 if (!vmaxinf) B.Add(W,evmax);
2844 W.Closed(!umininf && !umaxinf && !vmininf && !vmaxinf);
2845 F.Closed(uclosed && vclosed);
2849 //=======================================================================
2850 //function : EnLargeGeometry
2852 //=======================================================================
2854 static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S,
2859 Standard_Boolean& IsV1degen,
2860 Standard_Boolean& IsV2degen,
2861 const Standard_Real uf1,
2862 const Standard_Real uf2,
2863 const Standard_Real vf1,
2864 const Standard_Real vf2,
2865 const Standard_Boolean GlobalEnlargeU,
2866 const Standard_Boolean GlobalEnlargeVfirst,
2867 const Standard_Boolean GlobalEnlargeVlast)
2869 const Standard_Real coeff = 4.;
2870 const Standard_Real TolApex = 1.e-5;
2872 Standard_Boolean SurfaceChange = Standard_False;
2873 if ( S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2874 Handle(Geom_Surface) BS = (*((Handle(Geom_RectangularTrimmedSurface)*)&S))->BasisSurface();
2875 EnlargeGeometry(BS,U1,U2,V1,V2,IsV1degen,IsV2degen,
2876 uf1,uf2,vf1,vf2,GlobalEnlargeU,GlobalEnlargeVfirst,GlobalEnlargeVlast);
2877 if (!GlobalEnlargeVfirst)
2879 if (!GlobalEnlargeVlast)
2881 if (!GlobalEnlargeVfirst || !GlobalEnlargeVlast)
2882 //(*((Handle(Geom_RectangularTrimmedSurface)*)&S))->SetTrim( U1, U2, V1, V2 );
2883 S = new Geom_RectangularTrimmedSurface( BS, U1, U2, V1, V2 );
2886 SurfaceChange = Standard_True;
2888 else if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)) {
2889 Handle(Geom_Surface) Surf = (*((Handle(Geom_OffsetSurface)*)&S))->BasisSurface();
2890 SurfaceChange = EnlargeGeometry(Surf,U1,U2,V1,V2,IsV1degen,IsV2degen,
2891 uf1,uf2,vf1,vf2,GlobalEnlargeU,GlobalEnlargeVfirst,GlobalEnlargeVlast);
2892 Handle(Geom_OffsetSurface)::DownCast(S)->SetBasisSurface(Surf);
2894 else if (S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
2895 S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution))
2897 Standard_Real du=0., dv=0.;
2898 Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
2899 Standard_Real u1, u2, v1, v2;
2900 Standard_Boolean enlargeU = GlobalEnlargeU, enlargeV = Standard_True;
2901 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2902 Standard_Boolean enlargeVfirst = GlobalEnlargeVfirst, enlargeVlast = GlobalEnlargeVlast;
2903 S->Bounds( u1, u2, v1, v2 );
2904 if (Precision::IsInfinite(u1) || Precision::IsInfinite(u2))
2909 enlargeU = Standard_False;
2911 else if (S->IsUClosed())
2912 enlargeU = Standard_False;
2915 viso = S->VIso( vf1 );
2916 GeomAdaptor_Curve gac( viso );
2917 du = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2918 uiso1 = S->UIso( uf1 );
2919 uiso2 = S->UIso( uf2 );
2920 if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
2921 enlargeUfirst = Standard_False;
2922 if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
2923 enlargeUlast = Standard_False;
2925 if (Precision::IsInfinite(v1) || Precision::IsInfinite(v2))
2930 enlargeV = Standard_False;
2932 else if (S->IsVClosed())
2933 enlargeV = Standard_False;
2936 uiso = S->UIso( uf1 );
2937 GeomAdaptor_Curve gac( uiso );
2938 dv = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2939 viso1 = S->VIso( vf1 );
2940 viso2 = S->VIso( vf2 );
2941 if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
2943 enlargeVfirst = Standard_False;
2944 IsV1degen = Standard_True;
2946 if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
2948 enlargeVlast = Standard_False;
2949 IsV2degen = Standard_True;
2952 S = new Geom_RectangularTrimmedSurface( S, u1, u2, v1, v2 );
2956 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), du, 1, Standard_True, Standard_False );
2958 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), du, 1, Standard_True, Standard_True );
2963 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), dv, 1, Standard_False, Standard_False );
2965 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), dv, 1, Standard_False, Standard_True );
2967 S->Bounds( U1, U2, V1, V2 );
2968 SurfaceChange = Standard_True;
2970 else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
2971 S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
2973 Standard_Boolean enlargeU = GlobalEnlargeU, enlargeV = Standard_True;
2974 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2975 Standard_Boolean enlargeVfirst = GlobalEnlargeVfirst, enlargeVlast = GlobalEnlargeVlast;
2977 enlargeU = Standard_False;
2979 enlargeV = Standard_False;
2981 Standard_Real duf = uf2-uf1, dvf = vf2-vf1;
2982 Standard_Real u1, u2, v1, v2;
2983 S->Bounds( u1, u2, v1, v2 );
2985 Standard_Real du=0., dv=0.;
2986 Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
2987 GeomAdaptor_Curve gac;
2990 viso = S->VIso( v1 );
2992 du = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2993 uiso1 = S->UIso( u1 );
2994 uiso2 = S->UIso( u2 );
2995 if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
2996 enlargeUfirst = Standard_False;
2997 if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
2998 enlargeUlast = Standard_False;
3002 uiso = S->UIso( u1 );
3004 dv = GCPnts_AbscissaPoint::Length( gac ) / coeff;
3005 viso1 = S->VIso( v1 );
3006 viso2 = S->VIso( v2 );
3007 if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
3009 enlargeVfirst = Standard_False;
3010 IsV1degen = Standard_True;
3012 if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
3014 enlargeVlast = Standard_False;
3015 IsV2degen = Standard_True;
3021 if (enlargeUfirst && uf1-u1 < duf)
3022 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), du, 1, Standard_True, Standard_False );
3023 if (enlargeUlast && u2-uf2 < duf)
3024 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), du, 1, Standard_True, Standard_True );
3028 if (enlargeVfirst && vf1-v1 < dvf)
3029 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), dv, 1, Standard_False, Standard_False );
3030 if (enlargeVlast && v2-vf2 < dvf)
3031 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), dv, 1, Standard_False, Standard_True );
3034 S->Bounds( U1, U2, V1, V2 );
3035 SurfaceChange = Standard_True;
3037 // else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
3038 // S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface)) {
3039 // S->Bounds(U1,U2,V1,V2);
3042 Standard_Real UU1,UU2,VV1,VV2;
3043 S->Bounds(UU1,UU2,VV1,VV2);
3044 // Pas d extension au dela des bornes de la surface.
3050 return SurfaceChange;
3053 //=======================================================================
3054 //function : UpDatePCurve
3055 //purpose : Mise a jour des pcurves de F sur la surface de de BF.
3056 // F and BF has to be FORWARD,
3057 //=======================================================================
3059 static void UpdatePCurves (const TopoDS_Face& F,
3065 TopTools_IndexedMapOfShape Emap;
3066 Handle(Geom2d_Curve) NullPCurve;
3068 TopExp::MapShapes( F, TopAbs_EDGE, Emap );
3070 for (i = 1; i <= Emap.Extent(); i++)
3072 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
3073 CE.Orientation( TopAbs_FORWARD );
3074 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface( CE, F, f, l );
3077 if (BRep_Tool::IsClosed( CE, F ))
3080 Handle(Geom2d_Curve) C2R = BRep_Tool::CurveOnSurface( CE, F, f, l );
3081 B.UpdateEdge( CE, NullPCurve, NullPCurve, F, BRep_Tool::Tolerance(CE) );
3082 B.UpdateEdge( CE, C2, C2R, BF, BRep_Tool::Tolerance(CE) );
3086 B.UpdateEdge( CE, NullPCurve, F, BRep_Tool::Tolerance(CE) );
3087 B.UpdateEdge( CE, C2, BF, BRep_Tool::Tolerance(CE) );
3095 //=======================================================================
3096 //function :CompactUVBounds
3098 //=======================================================================
3100 static void CompactUVBounds (const TopoDS_Face& F,
3101 Standard_Real& UMin,
3102 Standard_Real& UMax,
3103 Standard_Real& VMin,
3104 Standard_Real& VMax)
3106 // Calcul serre pour que les bornes ne couvrent pas plus d une periode
3107 Standard_Real U1,U2;
3108 Standard_Real N = 33;
3111 TopExp_Explorer exp;
3112 for (exp.Init(F, TopAbs_EDGE); exp.More(); exp.Next()) {
3113 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3114 BRepAdaptor_Curve2d C(E,F);
3115 BRep_Tool::Range(E,U1,U2);
3117 Standard_Real U = U1;
3118 Standard_Real DU = (U2-U1)/(N-1);
3119 for (Standard_Integer j=1;j<N;j++) {
3127 B.Get(UMin,VMin,UMax,VMax);
3130 //=======================================================================
3131 //function : CheckBounds
3133 //=======================================================================
3135 void BRepOffset_Tool::CheckBounds(const TopoDS_Face& F,
3136 const BRepOffset_Analyse& Analyse,
3137 Standard_Boolean& enlargeU,
3138 Standard_Boolean& enlargeVfirst,
3139 Standard_Boolean& enlargeVlast)
3141 enlargeU = Standard_True;
3142 enlargeVfirst = Standard_True; enlargeVlast = Standard_True;
3144 Standard_Integer Ubound = 0, Vbound = 0;
3145 Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
3146 Standard_Real Vfirst = RealLast(), Vlast = RealFirst();
3148 Standard_Real UF1,UF2,VF1,VF2;
3149 CompactUVBounds(F,UF1,UF2,VF1,VF2);
3151 Handle(Geom_Surface) theSurf = BRep_Tool::Surface(F);
3152 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
3153 theSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&theSurf))->BasisSurface();
3155 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
3156 theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution) ||
3157 theSurf->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
3158 theSurf->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
3160 TopExp_Explorer Explo(F, TopAbs_EDGE);
3161 for (; Explo.More(); Explo.Next())
3163 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
3164 const BRepOffset_ListOfInterval& L = Analyse.Type(anEdge);
3165 if (!L.IsEmpty() || BRep_Tool::Degenerated(anEdge))
3167 BRepOffset_Type OT = L.First().Type();
3168 if (OT == BRepOffset_Tangent || BRep_Tool::Degenerated(anEdge))
3170 Standard_Real fpar, lpar;
3171 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, F, fpar, lpar);
3172 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
3173 aCurve = (*((Handle(Geom2d_TrimmedCurve)*)&aCurve))->BasisCurve();
3175 Handle(Geom2d_Line) theLine;
3176 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_Line))
3177 theLine = *((Handle(Geom2d_Line)*)&aCurve);
3178 else if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BezierCurve) ||
3179 aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BSplineCurve))
3181 Standard_Real newFpar, newLpar, deviation;
3182 theLine = ShapeCustom_Curve2d::ConvertToLine2d(aCurve, fpar, lpar, Precision::Confusion(),
3183 newFpar, newLpar, deviation);
3186 if (!theLine.IsNull())
3188 gp_Dir2d theDir = theLine->Direction();
3189 if (theDir.IsParallel( gp::DX2d(), Precision::Angular() ))
3192 if (BRep_Tool::Degenerated(anEdge))
3194 if (Abs(theLine->Location().Y() - VF1) <= Precision::Confusion())
3195 enlargeVfirst = Standard_False;
3196 else //theLine->Location().Y() is near VF2
3197 enlargeVlast = Standard_False;
3201 if (theLine->Location().Y() < Vfirst)
3202 Vfirst = theLine->Location().Y();
3203 if (theLine->Location().Y() > Vlast)
3204 Vlast = theLine->Location().Y();
3207 else if (theDir.IsParallel( gp::DY2d(), Precision::Angular() ))
3210 if (theLine->Location().X() < Ufirst)
3211 Ufirst = theLine->Location().X();
3212 if (theLine->Location().X() > Ulast)
3213 Ulast = theLine->Location().X();
3221 if (Ubound >= 2 || Vbound >= 2)
3224 Abs(UF1-Ufirst) <= Precision::Confusion() &&
3225 Abs(UF2-Ulast) <= Precision::Confusion())
3226 enlargeU = Standard_False;
3228 Abs(VF1-Vfirst) <= Precision::Confusion() &&
3229 Abs(VF2-Vlast) <= Precision::Confusion())
3231 enlargeVfirst = Standard_False;
3232 enlargeVlast = Standard_False;
3237 //=======================================================================
3238 //function : EnLargeFace
3240 //=======================================================================
3242 Standard_Boolean BRepOffset_Tool::EnLargeFace
3243 (const TopoDS_Face& F,
3245 const Standard_Boolean CanExtentSurface,
3246 const Standard_Boolean UpdatePCurve,
3247 const Standard_Boolean enlargeU,
3248 const Standard_Boolean enlargeVfirst,
3249 const Standard_Boolean enlargeVlast)
3251 //---------------------------
3252 // extension de la geometrie.
3253 //---------------------------
3255 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
3256 Standard_Real UU1,VV1,UU2,VV2;
3257 Standard_Boolean isVV1degen = Standard_False, isVV2degen = Standard_False;
3258 Standard_Real US1,VS1,US2,VS2;
3259 Standard_Real UF1,VF1,UF2,VF2;
3260 Standard_Real infini = 1.e8;
3261 Standard_Boolean SurfaceChange = Standard_False;
3263 if (S->IsUPeriodic() || S->IsVPeriodic()) {
3264 // Calcul serre pour que les bornes ne couvre pas plus d une periode
3265 CompactUVBounds(F,UF1,UF2,VF1,VF2);
3268 BRepTools::UVBounds(F,UF1,UF2,VF1,VF2);
3271 S->Bounds (US1,US2,VS1,VS2);
3272 UU1 = VV1 = - infini;
3275 if (CanExtentSurface) {
3276 SurfaceChange = EnlargeGeometry( S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2,
3277 enlargeU, enlargeVfirst, enlargeVlast );
3280 UU1 = Max(US1,UU1); UU2 = Min(UU2,US2);
3281 VV1 = Max(VS1,VV1); VV2 = Min(VS2,VV2);
3284 if (S->IsUPeriodic()) {
3285 Standard_Real Period = S->UPeriod();
3286 Standard_Real Delta = Period - (UF2 - UF1);
3287 Standard_Real alpha = 0.1;
3288 UU1 = UF1 - alpha*Delta; UU2 = UF2 + alpha*Delta;
3289 if ((UU2 - UU1) > Period) {
3293 if (S->IsVPeriodic()) {
3294 Standard_Real Period = S->VPeriod();
3295 Standard_Real Delta = Period - (VF2 - VF1);
3296 Standard_Real alpha = 0.1;
3297 VV1 = VF1 - alpha*Delta; VV2 = VF2 + alpha*Delta;
3298 if ((VV2 - VV1) > Period) {
3303 //Special treatment for conical surfaces
3304 Handle(Geom_Surface) theSurf = S;
3305 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
3306 theSurf = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface();
3307 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
3309 Handle(Geom_ConicalSurface) ConicalS = *((Handle(Geom_ConicalSurface)*) &theSurf);
3310 gp_Cone theCone = ConicalS->Cone();
3311 gp_Pnt theApex = theCone.Apex();
3312 Standard_Real Uapex, Vapex;
3313 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
3314 if (VV1 < Vapex && Vapex < VV2)
3316 //consider that VF1 and VF2 are on the same side from apex
3317 Standard_Real TolApex = 1.e-5;
3318 if (Vapex - VF1 >= TolApex ||
3319 Vapex - VF2 >= TolApex) //if (VF1 < Vapex || VF2 < Vapex)
3328 UU1 = UF1; UU2 = UF2;
3335 MakeFace(S,UU1,UU2,VV1,VV2,isVV1degen,isVV2degen,BF);
3338 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
3340 //----------------------------------------------------------------
3341 // utile pour les bouchons on ne doit pas changer leur geometrie.
3342 // (Ce que fait BRepLib_MakeFace si S est restreinte).
3343 // On remet S et on update les pcurves.
3344 //----------------------------------------------------------------
3345 TopExp_Explorer exp;
3346 exp.Init(BF,TopAbs_EDGE);
3347 Standard_Real f=0.,l=0.;
3348 for (; exp.More(); exp.Next()) {
3349 TopoDS_Edge CE = TopoDS::Edge(exp.Current());
3350 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,BF,f,l);
3351 B.UpdateEdge (CE,C2,S,L,BRep_Tool::Tolerance(CE));
3353 B.UpdateFace(BF,S,L,BRep_Tool::Tolerance(F));
3356 if (SurfaceChange && UpdatePCurve) {
3357 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3358 UpdatePCurves(TopoDS::Face(aLocalFace),BF);
3359 //UpdatePCurves(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),BF);
3361 BB.UpdateFace( F, S, L, BRep_Tool::Tolerance(F) );
3364 BF.Orientation(F.Orientation());
3365 return SurfaceChange;
3368 //=======================================================================
3369 //function : TryParameter
3371 //=======================================================================
3373 static Standard_Boolean TryParameter (const TopoDS_Edge& OE,
3375 const TopoDS_Edge& NE,
3376 Standard_Real TolConf)
3378 BRepAdaptor_Curve OC(OE);
3379 BRepAdaptor_Curve NC(NE);
3380 Standard_Real Of = OC.FirstParameter(); Standard_Real Ol = OC.LastParameter();
3381 Standard_Real Nf = NC.FirstParameter(); Standard_Real Nl = NC.LastParameter();
3383 Standard_Real U = 0.;
3387 gp_Pnt P = BRep_Tool::Pnt(V);
3388 Standard_Boolean OK = Standard_False;
3390 if (P.Distance(OC.Value(Of)) < TolConf) {
3391 if (Of > Nf && Of < Nl && P.Distance(NC.Value(Of)) < TolConf) {
3396 if (P.Distance(OC.Value(Ol)) < TolConf) {
3397 if (Ol > Nf && Ol < Nl && P.Distance(NC.Value(Ol)) < TolConf) {
3404 TopoDS_Shape aLocalShape = NE.Oriented(TopAbs_FORWARD);
3405 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
3406 // TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD));
3407 aLocalShape = V.Oriented(TopAbs_INTERNAL);
3408 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
3409 U,NE,BRep_Tool::Tolerance(NE));
3410 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
3411 // U,NE,BRep_Tool::Tolerance(NE));
3416 //=======================================================================
3419 //=======================================================================
3421 void BRepOffset_Tool::MapVertexEdges (const TopoDS_Shape& S,
3422 TopTools_DataMapOfShapeListOfShape& MEV)
3424 TopExp_Explorer exp;
3425 exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3426 TopTools_MapOfShape DejaVu;
3427 for ( ; exp.More(); exp.Next()) {
3428 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3429 if (DejaVu.Add(E)) {
3430 TopoDS_Vertex V1,V2;
3431 TopExp::Vertices (E,V1,V2);
3432 if (!MEV.IsBound(V1)) {
3433 TopTools_ListOfShape empty;
3437 if (!V1.IsSame(V2)) {
3438 if (!MEV.IsBound(V2)) {
3439 TopTools_ListOfShape empty;
3448 //=======================================================================
3451 //=======================================================================
3453 void BRepOffset_Tool::BuildNeighbour (const TopoDS_Wire& W,
3454 const TopoDS_Face& F,
3455 TopTools_DataMapOfShapeShape& NOnV1,
3456 TopTools_DataMapOfShapeShape& NOnV2)
3458 TopoDS_Vertex V1,V2,VP1,VP2,FV1,FV2;
3459 TopoDS_Edge CurE,FirstE,PrecE;
3460 BRepTools_WireExplorer wexp;
3462 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3463 TopoDS_Shape aLocalWire = W.Oriented(TopAbs_FORWARD);
3464 wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
3465 // wexp.Init(TopoDS::Wire(W.Oriented(TopAbs_FORWARD)),
3466 // TopoDS::Face(F.Oriented(TopAbs_FORWARD)));
3467 CurE = FirstE = PrecE = wexp.Current();
3468 TopExp::Vertices(CurE,V1,V2);
3469 FV1 = VP1 = V1; FV2 = VP2 = V2;
3471 while (wexp.More()) {
3472 CurE = wexp.Current();
3473 TopExp::Vertices(CurE,V1,V2);
3474 if (V1.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3475 if (V1.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3476 if (V2.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3477 if (V2.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3482 if (V1.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3483 if (V1.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3484 if (V2.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3485 if (V2.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3488 //=======================================================================
3489 //function : ExtentFace
3491 //=======================================================================
3493 void BRepOffset_Tool::ExtentFace (const TopoDS_Face& F,
3494 TopTools_DataMapOfShapeShape& ConstShapes,
3495 TopTools_DataMapOfShapeShape& ToBuild,
3496 const TopAbs_State Side,
3497 const Standard_Real TolConf,
3503 char* name = new char[100];
3504 sprintf(name,"FTE_%d",NbFTE++);
3509 TopExp_Explorer exp,exp2;
3510 TopTools_DataMapOfShapeShape Build;
3511 TopTools_DataMapOfShapeShape Extent;
3512 TopoDS_Edge FirstE,PrecE,CurE,NE;
3516 // Construction de la boite englobante de la face a etendre et des bouchons pour
3517 // limiter les extensions.
3518 //Bnd_Box ContextBox;
3519 //BRepBndLib::Add(F,B);
3520 //TopTools_DataMapIteratorOfDataMapOfShape itTB(ToBuild);
3521 //for (; itTB.More(); itTB.Next()) {
3522 //BRepBndLib::Add(TopBuild.Value(), ContextBox);
3526 Standard_Boolean SurfaceChange;
3527 SurfaceChange = EnLargeFace (F,EF,Standard_True);
3529 TopoDS_Shape aLocalShape = EF.EmptyCopied();
3530 NF = TopoDS::Face(aLocalShape);
3531 // NF = TopoDS::Face(EF.EmptyCopied());
3532 NF.Orientation(TopAbs_FORWARD);
3534 if (SurfaceChange) {
3535 //------------------------------------------------
3536 // Mise a jour des pcurves sur la surface de base.
3537 //------------------------------------------------
3538 TopoDS_Face Fforward = F;
3539 Fforward.Orientation(TopAbs_FORWARD);
3540 TopTools_IndexedMapOfShape Emap;
3541 TopExp::MapShapes( Fforward, TopAbs_EDGE, Emap );
3543 for (Standard_Integer i = 1; i <= Emap.Extent(); i++) {
3544 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
3545 CE.Orientation(TopAbs_FORWARD);
3546 TopoDS_Edge Ecs; //patch
3547 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,Fforward,f,l);
3549 if (ConstShapes.IsBound(CE)) {
3550 Ecs = TopoDS::Edge(ConstShapes(CE));
3551 BRep_Tool::Range(Ecs,f,l);
3553 if (BRep_Tool::IsClosed(CE,Fforward)) {
3554 TopoDS_Shape aLocalShape = CE.Reversed();
3555 Handle(Geom2d_Curve) C2R =
3556 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),Fforward,f,l);
3557 // Handle(Geom2d_Curve) C2R =
3558 // BRep_Tool::CurveOnSurface(TopoDS::Edge(CE.Reversed()),F,f,l);
3559 B.UpdateEdge (CE,C2,C2R,EF,BRep_Tool::Tolerance(CE));
3561 B.UpdateEdge (Ecs,C2,C2R,EF,BRep_Tool::Tolerance(CE));
3564 B.UpdateEdge (CE,C2,EF,BRep_Tool::Tolerance(CE));
3566 B.UpdateEdge (Ecs,C2,EF,BRep_Tool::Tolerance(CE));
3575 for (exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
3578 const TopoDS_Wire& W = TopoDS::Wire(exp.Current());
3579 TopTools_DataMapOfShapeListOfShape MVE; // Vertex -> Edges incidentes.
3580 TopTools_DataMapOfShapeShape NOnV1;
3581 TopTools_DataMapOfShapeShape NOnV2;
3583 MapVertexEdges (W,MVE);
3584 BuildNeighbour (W,F,NOnV1,NOnV2);
3586 TopTools_ListOfShape LInt1,LInt2;
3587 TopoDS_Face StopFace;
3588 //------------------------------------------------
3589 // Construction edges
3590 //------------------------------------------------
3591 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3592 exp2.More(); exp2.Next()) {
3593 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3594 if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
3595 if (ToBuild.IsBound(E)) {
3596 TopTools_ListOfShape LOE;
3598 BRepOffset_Tool::TryProject (TopoDS::Face(ToBuild(E)),
3599 EF,LOE,LInt2,LInt1,Side,TolConf);
3600 if (!LInt1.IsEmpty())
3605 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3606 exp2.More(); exp2.Next()) {
3607 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3608 if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
3609 if (ToBuild.IsBound(E)) {
3610 EnLargeFace(TopoDS::Face(ToBuild(E)),StopFace,Standard_False);
3611 BRepOffset_Tool::Inter3D (EF,StopFace,LInt1,LInt2,Side,E,Standard_True);
3612 if (LInt1.Extent() > 1) {
3613 // l intersection est en plusieurs edges (franchissement de couture)
3614 SelectEdge (F,EF,E,LInt1);
3616 NE = TopoDS::Edge(LInt1.First());
3617 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &NE.TShape());
3618 TE->Tolerance( TE->Tolerance()*10. ); //????
3619 if (NE.Orientation() == E.Orientation()) {
3620 Build.Bind(E,NE.Oriented(TopAbs_FORWARD));
3623 Build.Bind(E,NE.Oriented(TopAbs_REVERSED));
3625 const TopoDS_Edge& EOnV1 = TopoDS::Edge(NOnV1(E));
3626 if (!ToBuild .IsBound(EOnV1) &&
3627 !ConstShapes.IsBound(EOnV1) &&
3628 !Build .IsBound(EOnV1)) {
3629 ExtentEdge (F,EF,EOnV1,NE);
3630 Build.Bind (EOnV1,NE.Oriented(TopAbs_FORWARD));
3632 const TopoDS_Edge& EOnV2 = TopoDS::Edge(NOnV2(E));
3633 if (!ToBuild .IsBound(EOnV2) &&
3634 !ConstShapes.IsBound(EOnV2) &&
3635 !Build .IsBound(EOnV2)) {
3636 ExtentEdge (F,EF,EOnV2,NE);
3637 Build.Bind (EOnV2,NE.Oriented (TopAbs_FORWARD));
3642 //------------------------------------------------
3643 // Construction Vertex.
3644 //------------------------------------------------
3645 TopTools_ListOfShape LV;
3648 TopoDS_Vertex V1,V2;
3650 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3651 exp2.More(); exp2.Next()) {
3652 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3653 TopExp::Vertices (E,V1,V2);
3654 BRep_Tool::Range (E,f,l);
3656 if (Build.IsBound(E)) {
3657 const TopoDS_Edge& NEOnV1 = TopoDS::Edge(NOnV1(E));
3658 if (Build.IsBound(NEOnV1) &&
3659 (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV1))) {
3660 if (E.IsSame(NEOnV1))
3661 V = TopExp::FirstVertex(TopoDS::Edge(Build(E)));
3666 if (!Build.IsBound(V1)) {
3667 Inter2d (EF,TopoDS::Edge(Build(E)),
3668 TopoDS::Edge(Build(NEOnV1)),LV,/*TolConf*/Precision::Confusion());
3669 if (Build(E).Orientation() == TopAbs_FORWARD) {
3670 V = TopoDS::Vertex(LV.First());
3673 V = TopoDS::Vertex(LV.Last());
3677 V = TopoDS::Vertex(Build(V1));
3678 if (MVE (V1).Extent() > 2) {
3679 V.Orientation(TopAbs_FORWARD);
3680 if (Build(E).Orientation() == TopAbs_REVERSED)
3681 V.Orientation(TopAbs_REVERSED);
3682 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3692 if (ConstShapes.IsBound(V1)) V = TopoDS::Vertex(ConstShapes(V1));
3693 V.Orientation(TopAbs_FORWARD);
3694 if (Build(E).Orientation() == TopAbs_REVERSED)
3695 V.Orientation(TopAbs_REVERSED);
3696 if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
3697 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3699 ConstShapes.Bind(V1,V);
3701 const TopoDS_Edge& NEOnV2 = TopoDS::Edge(NOnV2(E));
3702 if (Build.IsBound(NEOnV2) &&
3703 (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV2))) {
3704 if (E.IsSame(NEOnV2))
3705 V = TopExp::LastVertex(TopoDS::Edge(Build(E)));
3710 if (!Build.IsBound(V2)) {
3711 Inter2d (EF,TopoDS::Edge(Build(E)),
3712 TopoDS::Edge(Build(NEOnV2)),LV,/*TolConf*/Precision::Confusion());
3713 if (Build(E).Orientation() == TopAbs_FORWARD) {
3714 V = TopoDS::Vertex(LV.Last());
3717 V = TopoDS::Vertex(LV.First());
3721 V = TopoDS::Vertex(Build(V2));
3722 if (MVE (V2).Extent() > 2) {
3723 V.Orientation(TopAbs_REVERSED);
3724 if (Build(E).Orientation() == TopAbs_REVERSED)
3725 V.Orientation(TopAbs_FORWARD);
3726 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3736 if (ConstShapes.IsBound(V2)) V = TopoDS::Vertex(ConstShapes(V2));
3737 V.Orientation(TopAbs_REVERSED);
3738 if (Build(E).Orientation() == TopAbs_REVERSED)
3739 V.Orientation(TopAbs_FORWARD);
3740 if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
3741 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3743 ConstShapes.Bind(V2,V);
3749 TopoDS_Vertex NV1,NV2;
3750 TopAbs_Orientation Or;
3751 Standard_Real U1,U2;
3752 Standard_Real eps = Precision::Confusion();
3762 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3763 exp2.More(); exp2.Next()) {
3764 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3765 TopExp::Vertices (E,V1,V2);
3766 if (Build.IsBound(E)) {
3767 NE = TopoDS::Edge(Build(E));
3768 BRep_Tool::Range(NE,f,l);
3769 Or = NE.Orientation();
3770 //-----------------------------------------------------
3771 // Copy pour virer les vertex deja sur la nouvelle edge.
3772 //-----------------------------------------------------
3773 NV1 = TopoDS::Vertex(ConstShapes(V1));
3774 NV2 = TopoDS::Vertex(ConstShapes(V2));
3776 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_INTERNAL);
3777 TopoDS_Shape aLocalEdge = NE.Oriented(TopAbs_INTERNAL);
3779 U1 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalVertex),
3780 TopoDS::Edge (aLocalEdge));
3781 aLocalVertex = NV2.Oriented(TopAbs_INTERNAL);
3782 aLocalEdge = NE.Oriented(TopAbs_FORWARD);
3783 U2 = BRep_Tool::Parameter
3784 (TopoDS::Vertex(aLocalVertex),TopoDS::Edge (aLocalEdge));
3785 // U1 = BRep_Tool::Parameter
3786 // (TopoDS::Vertex(NV1.Oriented(TopAbs_INTERNAL)),
3787 // TopoDS::Edge (NE .Oriented(TopAbs_FORWARD)));
3788 // U2 = BRep_Tool::Parameter
3789 // (TopoDS::Vertex(NV2.Oriented(TopAbs_INTERNAL)),
3790 // TopoDS::Edge (NE.Oriented(TopAbs_FORWARD)));
3791 aLocalEdge = NE.EmptyCopied();
3792 NE = TopoDS::Edge(aLocalEdge);
3793 NE.Orientation(TopAbs_FORWARD);
3794 if (NV1.IsSame(NV2))
3799 if (Or == TopAbs_FORWARD) {U1 = f; U2 = l;}
3800 else {U1 = l; U2 = f;}
3801 if (Or == TopAbs_FORWARD)
3805 if (Abs(U1-l) < eps) U1 = f;
3806 if (Abs(U2-f) < eps) U2 = l;
3808 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3809 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3810 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3811 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3812 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3813 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3815 ConstShapes.Bind(E,NE);
3816 NE.Orientation(E.Orientation());
3822 if (Abs(U2-l) < eps) U2 = f;
3823 if (Abs(U1-f) < eps) U1 = l;
3825 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3826 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3827 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3828 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3829 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3830 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3832 ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
3833 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3838 //-------------------
3839 // edge is not ferme.
3840 //-------------------
3841 if (Or == TopAbs_FORWARD) {
3843 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3844 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3845 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3846 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3847 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3848 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3853 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3854 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3855 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3856 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3857 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3858 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3861 ConstShapes.Bind(E,NE);
3862 NE.Orientation(E.Orientation());
3866 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3867 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3868 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3869 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3870 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3871 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3873 ConstShapes.Bind(E,NE);
3874 NE.Orientation(E.Orientation());
3878 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3879 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3880 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3881 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3882 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3883 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3885 ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
3886 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3891 } // Build.IsBound(E)
3892 else if (ConstShapes.IsBound(E)) { // !Build.IsBound(E)
3893 NE = TopoDS::Edge(ConstShapes(E));
3894 BuildPCurves(NE,NF);
3895 Or = NE.Orientation();
3896 if (Or == TopAbs_REVERSED) {
3897 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3900 NE.Orientation(E.Orientation());
3905 ConstShapes.Bind(E,NE.Oriented(TopAbs_FORWARD));
3909 B.Add(NF,NW.Oriented(W.Orientation()));
3911 NF.Orientation(F.Orientation());
3912 BRepTools::Update(NF); // Maj des UVPoints
3917 char* name = new char[100];
3918 sprintf(name,"FOB_%d",NbFOB++);
3919 DBRep::Set(name,NF);
3925 //=======================================================================
3926 //function : Deboucle3D
3928 //=======================================================================
3930 TopoDS_Shape BRepOffset_Tool::Deboucle3D(const TopoDS_Shape& S,
3931 const TopTools_MapOfShape& Boundary)
3933 return BRepAlgo_Tool::Deboucle3D(S,Boundary);
3936 //=======================================================================
3937 //function : IsInOut
3939 //=======================================================================
3941 static Standard_Boolean IsInOut (BRepTopAdaptor_FClass2d& FC,
3942 Geom2dAdaptor_Curve AC,
3943 const TopAbs_State& S )
3945 Standard_Real Def = 100*Precision::Confusion();
3946 GCPnts_QuasiUniformDeflection QU(AC,Def);
3948 for (Standard_Integer i = 1; i <= QU.NbPoints(); i++) {
3949 gp_Pnt2d P = AC.Value(QU.Parameter(i));
3950 if (FC.Perform(P) != S) {
3951 return Standard_False;
3955 return Standard_True;
3958 //=======================================================================
3959 //function : CorrectOrientation
3961 //=======================================================================
3963 void BRepOffset_Tool::CorrectOrientation(const TopoDS_Shape& SI,
3964 const TopTools_IndexedMapOfShape& NewEdges,
3965 Handle(BRepAlgo_AsDes)& AsDes,
3966 BRepAlgo_Image& InitOffset,
3967 const Standard_Real Offset)
3970 TopExp_Explorer exp;
3971 exp.Init(SI,TopAbs_FACE);
3972 Standard_Real f=0.,l=0.;
3974 for (; exp.More(); exp.Next()) {
3976 const TopoDS_Face& FI = TopoDS::Face(exp.Current());
3977 const TopTools_ListOfShape& LOF = InitOffset.Image(FI);
3978 TopTools_ListIteratorOfListOfShape it(LOF);
3979 for (; it.More(); it.Next()) {
3980 const TopoDS_Face& OF = TopoDS::Face(it.Value());
3981 TopTools_ListOfShape& LOE = AsDes->ChangeDescendant(OF);
3982 TopTools_ListIteratorOfListOfShape itE(LOE);
3984 Standard_Boolean YaInt = Standard_False;
3985 for (; itE.More(); itE.Next()) {
3986 const TopoDS_Edge& OE = TopoDS::Edge(itE.Value());
3987 if (NewEdges.Contains(OE)) {YaInt = Standard_True; break;}
3990 TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
3991 BRepTopAdaptor_FClass2d FC (TopoDS::Face(aLocalFace),
3992 Precision::Confusion());
3993 // BRepTopAdaptor_FClass2d FC (TopoDS::Face(FI.Oriented(TopAbs_FORWARD)),
3994 // Precision::Confusion());
3995 for (itE.Initialize(LOE); itE.More(); itE.Next()) {
3996 TopoDS_Shape& OE = itE.Value();
3997 if (NewEdges.Contains(OE)) {
3998 Handle(Geom2d_Curve) CO2d =
3999 BRep_Tool::CurveOnSurface(TopoDS::Edge(OE),OF,f,l);
4000 Geom2dAdaptor_Curve AC(CO2d,f,l);
4003 if (IsInOut(FC,AC,TopAbs_OUT)) OE.Reverse();
4006 // if (IsInOut(FC,AC,TopAbs_IN)) OE.Reverse();