1 // Created on: 1995-10-23
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
19 #include <BRepOffset_Tool.ixx>
21 #include <BRepAlgo_Tool.hxx>
23 #include <BRepAdaptor_Curve.hxx>
24 #include <BRepAdaptor_Surface.hxx>
25 #include <BRepAdaptor_HCurve.hxx>
26 #include <BRepAdaptor_HSurface.hxx>
28 #include <BRepBndLib.hxx>
30 #include <Bnd_Box2d.hxx>
31 #include <BndLib_Add3dCurve.hxx>
32 #include <BRep_Tool.hxx>
33 #include <BRepLib.hxx>
34 #include <BRepLib_MakeEdge.hxx>
35 #include <BRepLib_MakeVertex.hxx>
36 #include <BRepLib_MakePolygon.hxx>
37 #include <BRepLib_MakeFace.hxx>
38 #include <BRepLib_MakeWire.hxx>
39 #include <BRepTools.hxx>
40 #include <BRepTools_WireExplorer.hxx>
42 #include <BRepTools_Modifier.hxx>
43 #include <BRepTools_TrsfModification.hxx>
44 #include <BRepTopAdaptor_FClass2d.hxx>
45 #include <BRepAdaptor_Curve.hxx>
46 #include <BRepAdaptor_Curve2d.hxx>
48 #include <IntRes2d_IntersectionPoint.hxx>
49 #include <IntRes2d_IntersectionSegment.hxx>
50 #include <Extrema_ExtPC.hxx>
53 #include <TopExp_Explorer.hxx>
55 #include <Standard_ConstructionError.hxx>
57 #include <TopOpeBRepBuild_Builder.hxx>
58 #include <TopOpeBRepDS_HDataStructure.hxx>
59 #include <TopOpeBRepDS_CurveExplorer.hxx>
60 #include <TopOpeBRep_DSFiller.hxx>
61 #include <TopOpeBRepTool_GeomTool.hxx>
62 #include <TopOpeBRep_ShapeIntersector.hxx>
63 #include <TopOpeBRep_FacesFiller.hxx>
64 #include <TopOpeBRep_GeomTool.hxx>
66 #include <TopoDS_Iterator.hxx>
67 #include <TopTools_ListIteratorOfListOfShape.hxx>
68 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
70 #include <Geom_Surface.hxx>
71 #include <Geom_RectangularTrimmedSurface.hxx>
72 #include <Geom_OffsetSurface.hxx>
73 #include <Geom_BezierSurface.hxx>
74 #include <Geom_BSplineSurface.hxx>
75 #include <Geom_ConicalSurface.hxx>
76 #include <Geom_Curve.hxx>
77 #include <Geom_Line.hxx>
78 #include <Geom_Plane.hxx>
79 #include <Geom_Conic.hxx>
80 #include <Geom_TrimmedCurve.hxx>
81 #include <GCPnts_QuasiUniformDeflection.hxx>
83 #include <GeomLib.hxx>
84 #include <GeomAPI.hxx>
85 #include <GeomAPI_ProjectPointOnCurve.hxx>
86 #include <Geom2d_TrimmedCurve.hxx>
87 #include <Geom2d_Line.hxx>
88 #include <Geom2d_Curve.hxx>
89 #include <Geom2d_Circle.hxx>
90 #include <Geom2d_Ellipse.hxx>
91 #include <Geom2d_Parabola.hxx>
92 #include <Geom2d_Hyperbola.hxx>
93 #include <Geom2d_BezierCurve.hxx>
94 #include <Geom2d_BSplineCurve.hxx>
96 #include <Geom2dAdaptor_Curve.hxx>
97 #include <Geom2dInt_GInter.hxx>
99 #include <GeomAdaptor_Surface.hxx>
100 #include <GeomProjLib.hxx>
101 #include <GeomInt_IntSS.hxx>
102 #include <ProjLib_ProjectedCurve.hxx>
103 #include <ProjLib_HProjectedCurve.hxx>
105 #include <ElSLib.hxx>
106 #include <ElCLib.hxx>
109 #include <gp_Pnt.hxx>
110 #include <gp_Vec.hxx>
113 #include <Precision.hxx>
114 #include <Standard_ConstructionError.hxx>
116 #include <BRep_TEdge.hxx>
117 #include <Extrema_ExtPC2d.hxx>
119 #include <Geom_SurfaceOfLinearExtrusion.hxx>
120 #include <Geom_SurfaceOfRevolution.hxx>
121 #include <GCPnts_AbscissaPoint.hxx>
123 //tma: for new boolean operation
124 #include <TopTools_SequenceOfShape.hxx>
125 #include <Geom_BSplineCurve.hxx>
126 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
127 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
128 #include <GeomConvert_ApproxCurve.hxx>
129 #include <Geom2dConvert_ApproxCurve.hxx>
130 #include <TopoDS_Compound.hxx>
131 #include <GCPnts_UniformAbscissa.hxx>
132 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
133 #include <BRep_CurveRepresentation.hxx>
135 #include <BRepOffset_ListOfInterval.hxx>
136 #include <BRepOffset_Interval.hxx>
137 #include <TColgp_Array1OfPnt2d.hxx>
138 #include <ShapeCustom_Curve2d.hxx>
139 #include <GeomAPI_ExtremaCurveCurve.hxx>
141 #include <BOPDS_DS.hxx>
142 #include <BOPAlgo_PaveFiller.hxx>
143 #include <BOPTools_AlgoTools2D.hxx>
147 Standard_Boolean AffichInter = Standard_False;
148 static Standard_Integer NbNewEdges = 1;
149 static Standard_Integer NbFaces = 1;
150 static Standard_Integer NbFOB = 1;
151 static Standard_Integer NbFTE = 1;
152 static Standard_Integer NbExtE = 1;
156 static Standard_Boolean AffichExtent = Standard_False;
159 //=======================================================================
160 //function : EdgeVertices
162 //=======================================================================
164 void BRepOffset_Tool::EdgeVertices (const TopoDS_Edge& E,
168 if (E.Orientation() == TopAbs_REVERSED) {
169 TopExp::Vertices(E,V2,V1);
172 TopExp::Vertices(E,V1,V2);
176 //=======================================================================
177 //function : OriEdgeInFace
179 //=======================================================================
181 TopAbs_Orientation BRepOffset_Tool::OriEdgeInFace (const TopoDS_Edge& E,
182 const TopoDS_Face& F )
186 Exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
188 for (; Exp.More() ;Exp.Next()) {
189 if (Exp.Current().IsSame(E)) {
190 return Exp.Current().Orientation();
193 Standard_ConstructionError::Raise("BRepOffset_Tool::OriEdgeInFace");
194 return E.Orientation();
198 //=======================================================================
199 //function : FindPeriod
201 //=======================================================================
203 static void FindPeriod (const TopoDS_Face& F,
212 for (exp.Init(F,TopAbs_EDGE); exp.More(); exp.Next()) {
213 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
216 const Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,pf,pl);
217 if (C.IsNull()) return;
218 Geom2dAdaptor_Curve PC(C,pf,pl);
219 Standard_Real i, nbp = 20;
220 if (PC.GetType() == GeomAbs_Line) nbp = 2;
221 Standard_Real step = (pl - pf) / nbp;
225 for (i = 2; i < nbp; i++) {
232 B.Get(umin,vmin,umax,vmax);
236 //=======================================================================
237 //function : PutInBounds
238 //purpose : Recadre la courbe 2d dans les bounds de la face
239 //=======================================================================
241 static void PutInBounds (const TopoDS_Face& F,
242 const TopoDS_Edge& E,
243 Handle(Geom2d_Curve)& C2d)
245 Standard_Real umin,umax,vmin,vmax;
247 BRep_Tool::Range(E,f,l);
249 TopLoc_Location L; // Recup S avec la location pour eviter la copie.
250 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
252 if (S->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
253 S = (*(Handle(Geom_RectangularTrimmedSurface)*)&S)->BasisSurface();
258 if (!S->IsUPeriodic() && !S->IsVPeriodic()) return;
260 FindPeriod (F,umin,umax,vmin,vmax);
262 if (S->IsUPeriodic()) {
263 Standard_Real period = S->UPeriod();
264 Standard_Real eps = period*1.e-6;
265 gp_Pnt2d Pf = C2d->Value(f);
266 gp_Pnt2d Pl = C2d->Value(l);
267 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
268 Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
269 Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
270 Standard_Real du = 0.;
271 if (minC< umin - eps) {
272 du = (int((umin - minC)/period) + 1)*period;
274 if (minC > umax + eps) {
275 du = -(int((minC - umax)/period) + 1)*period;
280 minC += du; maxC += du;
282 // Ajuste au mieux la courbe dans le domaine.
283 if (maxC > umax +100*eps) {
284 Standard_Real d1 = maxC - umax;
285 Standard_Real d2 = umin - minC + period;
286 if (d2 < d1) du =-period;
296 if (S->IsVPeriodic()) {
297 Standard_Real period = S->VPeriod();
298 Standard_Real eps = period*1.e-6;
299 gp_Pnt2d Pf = C2d->Value(f);
300 gp_Pnt2d Pl = C2d->Value(l);
301 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
302 Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
303 Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
304 Standard_Real dv = 0.;
305 if (minC< vmin - eps) {
306 dv = (int((vmin - minC)/period) + 1)*period;
308 if (minC > vmax + eps) {
309 dv = -(int((minC - vmax)/period) + 1)*period;
314 minC += dv; maxC += dv;
316 // Ajuste au mieux la courbe dans le domaine.
317 if (maxC > vmax +100*eps) {
318 Standard_Real d1 = maxC - vmax;
319 Standard_Real d2 = vmin - minC + period;
320 if (d2 < d1) dv =-period;
329 //=======================================================================
332 //=======================================================================
334 Standard_Real BRepOffset_Tool::Gabarit(const Handle(Geom_Curve)& aCurve)
336 GeomAdaptor_Curve GC( aCurve );
338 BndLib_Add3dCurve::Add( GC, Precision::Confusion(), aBox );
339 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dist;
340 aBox.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
341 dist = Max( (aXmax-aXmin), (aYmax-aYmin) );
342 dist = Max( dist, (aZmax-aZmin) );
346 //=======================================================================
347 //function : BuildPCurves
349 //=======================================================================
351 static void BuildPCurves (const TopoDS_Edge& E,
352 const TopoDS_Face& F)
355 Handle (Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E,F,ff,ll);
356 if (!C2d.IsNull()) return;
358 //Standard_Real Tolerance = Max(Precision::Confusion(),BRep_Tool::Tolerance(E));
359 Standard_Real Tolerance = Precision::Confusion();
361 BRepAdaptor_Surface AS(F,0);
362 BRepAdaptor_Curve AC(E);
364 //Try to find pcurve on a bound of BSpline or Bezier surface
365 Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( F );
366 Handle( Standard_Type ) typS = theSurf->DynamicType();
367 if (typS == STANDARD_TYPE(Geom_OffsetSurface))
368 typS = (*((Handle(Geom_OffsetSurface)*)&theSurf))->BasisSurface()->DynamicType();
369 if (typS == STANDARD_TYPE(Geom_BezierSurface) || typS == STANDARD_TYPE(Geom_BSplineSurface))
371 gp_Pnt fpoint = AC.Value( AC.FirstParameter() );
372 gp_Pnt lpoint = AC.Value( AC.LastParameter() );
373 TopoDS_Face theFace = BRepLib_MakeFace( theSurf, Precision::Confusion() );
374 Standard_Real U1 = 0., U2 = 0., TolProj = 1.e-4; //1.e-5;
376 TopExp_Explorer Explo;
377 Explo.Init( theFace, TopAbs_EDGE );
378 for (; Explo.More(); Explo.Next())
380 TopoDS_Edge anEdge = TopoDS::Edge( Explo.Current() );
381 BRepAdaptor_Curve aCurve( anEdge );
382 Extrema_ExtPC fextr( fpoint, aCurve );
383 if (!fextr.IsDone() || fextr.NbExt() < 1)
385 Standard_Real dist2, dist2min = RealLast();
387 for (i = 1; i <= fextr.NbExt(); i++)
389 dist2 = fextr.SquareDistance(i);
390 if (dist2 < dist2min)
393 U1 = fextr.Point(i).Parameter();
396 if (dist2min > TolProj * TolProj)
398 Extrema_ExtPC lextr( lpoint, aCurve );
399 if (!lextr.IsDone() || lextr.NbExt() <1)
401 dist2min = RealLast();
402 for (i = 1; i <= lextr.NbExt(); i++)
404 dist2 = lextr.SquareDistance(i);
405 if (dist2 < dist2min)
408 U2 = lextr.Point(i).Parameter();
411 if (dist2min <= TolProj * TolProj)
416 } // for (; Explo.More(); Explo.Current())
418 if (! theEdge.IsNull())
420 //Construction of pcurve
423 Standard_Real temp = U1;
428 C2d = BRep_Tool::CurveOnSurface( theEdge, theFace, f, l );
429 C2d = new Geom2d_TrimmedCurve( C2d, U1, U2 );
431 if (theSurf->IsUPeriodic() || theSurf->IsVPeriodic())
432 PutInBounds( F, E, C2d );
435 B.UpdateEdge( E, C2d, F, BRep_Tool::Tolerance(E) );
436 BRepLib::SameRange( E );
442 Handle(BRepAdaptor_HSurface) HS = new BRepAdaptor_HSurface(AS);
443 Handle(BRepAdaptor_HCurve) HC = new BRepAdaptor_HCurve(AC);
445 ProjLib_ProjectedCurve Proj(HS,HC,Tolerance);
447 switch ( Proj.GetType()) {
450 C2d = new Geom2d_Line(Proj.Line());
454 C2d = new Geom2d_Circle(Proj.Circle());
457 case GeomAbs_Ellipse:
458 C2d = new Geom2d_Ellipse(Proj.Ellipse());
461 case GeomAbs_Parabola:
462 C2d = new Geom2d_Parabola(Proj.Parabola());
465 case GeomAbs_Hyperbola:
466 C2d = new Geom2d_Hyperbola(Proj.Hyperbola());
469 case GeomAbs_BezierCurve:
473 case GeomAbs_BSplineCurve:
474 C2d = Proj.BSpline();
480 if (AS.IsUPeriodic() || AS.IsVPeriodic()) {
481 PutInBounds(F,E,C2d);
485 B.UpdateEdge (E,C2d,F,BRep_Tool::Tolerance(E));
488 Standard_ConstructionError::Raise("BRepOffset_Tool::BuildPCurves");
489 cout <<"Echec ProjLib"<<endl;
493 //=======================================================================
496 //=======================================================================
498 void BRepOffset_Tool::OrientSection (const TopoDS_Edge& E,
499 const TopoDS_Face& F1,
500 const TopoDS_Face& F2,
501 TopAbs_Orientation& O1,
502 TopAbs_Orientation& O2)
508 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
509 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
510 Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l);
511 Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l);
512 Handle (Geom_Curve) C = BRep_Tool::Curve(E,L,f,l);
514 BRepAdaptor_Curve BAcurve( E );
516 GCPnts_AbscissaPoint AP(BAcurve,GCPnts_AbscissaPoint::Length(BAcurve)/2.0,f);
517 Standard_Real ParOnC;
520 ParOnC = AP.Parameter();
522 ParOnC = BOPTools_AlgoTools2D::IntermediatePoint(f, l);
524 gp_Vec T1 = C->DN(ParOnC,1).Transformed(L.Transformation());
525 if (T1.SquareMagnitude() > gp::Resolution()) {
529 gp_Pnt2d P = C1->Value(ParOnC);
533 S1->D1(P.X(),P.Y(),P3,D1U,D1V);
535 if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse();
537 P = C2->Value(ParOnC);
538 S2->D1(P.X(),P.Y(),P3,D1U,D1V);
540 if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse();
542 gp_Vec ProVec = DN2^T1;
543 Standard_Real Prod = DN1.Dot(ProVec);
548 O1 = TopAbs_REVERSED;
551 Prod = DN2.Dot(ProVec);
556 O2 = TopAbs_REVERSED;
558 if (F1.Orientation() == TopAbs_REVERSED) O1 = TopAbs::Reverse(O1);
559 if (F2.Orientation() == TopAbs_REVERSED) O2 = TopAbs::Reverse(O2);
562 //=======================================================================
563 //function : HasCommonShape
565 //=======================================================================
567 Standard_Boolean BRepOffset_Tool::HasCommonShapes (const TopoDS_Face& F1,
568 const TopoDS_Face& F2,
569 TopTools_ListOfShape& LE,
570 TopTools_ListOfShape& LV)
572 Standard_Boolean Common = Standard_False;
573 LE.Clear(); LV.Clear();
575 TopExp_Explorer exp1;
576 exp1.Init(F1,TopAbs_EDGE);
578 for (; exp1.More(); exp1.Next()) {
579 TopExp_Explorer exp2;
580 exp2.Init(F2,TopAbs_EDGE);
581 for (; exp2.More(); exp2.Next()) {
582 if (exp1.Current().IsSame(exp2.Current())) {
583 Common = Standard_True;
584 LE.Append(exp1.Current());
588 for (exp1.Init(F1,TopAbs_VERTEX); exp1.More(); exp1.Next()) {
589 TopExp_Explorer exp2;
590 exp2.Init(F2,TopAbs_EDGE);
591 for (exp2.Init(F2,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
592 if (exp1.Current().IsSame(exp2.Current())) {
593 Common = Standard_True;
594 LV.Append(exp1.Current());
601 //=======================================================================
604 //=======================================================================
606 static Standard_Boolean ToSmall (const Handle(Geom_Curve)& C)
608 Standard_Real Tol = 10*Precision::Confusion();
609 Standard_Real m = (C->FirstParameter()*0.668 + C->LastParameter()*0.332);
610 gp_Pnt P1 = C->Value(C->FirstParameter());
611 gp_Pnt P2 = C->Value(C->LastParameter());
612 gp_Pnt P3 = C->Value(m);
613 if (P1.Distance(P2) > Tol) return Standard_False;
614 if (P2.Distance(P3) > Tol) return Standard_False;
615 return Standard_True;
619 //=======================================================================
620 //function : IsOnSurface
622 //=======================================================================
624 static Standard_Boolean IsOnSurface(const Handle(Geom_Curve)& C,
625 const Handle(Geom_Surface)& S,
626 Standard_Real TolConf,
627 Standard_Real& TolReached)
629 Standard_Real f = C->FirstParameter();
630 Standard_Real l = C->LastParameter();
631 Standard_Integer n = 5;
632 Standard_Real du = (f-l)/(n-1);
638 GeomAdaptor_Surface AS(S);
640 switch ( AS.GetType()) {
643 gp_Ax3 Ax = AS.Plane().Position();
644 for ( Standard_Integer i = 0; i < n; i++) {
645 P = C->Value(f+i*du);
646 ElSLib::PlaneParameters(Ax,P,U,V);
647 TolReached = P.Distance(ElSLib::PlaneValue(U,V,Ax));
648 if ( TolReached > TolConf)
649 return Standard_False;
653 case GeomAbs_Cylinder:
655 gp_Ax3 Ax = AS.Cylinder().Position();
656 Standard_Real Rad = AS.Cylinder().Radius();
657 for ( Standard_Integer i = 0; i < n; i++) {
658 P = C->Value(f+i*du);
659 ElSLib::CylinderParameters(Ax,Rad,P,U,V);
660 TolReached = P.Distance(ElSLib::CylinderValue(U,V,Ax,Rad));
661 if ( TolReached > TolConf)
662 return Standard_False;
668 gp_Ax3 Ax = AS.Cone().Position();
669 Standard_Real Rad = AS.Cone().RefRadius();
670 Standard_Real Alp = AS.Cone().SemiAngle();
671 for ( Standard_Integer i = 0; i < n; i++) {
672 P = C->Value(f+i*du);
673 ElSLib::ConeParameters(Ax,Rad,Alp,P,U,V);
674 TolReached = P.Distance(ElSLib::ConeValue(U,V,Ax,Rad,Alp));
675 if ( TolReached > TolConf)
676 return Standard_False;
682 gp_Ax3 Ax = AS.Sphere().Position();
683 Standard_Real Rad = AS.Sphere().Radius();
684 for ( Standard_Integer i = 0; i < n; i++) {
685 P = C->Value(f+i*du);
686 ElSLib::SphereParameters(Ax,Rad,P,U,V);
687 TolReached = P.Distance(ElSLib::SphereValue(U,V,Ax,Rad));
688 if ( TolReached > TolConf)
689 return Standard_False;
695 gp_Ax3 Ax = AS.Torus().Position();
696 Standard_Real R1 = AS.Torus().MajorRadius();
697 Standard_Real R2 = AS.Torus().MinorRadius();
698 for ( Standard_Integer i = 0; i < n; i++) {
699 P = C->Value(f+i*du);
700 ElSLib::TorusParameters(Ax,R1,R2,P,U,V);
701 TolReached = P.Distance(ElSLib::TorusValue(U,V,Ax,R1,R2));
702 if ( TolReached > TolConf)
703 return Standard_False;
710 return Standard_False;
714 return Standard_True;
718 //=======================================================================
719 //function : PipeInter
721 //=======================================================================
723 void BRepOffset_Tool::PipeInter(const TopoDS_Face& F1,
724 const TopoDS_Face& F2,
725 TopTools_ListOfShape& L1,
726 TopTools_ListOfShape& L2,
727 const TopAbs_State Side)
732 sprintf(name,"FF_%d",NbFaces++);
734 sprintf(name,"FF_%d",NbFaces++);
739 Handle (Geom_Curve) CI;
741 TopAbs_Orientation O1,O2;
742 L1.Clear(); L2.Clear();
744 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
745 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
747 GeomInt_IntSS Inter (S1,S2, Precision::Confusion(),1,1,1);
749 if (Inter.IsDone()) {
750 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
752 if (ToSmall(CI)) continue;
753 TopoDS_Edge E = BRepLib_MakeEdge(CI);
754 if (Inter.HasLineOnS1(i)) {
755 Handle(Geom2d_Curve) C2 = Inter.LineOnS1(i);
756 PutInBounds (F1,E,C2);
757 B.UpdateEdge (E,C2,F1,BRep_Tool::Tolerance(E));
762 if (Inter.HasLineOnS2(i)) {
763 Handle(Geom2d_Curve) C2 = Inter.LineOnS2(i);
764 PutInBounds (F2,E,C2);
765 B.UpdateEdge (E,C2,F2,BRep_Tool::Tolerance(E));
770 OrientSection (E,F1,F2,O1,O2);
771 if (Side == TopAbs_OUT) {
772 O1 = TopAbs::Reverse(O1);
773 O2 = TopAbs::Reverse(O2);
775 L1.Append (E.Oriented(O1));
776 L2.Append (E.Oriented(O2));
780 sprintf(name,"EI_%d",NbNewEdges++);
781 DBRep::Set(name,E.Oriented(O1));
789 //=======================================================================
790 //function : IsAutonomVertex
791 //purpose : Checks wether a vertex is "autonom" or not
792 //=======================================================================
794 static Standard_Boolean IsAutonomVertex(const TopoDS_Shape& aVertex,
795 const BOPDS_PDS& pDS)
797 Standard_Integer index;
798 Standard_Integer aNbVVs, aNbEEs, aNbEFs, aInt;
800 index = pDS->Index(aVertex);
802 Standard_Integer i, i1, i2;
803 i1=pDS->NbSourceShapes();
805 for (i=i1; i<i2; ++i) {
806 const TopoDS_Shape& aSx=pDS->Shape(i);
807 if(aSx.IsSame(aVertex)) {
814 if (!pDS->IsNewShape(index)) {
815 return Standard_False;
817 //check if vertex with index "index" is not created in VV or EE or EF interference
819 BOPDS_VectorOfInterfVV& aVVs=pDS->InterfVV();
820 aNbVVs = aVVs.Extent();
821 for(aInt = 0; aInt < aNbVVs; aInt++) {
822 const BOPDS_InterfVV& aVV = aVVs(aInt);
823 if (aVV.HasIndexNew()) {
824 if (aVV.IndexNew() == index) {
825 return Standard_False;
830 BOPDS_VectorOfInterfEE& aEEs=pDS->InterfEE();
831 aNbEEs = aEEs.Extent();
832 for(aInt = 0; aInt < aNbEEs; aInt++) {
833 const BOPDS_InterfEE& aEE = aEEs(aInt);
834 IntTools_CommonPrt aCP = aEE.CommonPart();
835 if(aCP.Type() == TopAbs_VERTEX) {
836 if (aEE.IndexNew() == index) {
837 return Standard_False;
842 BOPDS_VectorOfInterfEF& aEFs=pDS->InterfEF();
843 aNbEFs = aEFs.Extent();
844 for(aInt = 0; aInt < aNbEFs; aInt++) {
845 const BOPDS_InterfEF& aEF = aEFs(aInt);
846 IntTools_CommonPrt aCP = aEF.CommonPart();
847 if(aCP.Type() == TopAbs_VERTEX) {
848 if (aEF.IndexNew() == index) {
849 return Standard_False;
853 return Standard_True;
857 //=======================================================================
858 //function : AreConnex
859 //purpose : define if two shapes are connex by a vertex (vertices)
860 //=======================================================================
862 static Standard_Boolean AreConnex(const TopoDS_Wire& W1,
863 const TopoDS_Wire& W2,
864 const BOPDS_PDS& pDS)
866 TopoDS_Vertex V11, V12, V21, V22;
867 TopExp::Vertices( W1, V11, V12 );
868 TopExp::Vertices( W2, V21, V22 );
870 if (V11.IsSame(V21) || V11.IsSame(V22) ||
871 V12.IsSame(V21) || V12.IsSame(V22))
873 Standard_Boolean isCV1 = V11.IsSame(V21) || V11.IsSame(V22);
874 Standard_Boolean isCV2 = V12.IsSame(V21) || V12.IsSame(V22);
875 if (isCV1 && !IsAutonomVertex(V11, pDS))
878 return Standard_False;
879 if (!IsAutonomVertex(V12, pDS))
880 return Standard_False;
882 if (!isCV1 && !IsAutonomVertex(V12, pDS))
883 return Standard_False;
885 TopoDS_Vertex CV = (V11.IsSame(V21) || V11.IsSame(V22))? V11 : V12;
887 TopoDS_Iterator itw( W1 );
888 for (; itw.More(); itw.Next())
890 E1 = TopoDS::Edge(itw.Value());
891 TopoDS_Vertex V1, V2;
892 TopExp::Vertices( E1, V1, V2 );
893 if (V1.IsSame(CV) || V2.IsSame(CV))
896 itw.Initialize( W2 );
897 E2 = TopoDS::Edge(itw.Value());
900 Handle(Geom_Curve) C1 = BRep_Tool::Curve( E1, f, l );
901 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
902 C1 = (*((Handle(Geom_TrimmedCurve)*)&C1))->BasisCurve();
904 Handle(Geom_Curve) C2 = BRep_Tool::Curve( E2, f, l );
905 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
906 C2 = (*((Handle(Geom_TrimmedCurve)*)&C2))->BasisCurve();
908 if (C1->IsInstance(STANDARD_TYPE(Geom_Line)) &&
909 C2->IsInstance(STANDARD_TYPE(Geom_Line)))
911 Handle(Geom_Line) L1 = *((Handle(Geom_Line)*) &C1);
912 gp_Ax1 Axis1 = L1->Position();
913 Handle(Geom_Line) L2 = *((Handle(Geom_Line)*) &C2);
914 gp_Ax1 Axis2 = L2->Position();
915 if (! Axis1.IsParallel( Axis2, Precision::Angular() ))
916 return Standard_False;
919 return Standard_True;
922 return Standard_False;
925 //=======================================================================
926 //function : AreClosed
927 //purpose : define if two edges are connex by two vertices
928 //=======================================================================
930 static Standard_Boolean AreClosed(const TopoDS_Edge& E1,
931 const TopoDS_Edge& E2)
933 TopoDS_Vertex V11, V12, V21, V22;
934 TopExp::Vertices( E1, V11, V12 );
935 TopExp::Vertices( E2, V21, V22 );
937 if ((V11.IsSame(V21) && V12.IsSame(V22)) ||
938 (V11.IsSame(V22) && V12.IsSame(V21)))
939 return Standard_True;
941 return Standard_False;
944 //=======================================================================
945 //function : BSplineEdges
947 //=======================================================================
949 static Standard_Boolean BSplineEdges(const TopoDS_Edge& E1,
950 const TopoDS_Edge& E2,
951 const Standard_Integer par1,
952 const Standard_Integer par2,
953 Standard_Real& angle)
955 Standard_Real first1, last1, first2, last2, Param1, Param2;
957 Handle(Geom_Curve) C1 = BRep_Tool::Curve( E1, first1, last1 );
958 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
959 C1 = (*((Handle(Geom_TrimmedCurve)*)&C1))->BasisCurve();
961 Handle(Geom_Curve) C2 = BRep_Tool::Curve( E2, first2, last2 );
962 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
963 C2 = (*((Handle(Geom_TrimmedCurve)*)&C2))->BasisCurve();
965 if (!C1->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)) ||
966 !C2->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)))
967 return Standard_False;
969 Param1 = (par1 == 0)? first1 : last1;
970 Param2 = (par2 == 0)? first2 : last2;
974 C1->D1( Param1, Pnt1, Der1 );
975 C2->D1( Param2, Pnt2, Der2 );
977 if (Der1.Magnitude() <= gp::Resolution() ||
978 Der2.Magnitude() <= gp::Resolution())
981 angle = Der1.Angle(Der2);
983 return Standard_True;
986 //=======================================================================
987 //function : AngleWireEdge
989 //=======================================================================
991 static Standard_Real AngleWireEdge(const TopoDS_Wire& aWire,
992 const TopoDS_Edge& anEdge)
994 TopoDS_Vertex V11, V12, V21, V22, CV;
995 TopExp::Vertices( aWire, V11, V12 );
996 TopExp::Vertices( anEdge, V21, V22 );
997 CV = (V11.IsSame(V21) || V11.IsSame(V22))? V11 : V12;
998 TopoDS_Edge FirstEdge;
999 TopoDS_Iterator itw(aWire);
1000 for (; itw.More(); itw.Next())
1002 FirstEdge = TopoDS::Edge(itw.Value());
1003 TopoDS_Vertex v1, v2;
1004 TopExp::Vertices( FirstEdge, v1, v2 );
1005 if (v1.IsSame(CV) || v2.IsSame(CV))
1012 Standard_Real Angle;
1013 if (V11.IsSame(CV) && V21.IsSame(CV))
1015 BSplineEdges( FirstEdge, anEdge, 0, 0, Angle );
1016 Angle = M_PI - Angle;
1018 else if (V11.IsSame(CV) && V22.IsSame(CV))
1019 BSplineEdges( FirstEdge, anEdge, 0, 1, Angle );
1020 else if (V12.IsSame(CV) && V21.IsSame(CV))
1021 BSplineEdges( FirstEdge, anEdge, 1, 0, Angle );
1024 BSplineEdges( FirstEdge, anEdge, 1, 1, Angle );
1025 Angle = M_PI - Angle;
1031 //=======================================================================
1032 //function : ReconstructPCurves
1034 //=======================================================================
1036 static void ReconstructPCurves(const TopoDS_Edge& anEdge)
1039 Handle(Geom_Curve) C3d = BRep_Tool::Curve(anEdge, f, l);
1041 BRep_ListIteratorOfListOfCurveRepresentation
1042 itcr( (Handle(BRep_TEdge)::DownCast(anEdge.TShape()))->ChangeCurves() );
1043 for (; itcr.More(); itcr.Next())
1045 Handle( BRep_CurveRepresentation ) CurveRep = itcr.Value();
1046 if (CurveRep->IsCurveOnSurface())
1048 Handle(Geom_Surface) theSurf = CurveRep->Surface();
1049 TopLoc_Location theLoc = CurveRep->Location();
1050 theLoc = anEdge.Location() * theLoc;
1051 theSurf = Handle(Geom_Surface)::DownCast
1052 (theSurf->Transformed(theLoc.Transformation()));
1053 Handle(Geom2d_Curve) ProjPCurve =
1054 GeomProjLib::Curve2d( C3d, f, l, theSurf );
1055 CurveRep->PCurve( ProjPCurve );
1060 //=======================================================================
1061 //function : ConcatPCurves
1063 //=======================================================================
1065 static Handle(Geom2d_Curve) ConcatPCurves(const TopoDS_Edge& E1,
1066 const TopoDS_Edge& E2,
1067 const TopoDS_Face& F,
1068 const Standard_Boolean After,
1069 Standard_Real& newFirst,
1070 Standard_Real& newLast)
1072 Standard_Real Tol = 1.e-7;
1073 GeomAbs_Shape Continuity = GeomAbs_C1;
1074 Standard_Integer MaxDeg = 14;
1075 Standard_Integer MaxSeg = 16;
1077 Standard_Real first1, last1, first2, last2;
1078 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1080 PCurve1 = BRep_Tool::CurveOnSurface( E1, F, first1, last1 );
1081 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
1082 PCurve1 = (*((Handle(Geom2d_TrimmedCurve)*)&PCurve1))->BasisCurve();
1084 PCurve2 = BRep_Tool::CurveOnSurface( E2, F, first2, last2 );
1085 if (PCurve2->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
1086 PCurve2 = (*((Handle(Geom2d_TrimmedCurve)*)&PCurve2))->BasisCurve();
1088 if (PCurve1 == PCurve2)
1090 newPCurve = PCurve1;
1091 newFirst = Min( first1, first2 );
1092 newLast = Max( last1, last2 );
1094 else if (PCurve1->DynamicType() == PCurve2->DynamicType() &&
1095 (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)) ||
1096 PCurve1->IsKind(STANDARD_TYPE(Geom2d_Conic))))
1098 newPCurve = PCurve1;
1100 P1 = PCurve2->Value( first2 );
1101 P2 = PCurve2->Value( last2 );
1102 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)))
1104 Handle(Geom2d_Line) Lin1 = *((Handle(Geom2d_Line)*) &PCurve1);
1105 gp_Lin2d theLin = Lin1->Lin2d();
1106 first2 = ElCLib::Parameter( theLin, P1 );
1107 last2 = ElCLib::Parameter( theLin, P2 );
1109 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Circle)))
1111 Handle(Geom2d_Circle) Circ1 = *((Handle(Geom2d_Circle)*) &PCurve1);
1112 gp_Circ2d theCirc = Circ1->Circ2d();
1113 first2 = ElCLib::Parameter( theCirc, P1 );
1114 last2 = ElCLib::Parameter( theCirc, P2 );
1116 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Ellipse)))
1118 Handle(Geom2d_Ellipse) Ell1 = *((Handle(Geom2d_Ellipse)*) &PCurve1);
1119 gp_Elips2d theElips = Ell1->Elips2d();
1120 first2 = ElCLib::Parameter( theElips, P1 );
1121 last2 = ElCLib::Parameter( theElips, P2 );
1123 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Parabola)))
1125 Handle(Geom2d_Parabola) Parab1 = *((Handle(Geom2d_Parabola)*) &PCurve1);
1126 gp_Parab2d theParab = Parab1->Parab2d();
1127 first2 = ElCLib::Parameter( theParab, P1 );
1128 last2 = ElCLib::Parameter( theParab, P2 );
1130 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Hyperbola)))
1132 Handle(Geom2d_Hyperbola) Hypr1 = *((Handle(Geom2d_Hyperbola)*) &PCurve1);
1133 gp_Hypr2d theHypr = Hypr1->Hypr2d();
1134 first2 = ElCLib::Parameter( theHypr, P1 );
1135 last2 = ElCLib::Parameter( theHypr, P2 );
1137 newFirst = Min( first1, first2 );
1138 newLast = Max( last1, last2 );
1142 Handle(Geom2d_TrimmedCurve) TC1 = new Geom2d_TrimmedCurve( PCurve1, first1, last1 );
1143 Handle(Geom2d_TrimmedCurve) TC2 = new Geom2d_TrimmedCurve( PCurve2, first2, last2 );
1144 Geom2dConvert_CompCurveToBSplineCurve Concat2d( TC1 );
1145 Concat2d.Add( TC2, Precision::Confusion(), After );
1146 newPCurve = Concat2d.BSplineCurve();
1147 if (newPCurve->Continuity() < GeomAbs_C1)
1149 Geom2dConvert_ApproxCurve Approx2d( newPCurve, Tol, Continuity, MaxSeg, MaxDeg );
1150 if (Approx2d.HasResult())
1151 newPCurve = Approx2d.Curve();
1153 newFirst = newPCurve->FirstParameter();
1154 newLast = newPCurve->LastParameter();
1160 //=======================================================================
1162 //purpose : glue two edges.
1163 //=======================================================================
1165 static TopoDS_Edge Glue(const TopoDS_Edge& E1,
1166 const TopoDS_Edge& E2,
1167 const TopoDS_Vertex& Vfirst,
1168 const TopoDS_Vertex& Vlast,
1169 const Standard_Boolean After,
1170 const TopoDS_Face& F1,
1171 const Standard_Boolean addPCurve1,
1172 const TopoDS_Face& F2,
1173 const Standard_Boolean addPCurve2)
1175 Standard_Real Tol = 1.e-7;
1176 GeomAbs_Shape Continuity = GeomAbs_C1;
1177 Standard_Integer MaxDeg = 14;
1178 Standard_Integer MaxSeg = 16;
1180 Handle(Geom_Curve) C1, C2, newCurve;
1181 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1182 Standard_Real first1, last1, first2, last2, fparam=0., lparam=0.;
1183 Standard_Boolean IsCanonic = Standard_False;
1185 C1 = BRep_Tool::Curve( E1, first1, last1 );
1186 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
1187 C1 = (*((Handle(Geom_TrimmedCurve)*)&C1))->BasisCurve();
1189 C2 = BRep_Tool::Curve( E2, first2, last2 );
1190 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
1191 C2 = (*((Handle(Geom_TrimmedCurve)*)&C2))->BasisCurve();
1196 fparam = Min( first1, first2 );
1197 lparam = Max( last1, last2 );
1199 else if (C1->DynamicType() == C2->DynamicType() &&
1200 (C1->IsInstance(STANDARD_TYPE(Geom_Line)) ||
1201 C1->IsKind(STANDARD_TYPE(Geom_Conic))))
1203 IsCanonic = Standard_True;
1208 Handle(Geom_TrimmedCurve) TC1 = new Geom_TrimmedCurve( C1, first1, last1 );
1209 Handle(Geom_TrimmedCurve) TC2 = new Geom_TrimmedCurve( C2, first2, last2 );
1210 GeomConvert_CompCurveToBSplineCurve Concat( TC1 );
1211 Concat.Add( TC2, Precision::Confusion(), After );
1212 newCurve = Concat.BSplineCurve();
1213 if (newCurve->Continuity() < GeomAbs_C1)
1215 GeomConvert_ApproxCurve Approx3d( newCurve, Tol, Continuity, MaxSeg, MaxDeg );
1216 if (Approx3d.HasResult())
1217 newCurve = Approx3d.Curve();
1219 fparam = newCurve->FirstParameter();
1220 lparam = newCurve->LastParameter();
1223 TopoDS_Edge newEdge;
1227 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast );
1229 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast, fparam, lparam );
1231 Standard_Real newFirst, newLast;
1234 newPCurve = ConcatPCurves( E1, E2, F1, After, newFirst, newLast );
1235 BB.UpdateEdge( newEdge, newPCurve, F1, 0. );
1236 BB.Range( newEdge, F1, newFirst, newLast );
1240 newPCurve = ConcatPCurves( E1, E2, F2, After, newFirst, newLast );
1241 BB.UpdateEdge( newEdge, newPCurve, F2, 0. );
1242 BB.Range( newEdge, F2, newFirst, newLast );
1249 //=======================================================================
1250 //function : FindNewVerticesOnBoundsOfFace
1252 //=======================================================================
1254 static void FindNewVerticesOnBoundsOfFace(const BOPDS_PDS& pDS,
1255 const TopoDS_Face& aFace,
1256 TopTools_DataMapOfShapeShape& VEmap)
1258 TopTools_IndexedMapOfShape OldVertices;
1259 TopExp::MapShapes( aFace, TopAbs_VERTEX, OldVertices );
1260 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
1261 TopoDS_Vertex V1, V2;
1263 TopExp_Explorer Explo( aFace, TopAbs_EDGE );
1264 for (; Explo.More(); Explo.Next()) {
1265 const TopoDS_Shape& aE = Explo.Current();
1266 Standard_Integer nE = pDS->Index(aE);
1268 const BOPDS_ListOfPaveBlock& aLPB = pDS->PaveBlocks(nE);
1269 aItLPB.Initialize(aLPB);
1270 for (; aItLPB.More(); aItLPB.Next()) {
1271 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
1272 const TopoDS_Edge& aESp = *(TopoDS_Edge*)&pDS->Shape(aPB->Edge());
1274 TopExp::Vertices( aESp, V1, V2 );
1275 if (!OldVertices.Contains( V1 )) {
1276 VEmap.Bind( V1, aE );
1279 if (!OldVertices.Contains( V2 )) {
1280 VEmap.Bind( V2, aE );
1286 //=======================================================================
1287 //function : CheckIntersFF
1289 //=======================================================================
1291 static Standard_Boolean CheckIntersFF(const BOPDS_PDS& pDS,
1292 const TopoDS_Edge& RefEdge,
1293 const TopoDS_Face& F1,
1294 const TopoDS_Face& F2,
1295 TopTools_IndexedMapOfShape& TrueEdges)
1297 Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
1298 Standard_Boolean isPlane1 = Standard_False, isPlane2 = Standard_False;
1300 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F1);
1301 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1302 aSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&aSurf))->BasisSurface();
1303 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1304 isPlane1 = Standard_True;
1305 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1306 isEl1 = Standard_True;
1308 aSurf = BRep_Tool::Surface(F2);
1309 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1310 aSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&aSurf))->BasisSurface();
1311 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1312 isPlane2 = Standard_True;
1313 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1314 isEl2 = Standard_True;
1316 if (isPlane1 || isPlane2)
1317 return Standard_True;
1320 return Standard_True;
1322 BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF();
1323 Standard_Integer aNb = aFFs.Extent();
1324 Standard_Integer i, j, nbe = 0;
1326 TopTools_SequenceOfShape Edges;
1328 for (i = 0; i < aNb; ++i)
1330 BOPDS_InterfFF& aFFi=aFFs(i);
1331 const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
1332 Standard_Integer aNbCurves = aBCurves.Extent();
1334 for (j = 0; j < aNbCurves; ++j)
1336 const BOPDS_Curve& aBC=aBCurves(j);
1337 const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
1339 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1340 aPBIt.Initialize(aSectEdges);
1342 for (; aPBIt.More(); aPBIt.Next())
1344 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
1345 Standard_Integer nSect = aPB->Edge();
1346 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
1347 Edges.Append( anEdge );
1354 return Standard_True;
1356 //define tangents of RefEdge on start and on end
1357 BRepAdaptor_Curve cref(RefEdge);
1358 gp_Vec RefTangFirst = cref.DN(cref.FirstParameter(), 1);
1359 gp_Vec RefTangLast = cref.DN(cref.LastParameter(), 1);
1361 //find the start edge and take it from Edges
1362 TopoDS_Edge StartEdge; //, StartEonF1, StartEonF2, EndEonF1, EndEonF2;
1364 TopTools_DataMapOfShapeShape VEmapF1, VEmapF2;
1365 FindNewVerticesOnBoundsOfFace( pDS, F1, VEmapF1 );
1366 FindNewVerticesOnBoundsOfFace( pDS, F2, VEmapF2 );
1368 Standard_Real AngTol = 0.1;
1369 Standard_Boolean V1onBound = Standard_False;
1370 Standard_Boolean V2onBound = Standard_False;
1371 TopoDS_Vertex V1, V2, Vcur;
1372 gp_Vec TangFirst, TangLast, TangCur;
1373 for (i = 1; i <= Edges.Length(); i++)
1375 StartEdge = TopoDS::Edge(Edges(i));
1376 TopExp::Vertices( StartEdge, V1, V2 );
1377 V1onBound = VEmapF1.IsBound(V1) || VEmapF2.IsBound(V1); // && ?
1378 V2onBound = VEmapF1.IsBound(V2) || VEmapF2.IsBound(V2); // && ?
1379 if (V1onBound || V2onBound)
1381 BRepAdaptor_Curve CE(StartEdge);
1382 TangFirst = CE.DN( CE.FirstParameter(), 1 );
1383 TangLast = CE.DN( CE.LastParameter(), 1 );
1386 if (TangFirst.IsParallel( RefTangFirst, AngTol ) ||
1387 TangFirst.IsParallel( RefTangLast, AngTol ))
1388 break; //start edged found
1392 if (TangLast.IsParallel( RefTangLast, AngTol ) ||
1393 TangLast.IsParallel( RefTangFirst, AngTol ))
1394 break; //start edged found
1399 if (i > Edges.Length()) //start edged not found
1400 return Standard_False;
1402 if (V1onBound && V2onBound)
1404 if ((TangFirst.IsParallel(RefTangFirst,AngTol) && TangLast.IsParallel(RefTangLast,AngTol)) ||
1405 (TangFirst.IsParallel(RefTangLast,AngTol) && TangLast.IsParallel(RefTangFirst,AngTol)))
1407 TrueEdges.Add( Edges(i) );
1408 return Standard_True;
1411 return Standard_False;
1414 //StartEonF1 = (V1onBound)? VEmapF1( V1 ) : VEmapF1( V2 );
1415 //StartEonF2 = (V1onBound)? VEmapF2( V1 ) : VEmapF2( V2 );
1417 TrueEdges.Add( Edges(i) );
1419 Vcur = (V1onBound)? V2 : V1;
1420 TangCur = (V1onBound)? TangLast : TangFirst;
1424 //build the chain from StartEdge till the opposite bound of face
1427 TColStd_SequenceOfInteger Candidates;
1428 for (i = 1; i <= Edges.Length(); i++)
1430 TopoDS_Edge anEdge = TopoDS::Edge(Edges(i));
1431 TopExp::Vertices( anEdge, V1, V2 );
1432 if (V1.IsSame(Vcur) || V2.IsSame(Vcur))
1433 Candidates.Append(i);
1435 if (Candidates.IsEmpty())
1438 return Standard_False;
1441 Standard_Integer minind = 1;
1442 if (Candidates.Length() > 1)
1444 Standard_Real MinAngle = RealLast();
1445 for (i = 1; i <= Candidates.Length(); i++)
1447 TopoDS_Edge anEdge = TopoDS::Edge(Edges(Candidates(i)));
1448 TopExp::Vertices( anEdge, V1, V2 );
1449 Standard_Boolean ConnectByFirst = (Vcur.IsSame(V1))? Standard_True : Standard_False;
1450 BRepAdaptor_Curve CE(anEdge);
1451 gp_Vec aTang = (ConnectByFirst)?
1452 CE.DN( CE.FirstParameter(), 1 ) : CE.DN( CE.LastParameter(), 1 );
1453 if (!ConnectByFirst)
1455 Standard_Real anAngle = TangCur.Angle(aTang);
1456 if (anAngle < MinAngle)
1463 TopoDS_Edge CurEdge = TopoDS::Edge(Edges(Candidates(minind)));
1464 TrueEdges.Add( CurEdge );
1465 Edges.Remove(Candidates(minind));
1466 TopExp::Vertices( CurEdge, V1, V2 );
1467 Standard_Boolean ConnectByFirst = (Vcur.IsSame(V1))? Standard_True : Standard_False;
1468 Vcur = (ConnectByFirst)? V2 : V1;
1469 BRepAdaptor_Curve CE(CurEdge);
1470 TangCur = (ConnectByFirst)? CE.DN( CE.LastParameter(), 1 ) : CE.DN( CE.FirstParameter(), 1 );
1471 if (!ConnectByFirst)
1473 //check if Vcur is on bounds of faces
1474 if (VEmapF1.IsBound(Vcur) || VEmapF2.IsBound(Vcur))
1478 if (TangCur.IsParallel( RefTangFirst, AngTol ) ||
1479 TangCur.IsParallel( RefTangLast, AngTol ))
1480 return Standard_True;
1483 return Standard_False;
1486 //=======================================================================
1487 //function : AssembleEdge
1489 //=======================================================================
1491 static TopoDS_Edge AssembleEdge(const BOPDS_PDS& pDS,
1492 const TopoDS_Face& F1,
1493 const TopoDS_Face& F2,
1494 const Standard_Boolean addPCurve1,
1495 const Standard_Boolean addPCurve2,
1496 const TopTools_SequenceOfShape& EdgesForConcat)
1498 TopoDS_Edge CurEdge = TopoDS::Edge( EdgesForConcat(1) );
1499 for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
1501 TopoDS_Edge anEdge = TopoDS::Edge( EdgesForConcat(j) );
1502 Standard_Boolean After = Standard_False;
1503 TopoDS_Vertex Vfirst, Vlast;
1504 if (AreClosed( CurEdge, anEdge ))
1506 TopoDS_Vertex V1, V2;
1507 TopExp::Vertices( CurEdge, V1, V2 );
1508 if (IsAutonomVertex( V1, pDS ))
1510 After = Standard_False;
1511 Vfirst = Vlast = V2;
1515 After = Standard_True;
1516 Vfirst = Vlast = V1;
1521 TopoDS_Vertex CV, V11, V12, V21, V22;
1522 TopExp::CommonVertex( CurEdge, anEdge, CV );
1523 TopExp::Vertices( CurEdge, V11, V12 );
1524 TopExp::Vertices( anEdge, V21, V22 );
1525 if (V11.IsSame(CV) && V21.IsSame(CV))
1530 else if (V11.IsSame(CV) && V22.IsSame(CV))
1535 else if (V12.IsSame(CV) && V21.IsSame(CV))
1545 } //end of else (open wire)
1547 TopoDS_Edge NewEdge = Glue(CurEdge, anEdge,
1548 Vfirst, Vlast, After,
1549 F1, addPCurve1, F2, addPCurve2);
1551 } //end of for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
1556 //=======================================================================
1557 //function : Inter3D
1559 //=======================================================================
1561 void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1,
1562 const TopoDS_Face& F2,
1563 TopTools_ListOfShape& L1,
1564 TopTools_ListOfShape& L2,
1565 const TopAbs_State Side,
1566 const TopoDS_Edge& RefEdge,
1567 const Standard_Boolean IsRefEdgeDefined)
1572 sprintf(name,"FF_%d",NbFaces++);
1573 DBRep::Set(name,F1);
1574 sprintf(name,"FF_%d",NbFaces++);
1575 DBRep::Set(name,F2);
1579 TopoDS_Face cpF1=F1;
1580 TopoDS_Face cpF2=F2;
1581 // create 3D curves on faces
1582 BRepLib::BuildCurves3d(cpF1);
1583 BRepLib::BuildCurves3d(cpF2);
1585 BOPAlgo_PaveFiller aPF1, aPF2;
1586 BOPCol_ListOfShape aLS;
1589 aPF1.SetArguments(aLS);
1593 BOPAlgo_PaveFiller *pPF = &aPF1;
1596 TopTools_IndexedMapOfShape TrueEdges;
1597 if (IsRefEdgeDefined && !CheckIntersFF( pPF->PDS(), RefEdge, cpF1, cpF2, TrueEdges ))
1603 aPF2.SetArguments(aLS);
1606 CheckIntersFF( pPF->PDS(), RefEdge, cpF1, cpF2, TrueEdges );
1609 Standard_Boolean addPCurve1 = 1;
1610 Standard_Boolean addPCurve2 = 1;
1612 const BOPDS_PDS& pDS = pPF->PDS();
1613 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
1614 Standard_Integer aNb = aFFs.Extent();
1615 Standard_Integer i = 0, j = 0, k;
1617 L1.Clear(); L2.Clear();
1618 TopAbs_Orientation O1,O2;
1620 for (i = 0; i < aNb; i++) {
1621 BOPDS_InterfFF& aFFi=aFFs(i);
1622 const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
1624 Standard_Integer aNbCurves = aBCurves.Extent();
1626 for (j = 0; j < aNbCurves; j++) {
1627 const BOPDS_Curve& aBC=aBCurves(j);
1628 const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
1630 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1631 aPBIt.Initialize(aSectEdges);
1633 for (; aPBIt.More(); aPBIt.Next()) {
1634 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
1635 Standard_Integer nSect = aPB->Edge();
1636 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
1637 if (!TrueEdges.IsEmpty() && !TrueEdges.Contains(anEdge))
1641 const Handle(Geom_Curve)& aC3DE = BRep_Tool::Curve(anEdge, f, l);
1642 Handle(Geom_TrimmedCurve) aC3DETrim;
1645 aC3DETrim = new Geom_TrimmedCurve(aC3DE, f, l);
1648 Standard_Real aTolEdge = BRep_Tool::Tolerance(anEdge);
1650 if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, cpF1)) {
1651 Handle(Geom2d_Curve) aC2d = aBC.Curve().FirstCurve2d();
1652 if(!aC3DETrim.IsNull()) {
1653 Handle(Geom2d_Curve) aC2dNew;
1655 if(aC3DE->IsPeriodic()) {
1656 BOPTools_AlgoTools2D::AdjustPCurveOnFace(cpF1, f, l, aC2d, aC2dNew);
1659 BOPTools_AlgoTools2D::AdjustPCurveOnFace(cpF1, aC3DETrim, aC2d, aC2dNew);
1663 aBB.UpdateEdge(anEdge, aC2d, cpF1, aTolEdge);
1666 if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, cpF2)) {
1667 Handle(Geom2d_Curve) aC2d = aBC.Curve().SecondCurve2d();
1668 if(!aC3DETrim.IsNull()) {
1669 Handle(Geom2d_Curve) aC2dNew;
1671 if(aC3DE->IsPeriodic()) {
1672 BOPTools_AlgoTools2D::AdjustPCurveOnFace(cpF2, f, l, aC2d, aC2dNew);
1675 BOPTools_AlgoTools2D::AdjustPCurveOnFace(cpF2, aC3DETrim, aC2d, aC2dNew);
1679 aBB.UpdateEdge(anEdge, aC2d, cpF2, aTolEdge);
1682 OrientSection (anEdge, F1, F2, O1, O2);
1683 if (Side == TopAbs_OUT) {
1684 O1 = TopAbs::Reverse(O1);
1685 O2 = TopAbs::Reverse(O2);
1688 L1.Append (anEdge.Oriented(O1));
1689 L2.Append (anEdge.Oriented(O2));
1694 sprintf(name,"EI_%d",NbNewEdges++);
1695 DBRep::Set(name,anEdge.Oriented(O1));
1703 Standard_Real aSameParTol = Precision::Confusion();
1704 Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
1706 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(cpF1);
1707 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1708 aSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&aSurf))->BasisSurface();
1709 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1710 addPCurve1 = Standard_False;
1711 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1712 isEl1 = Standard_True;
1714 aSurf = BRep_Tool::Surface(cpF2);
1715 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1716 aSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&aSurf))->BasisSurface();
1717 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1718 addPCurve2 = Standard_False;
1719 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1720 isEl2 = Standard_True;
1722 if (L1.Extent() > 1 && (!isEl1 || !isEl2)) {
1723 TopTools_SequenceOfShape eseq;
1724 TopTools_SequenceOfShape EdgesForConcat;
1726 if (!TrueEdges.IsEmpty())
1728 for (i = TrueEdges.Extent(); i >= 1; i--)
1729 EdgesForConcat.Append( TrueEdges(i) );
1730 TopoDS_Edge theEdge =
1731 AssembleEdge( pDS, cpF1, cpF2, addPCurve1, addPCurve2, EdgesForConcat );
1732 eseq.Append(theEdge);
1737 TopTools_SequenceOfShape wseq;
1738 TopTools_SequenceOfShape edges;
1739 TopTools_ListIteratorOfListOfShape itl(L1);
1740 for (; itl.More(); itl.Next())
1741 edges.Append( itl.Value() );
1742 while (!edges.IsEmpty())
1744 TopoDS_Edge anEdge = TopoDS::Edge( edges.First() );
1745 TopoDS_Wire aWire = BRepLib_MakeWire( anEdge ), resWire;
1746 TColStd_SequenceOfInteger Candidates;
1747 for (k = 1; k <= wseq.Length(); k++)
1749 resWire = TopoDS::Wire(wseq(k));
1750 if (AreConnex( resWire, aWire, pDS ))
1752 Candidates.Append( 1 );
1756 if (Candidates.IsEmpty())
1758 wseq.Append( aWire );
1763 for (j = 2; j <= edges.Length(); j++)
1765 anEdge = TopoDS::Edge( edges(j) );
1766 //if (anEdge.IsSame(edges(Candidates.First())))
1768 aWire = BRepLib_MakeWire( anEdge );
1769 if (AreConnex( resWire, aWire, pDS ))
1770 Candidates.Append( j );
1772 Standard_Integer minind = 1;
1773 if (Candidates.Length() > 1)
1775 Standard_Real MinAngle = RealLast();
1776 for (j = 1; j <= Candidates.Length(); j++)
1778 anEdge = TopoDS::Edge( edges(Candidates(j)) );
1779 Standard_Real anAngle = AngleWireEdge( resWire, anEdge );
1780 if (anAngle < MinAngle)
1787 TopoDS_Wire NewWire = BRepLib_MakeWire( resWire, TopoDS::Edge(edges(Candidates(minind))) );
1789 edges.Remove(Candidates(minind));
1791 } //end of while (!edges.IsEmpty())
1793 for (i = 1; i <= wseq.Length(); i++)
1795 TopoDS_Wire aWire = TopoDS::Wire(wseq(i));
1796 TopTools_SequenceOfShape EdgesForConcat;
1799 TopoDS_Vertex StartVertex;
1800 TopoDS_Edge StartEdge;
1801 Standard_Boolean StartFound = Standard_False;
1802 TopTools_ListOfShape Elist;
1804 TopoDS_Iterator itw(aWire);
1805 for (; itw.More(); itw.Next())
1807 TopoDS_Edge anEdge = TopoDS::Edge(itw.Value());
1809 Elist.Append(anEdge);
1812 TopoDS_Vertex V1, V2;
1813 TopExp::Vertices( anEdge, V1, V2 );
1814 if (!IsAutonomVertex( V1, pDS ))
1818 StartFound = Standard_True;
1820 else if (!IsAutonomVertex( V2, pDS ))
1824 StartFound = Standard_True;
1827 Elist.Append(anEdge);
1829 } //end of for (; itw.More(); itw.Next())
1832 itl.Initialize(Elist);
1833 StartEdge = TopoDS::Edge(itl.Value());
1835 TopoDS_Vertex V1, V2;
1836 TopExp::Vertices( StartEdge, V1, V2 );
1839 EdgesForConcat.Append( StartEdge );
1840 while (!Elist.IsEmpty())
1842 for (itl.Initialize(Elist); itl.More(); itl.Next())
1844 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
1845 TopoDS_Vertex V1, V2;
1846 TopExp::Vertices( anEdge, V1, V2 );
1847 if (V1.IsSame(StartVertex))
1850 EdgesForConcat.Append( anEdge );
1854 else if (V2.IsSame(StartVertex))
1857 EdgesForConcat.Append( anEdge );
1862 } //end of while (!Elist.IsEmpty())
1863 } //end of if (aWire.Closed())
1866 BRepTools_WireExplorer Wexp( aWire );
1867 for (; Wexp.More(); Wexp.Next())
1868 EdgesForConcat.Append( Wexp.Current() );
1871 TopoDS_Edge theEdge =
1872 AssembleEdge( pDS, cpF1, cpF2, addPCurve1, addPCurve2, EdgesForConcat );
1873 eseq.Append( theEdge );
1875 } //end of else (when TrueEdges is empty)
1877 if (eseq.Length() < L1.Extent())
1881 for (i = 1; i <= eseq.Length(); i++)
1883 TopoDS_Edge anEdge = TopoDS::Edge(eseq(i));
1884 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1885 Standard_Real EdgeTol = BRep_Tool::Tolerance(anEdge);
1887 cout<<"Tolerance of glued E = "<<EdgeTol<<endl;
1889 if (EdgeTol > 1.e-2)
1892 if (EdgeTol >= 1.e-4)
1894 ReconstructPCurves(anEdge);
1895 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1897 cout<<"After projection tol of E = "<<BRep_Tool::Tolerance(anEdge)<<endl;
1901 OrientSection( anEdge, F1, F2, O1, O2 );
1902 if (Side == TopAbs_OUT)
1904 O1 = TopAbs::Reverse(O1);
1905 O2 = TopAbs::Reverse(O2);
1908 L1.Append( anEdge.Oriented(O1) );
1909 L2.Append( anEdge.Oriented(O2) );
1912 } //end of if (L1.Extent() > 1)
1916 TopTools_ListIteratorOfListOfShape itl(L1);
1917 for (; itl.More(); itl.Next())
1919 const TopoDS_Edge& anEdge = TopoDS::Edge( itl.Value() );
1920 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1925 //=======================================================================
1926 //function : TryProject
1928 //=======================================================================
1930 Standard_Boolean BRepOffset_Tool::TryProject
1931 (const TopoDS_Face& F1,
1932 const TopoDS_Face& F2,
1933 const TopTools_ListOfShape& Edges,
1934 TopTools_ListOfShape& LInt1,
1935 TopTools_ListOfShape& LInt2,
1936 const TopAbs_State Side,
1937 const Standard_Real TolConf)
1942 sprintf(name,"FF_%d",NbFaces++);
1943 DBRep::Set(name,F1);
1944 sprintf(name,"FF_%d",NbFaces++);
1945 DBRep::Set(name,F2);
1949 // try to find if the edges <Edges> are laying on the face F1.
1950 LInt1.Clear(); LInt2.Clear();
1951 TopTools_ListIteratorOfListOfShape it(Edges);
1952 Standard_Boolean isOk = Standard_True;
1953 Standard_Boolean Ok = Standard_True;
1954 TopAbs_Orientation O1,O2;
1955 Handle(Geom_Surface) Bouchon = BRep_Tool::Surface(F1);
1958 for ( ; it.More(); it.Next()) {
1961 TopoDS_Edge CurE = TopoDS::Edge(it.Value());
1962 Handle(Geom_Curve) C = BRep_Tool::Curve(CurE,L,f,l);
1964 BRepLib::BuildCurve3d(CurE,BRep_Tool::Tolerance(CurE));
1965 C = BRep_Tool::Curve(CurE,L,f,l);
1967 C = new Geom_TrimmedCurve(C,f,l);
1968 if ( !L.IsIdentity()) C->Transform(L);
1969 Standard_Real TolReached;
1970 isOk = IsOnSurface(C,Bouchon,TolConf,TolReached);
1973 B.UpdateEdge(CurE,TolReached);
1974 BuildPCurves(CurE,F1);
1975 OrientSection (CurE,F1,F2,O1,O2);
1976 if (Side == TopAbs_OUT) {
1977 O1 = TopAbs::Reverse(O1);
1978 O2 = TopAbs::Reverse(O2);
1980 LInt1.Append (CurE.Oriented(O1));
1981 LInt2.Append (CurE.Oriented(O2));
1985 sprintf(name,"EI_%d",NbNewEdges++);
1986 DBRep::Set(name,CurE.Oriented(O1));
1991 Ok = Standard_False;
1997 //=======================================================================
1998 //function : InterOrExtent
2000 //=======================================================================
2002 void BRepOffset_Tool::InterOrExtent(const TopoDS_Face& F1,
2003 const TopoDS_Face& F2,
2004 TopTools_ListOfShape& L1,
2005 TopTools_ListOfShape& L2,
2006 const TopAbs_State Side)
2011 sprintf(name,"FF_%d",NbFaces++);
2012 DBRep::Set(name,F1);
2013 sprintf(name,"FF_%d",NbFaces++);
2014 DBRep::Set(name,F2);
2018 Handle (Geom_Curve) CI;
2020 TopAbs_Orientation O1,O2;
2021 L1.Clear(); L2.Clear();
2022 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
2023 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
2025 if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2026 Handle(Geom_RectangularTrimmedSurface) RTS ;
2027 RTS = *((Handle(Geom_RectangularTrimmedSurface)*) &S1);
2028 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
2029 S1 = RTS->BasisSurface();
2032 if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2033 Handle(Geom_RectangularTrimmedSurface) RTS ;
2034 RTS = *((Handle(Geom_RectangularTrimmedSurface)*) &S2);
2035 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
2036 S2 = RTS->BasisSurface();
2040 GeomInt_IntSS Inter (S1,S2, Precision::Confusion());
2042 if (Inter.IsDone()) {
2043 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
2046 if (ToSmall(CI)) continue;
2047 TopoDS_Edge E = BRepLib_MakeEdge(CI);
2048 BuildPCurves (E,F1);
2049 BuildPCurves (E,F2);
2050 OrientSection (E,F1,F2,O1,O2);
2051 if (Side == TopAbs_OUT) {
2052 O1 = TopAbs::Reverse(O1);
2053 O2 = TopAbs::Reverse(O2);
2055 L1.Append (E.Oriented(O1));
2056 L2.Append (E.Oriented(O2));
2060 sprintf(name,"EI_%d",NbNewEdges++);
2061 DBRep::Set(name,E.Oriented(O1));
2068 //=======================================================================
2069 //function : ExtentEdge
2071 //=======================================================================
2073 static void ExtentEdge(const TopoDS_Face& F,
2074 const TopoDS_Face& EF,
2075 const TopoDS_Edge& E,
2078 BRepAdaptor_Curve CE(E);
2079 GeomAbs_CurveType Type = CE.GetType();
2080 TopoDS_Shape aLocalEdge = E.EmptyCopied();
2081 NE = TopoDS::Edge(aLocalEdge);
2082 // NE = TopoDS::Edge(E.EmptyCopied());
2084 if (Type == GeomAbs_Line || Type == GeomAbs_Circle || Type == GeomAbs_Ellipse ||
2085 Type == GeomAbs_Hyperbola || Type == GeomAbs_Parabola) {
2088 // Extension en tangence jusqu'au bord de la surface.
2089 Standard_Real PMax = 1.e2;
2091 Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
2092 Standard_Real umin,umax,vmin,vmax;
2094 S->Bounds(umin,umax,vmin,vmax);
2095 umin = Max(umin,-PMax);vmin = Max(vmin,-PMax);
2096 umax = Min(umax, PMax);vmax = Min(vmax, PMax);
2100 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f,l);
2102 //calcul point cible . ie point d'intersection du prolongement tangent et des bords.
2105 C2d->D1(CE.FirstParameter(),P,Tang);
2106 Standard_Real tx,ty,tmin;
2107 tx = ty = Precision::Infinite();
2108 if (Abs(Tang.X()) > Precision::Confusion())
2109 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
2110 if (Abs(Tang.Y()) > Precision::Confusion())
2111 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
2114 gp_Pnt2d PF2d (P.X() - Tang.X(),P.Y() - Tang.Y());
2116 C2d->D1(CE.LastParameter(),P,Tang);
2117 tx = ty = Precision::Infinite();
2118 if (Abs(Tang.X()) > Precision::Confusion())
2119 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
2120 if (Abs(Tang.Y()) > Precision::Confusion())
2121 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
2124 gp_Pnt2d PL2d (P.X() + Tang.X(),P.Y() + Tang.Y());
2126 Handle(Geom_Curve) CC = GeomAPI::To3d(C2d,gp_Pln(gp::XOY()));
2127 gp_Pnt PF(PF2d.X(),PF2d.Y(),0.);
2128 gp_Pnt PL(PL2d.X(),PL2d.Y(),0.);
2130 Handle(Geom_BoundedCurve) ExtC = Handle(Geom_BoundedCurve)::DownCast(CC);
2131 if (ExtC.IsNull()) return;
2133 GeomLib::ExtendCurveToPoint(ExtC,PF,1,0);
2134 GeomLib::ExtendCurveToPoint(ExtC,PL,1,1);
2136 Handle(Geom2d_Curve) CNE2d = GeomAPI::To2d(ExtC,gp_Pln(gp::XOY()));
2138 //Construction de la nouvelle arrete;
2141 // B.UpdateEdge (NE,CNE2d,F,BRep_Tool::Tolerance(E));
2142 B.UpdateEdge (NE,CNE2d,EF,BRep_Tool::Tolerance(E));
2143 B.Range (NE,CNE2d->FirstParameter(), CNE2d->LastParameter());
2144 NE.Orientation(E.Orientation());
2148 sprintf (name,"F_%d",NbExtE);
2149 DBRep::Set(name,EF);
2150 sprintf (name,"OE_%d",NbExtE);
2151 DBRep::Set (name,E);
2152 sprintf (name,"ExtE_%d",NbExtE++);
2153 DBRep::Set(name,NE);
2158 //=======================================================================
2159 //function : ProjectVertexOnEdge
2161 //=======================================================================
2163 static Standard_Boolean ProjectVertexOnEdge(TopoDS_Vertex& V,
2164 const TopoDS_Edge& E,
2165 Standard_Real TolConf)
2175 Standard_Real U = 0.;
2177 Standard_Boolean found = Standard_False;
2179 gp_Pnt P = BRep_Tool::Pnt (V);
2180 BRepAdaptor_Curve C = BRepAdaptor_Curve(E);
2181 f = C.FirstParameter(); l = C.LastParameter();
2183 if (V.Orientation() == TopAbs_FORWARD) {
2184 if (Abs(f) < Precision::Infinite()) {
2185 gp_Pnt PF = C.Value (f);
2186 if (PF.IsEqual(P,TolConf)) {
2188 found = Standard_True;
2192 if (V.Orientation() == TopAbs_REVERSED) {
2193 if (!found && Abs(l) < Precision::Infinite()) {
2194 gp_Pnt PL = C.Value (l);
2195 if (PL.IsEqual(P,TolConf)) {
2197 found = Standard_True;
2202 Extrema_ExtPC Proj(P,C);
2203 if (Proj.IsDone() && Proj.NbExt() > 0) {
2204 Standard_Real Dist2,Dist2Min = Proj.SquareDistance(1);
2205 U = Proj.Point(1).Parameter();
2206 for (Standard_Integer i = 2; i <= Proj.NbExt(); i++) {
2207 Dist2 = Proj.SquareDistance(i);
2208 if (Dist2 < Dist2Min) {
2210 U = Proj.Point(i).Parameter();
2213 found = Standard_True;
2219 Standard_Real Dist = P.Distance(C.Value(U));
2220 if (Dist > TolConf) {
2221 cout << " ProjectVertexOnEdge :distance vertex edge :"<<Dist<<endl;
2223 if (U < f - Precision::Confusion() ||
2224 U > l + Precision::Confusion()) {
2225 cout << " ProjectVertexOnEdge : hors borne :"<<endl;
2226 cout << " f = "<<f<<" l ="<<l<< " U ="<<U<<endl;
2230 cout <<"BRepOffset_Tool::ProjectVertexOnEdge Parameter no found"<<endl;
2231 if (Abs(f) < Precision::Infinite() &&
2232 Abs(l) < Precision::Infinite()) {
2240 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
2241 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
2242 aLocalShape = V.Oriented(TopAbs_INTERNAL);
2243 // TopoDS_Edge EE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
2244 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
2245 U,EE,BRep_Tool::Tolerance(E));
2251 //=======================================================================
2252 //function : Inter2d
2254 //=======================================================================
2256 void BRepOffset_Tool::Inter2d (const TopoDS_Face& F,
2257 const TopoDS_Edge& E1,
2258 const TopoDS_Edge& E2,
2259 TopTools_ListOfShape& LV,
2260 const Standard_Real TolConf)
2264 DBRep::Set("E1",E1);
2265 DBRep::Set("E2",E2);
2270 Standard_Real fl1[2],fl2[2];
2273 // Si l edge a ete etendu les pcurves ne sont pas forcement
2279 // Construction des curves 3d si elles n existent pas
2280 // utile pour coder correctement les parametres des vertex
2281 // d intersection sur les edges.
2282 //TopLoc_Location L;
2283 //Standard_Real f,l;
2284 //Handle(Geom_Curve) C3d1 = BRep_Tool::Curve(E1,L,f,l);
2285 //if (C3d1.IsNull()) {
2286 // BRepLib::BuildCurve3d(E1,BRep_Tool::Tolerance(E1));
2288 //Handle(Geom_Curve) C3d2 = BRep_Tool::Curve(E2,L,f,l);
2289 //if (C3d2.IsNull()) {
2290 // BRepLib::BuildCurve3d(E2,BRep_Tool::Tolerance(E2));
2293 Standard_Integer NbPC1 = 1, NbPC2 = 1;
2294 if (BRep_Tool::IsClosed(E1,F)) NbPC1++;
2295 if (BRep_Tool::IsClosed(E2,F)) NbPC2++;
2297 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
2298 Handle(Geom2d_Curve) C1, C2;
2299 Standard_Boolean YaSol = Standard_False;
2300 Standard_Integer itry = 0;
2302 while (!YaSol && itry < 2) {
2303 for ( Standard_Integer i = 1; i <= NbPC1 ; i++) {
2304 TopoDS_Shape aLocalEdge = E1.Reversed();
2305 if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
2306 else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdge),
2308 // if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
2309 // else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E1.Reversed()),
2310 // F,fl1[0],fl1[1]);
2311 for ( Standard_Integer j = 1; j <= NbPC2; j++ ) {
2312 TopoDS_Shape aLocalEdge = E2.Reversed();
2313 if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2314 else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdge),
2316 // if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2317 // else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E2.Reversed()),
2318 // F,fl2[0],fl2[1]);
2320 if (C1.IsNull() || C2.IsNull()) {
2321 cout <<"Inter2d : Pas de pcurve"<<endl;
2323 DBRep::Set("E1",E1);
2324 DBRep::Set("E2",E2);
2330 Standard_Real U1 = 0.,U2 = 0.;
2333 fl1[0] = C1->FirstParameter(); fl1[1] = C1->LastParameter();
2334 fl2[0] = C2->FirstParameter(); fl2[1] = C2->LastParameter();
2336 Geom2dAdaptor_Curve AC1(C1,fl1[0],fl1[1]);
2337 Geom2dAdaptor_Curve AC2(C2,fl2[0],fl2[1]);
2340 gp_Pnt2d P1[2],P2[2];
2341 P1[0] = C1->Value(fl1[0]); P1[1] = C1->Value(fl1[1]);
2342 P2[0] = C2->Value(fl2[0]); P2[1] = C2->Value(fl2[1]);
2344 Standard_Integer i1 ;
2345 for ( i1 = 0; i1 < 2; i1++) {
2346 for (Standard_Integer i2 = 0; i2 < 2; i2++) {
2347 if (Abs(fl1[i1]) < Precision::Infinite() &&
2348 Abs(fl2[i2]) < Precision::Infinite() ) {
2349 if (P1[i1].IsEqual(P2[i2],TolConf)) {
2350 YaSol = Standard_True;
2351 U1 = fl1[i1]; U2 = fl2[i2];
2352 P2d = C1->Value(U1);
2358 for (i1 = 0; i1 < 2; i1++)
2360 Extrema_ExtPC2d extr( P1[i1], AC2 );
2361 if (extr.IsDone() && extr.NbExt() > 0)
2363 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2364 Standard_Integer IndexMin = 1;
2365 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2367 Dist2 = extr.SquareDistance(ind);
2368 if (Dist2 < Dist2Min)
2374 if (Dist2Min <= Precision::SquareConfusion())
2376 YaSol = Standard_True;
2379 U2 = (extr.Point(IndexMin)).Parameter();
2385 for (Standard_Integer i2 = 0; i2 < 2; i2++)
2387 Extrema_ExtPC2d extr( P2[i2], AC1 );
2388 if (extr.IsDone() && extr.NbExt() > 0)
2390 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2391 Standard_Integer IndexMin = 1;
2392 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2394 Dist2 = extr.SquareDistance(ind);
2395 if (Dist2 < Dist2Min)
2401 if (Dist2Min <= Precision::SquareConfusion())
2403 YaSol = Standard_True;
2406 U1 = (extr.Point(IndexMin)).Parameter();
2414 Geom2dInt_GInter Inter (AC1,AC2,TolConf,TolConf);
2416 if (!Inter.IsEmpty() && Inter.NbPoints() > 0) {
2417 YaSol = Standard_True;
2418 U1 = Inter.Point(1).ParamOnFirst();
2419 U2 = Inter.Point(1).ParamOnSecond();
2420 P2d = Inter.Point(1).Value();
2422 else if (!Inter.IsEmpty() && Inter.NbSegments() > 0) {
2423 YaSol = Standard_True;
2424 IntRes2d_IntersectionSegment Seg = Inter.Segment(1);
2425 IntRes2d_IntersectionPoint IntP1 = Seg.FirstPoint();
2426 IntRes2d_IntersectionPoint IntP2 = Seg.LastPoint();
2427 Standard_Real U1on1 = IntP1.ParamOnFirst();
2428 Standard_Real U1on2 = IntP2.ParamOnFirst();
2429 Standard_Real U2on1 = IntP1.ParamOnSecond();
2430 Standard_Real U2on2 = IntP2.ParamOnSecond();
2432 cout << " BRepOffset_Tool::Inter2d SEGMENT d intersection" << endl;
2433 cout << " ===> Parametres sur Curve1 : ";
2434 cout << U1on1 << " " << U1on2 << endl;
2435 cout << " ===> Parametres sur Curve2 : ";
2436 cout << U2on1 << " " << U2on2 << endl;
2438 U1 = (U1on1 + U1on2)/2.;
2439 U2 = (U2on1 + U2on2)/2.;
2440 gp_Pnt2d P2d1 = C1->Value(U1);
2441 gp_Pnt2d P2d2 = C2->Value(U2);
2442 P2d.SetX( (P2d1.X() + P2d2.X()) / 2.);
2443 P2d.SetY( (P2d1.Y() + P2d2.Y()) / 2.);
2447 gp_Pnt P = S->Value(P2d.X(),P2d.Y());
2448 TopoDS_Vertex V = BRepLib_MakeVertex(P);
2449 V.Orientation(TopAbs_INTERNAL);
2450 TopoDS_Shape aLocalEdge = E1.Oriented(TopAbs_FORWARD);
2451 B.UpdateVertex(V,U1,TopoDS::Edge(aLocalEdge),TolConf);
2452 aLocalEdge = E2.Oriented(TopAbs_FORWARD);
2453 B.UpdateVertex(V,U2,TopoDS::Edge(aLocalEdge),TolConf);
2454 // B.UpdateVertex(V,U1,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)),TolConf);
2455 // B.UpdateVertex(V,U2,TopoDS::Edge(E2.Oriented(TopAbs_FORWARD)),TolConf);
2463 if (LV.Extent() > 1) {
2464 //------------------------------------------------
2465 // garde seulement les vertex les plus proches du
2466 //debut et de la fin.
2467 //------------------------------------------------
2468 TopTools_ListIteratorOfListOfShape it(LV);
2469 TopoDS_Vertex VF,VL;
2470 Standard_Real UMin = Precision::Infinite();
2471 Standard_Real UMax = -Precision::Infinite();
2474 for ( ; it.More(); it.Next()) {
2475 TopoDS_Vertex CV = TopoDS::Vertex(it.Value());
2476 TopoDS_Shape aLocalEdge = E1.Oriented(TopAbs_FORWARD);
2477 U = BRep_Tool::Parameter(CV,TopoDS::Edge(aLocalEdge));
2478 // U = BRep_Tool::Parameter(CV,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)));
2486 LV.Clear();LV.Append(VF); LV.Append(VL);
2491 cout <<"Inter2d : Pas de solution"<<endl;
2493 DBRep::Set("E1",E1);
2494 DBRep::Set("E2",E2);
2501 //=======================================================================
2502 //function : SelectEdge
2504 //=======================================================================
2506 static void SelectEdge (const TopoDS_Face& /*F*/,
2507 const TopoDS_Face& /*EF*/,
2508 const TopoDS_Edge& E,
2509 TopTools_ListOfShape& LInt)
2511 //------------------------------------------------------------
2512 // detrompeur sur les intersections sur les faces periodiques
2513 //------------------------------------------------------------
2514 TopTools_ListIteratorOfListOfShape it(LInt);
2515 Standard_Real dU = 1.0e100;
2518 Standard_Real Fst, Lst, tmp;
2519 BRep_Tool::Range(E, Fst, Lst);
2520 BRepAdaptor_Curve Ad1(E);
2522 gp_Pnt PFirst = Ad1.Value( Fst );
2523 gp_Pnt PLast = Ad1.Value( Lst );
2525 //----------------------------------------------------------------------
2526 // Selection de l edge qui couvre le plus le domaine de l edge initiale.
2527 //----------------------------------------------------------------------
2528 for (; it.More(); it.Next()) {
2529 const TopoDS_Edge& EI = TopoDS::Edge(it.Value());
2531 BRep_Tool::Range(EI, Fst, Lst);
2532 BRepAdaptor_Curve Ad2(EI);
2533 gp_Pnt P1 = Ad2.Value(Fst);
2534 gp_Pnt P2 = Ad2.Value(Lst);
2536 tmp = P1.Distance(PFirst) + P2.Distance(PLast);
2548 //=======================================================================
2551 //=======================================================================
2553 static void MakeFace(const Handle(Geom_Surface)& S,
2554 const Standard_Real Um,
2555 const Standard_Real UM,
2556 const Standard_Real Vm,
2557 const Standard_Real VM,
2558 const Standard_Boolean isVminDegen,
2559 const Standard_Boolean isVmaxDegen,
2562 Standard_Real UMin = Um;
2563 Standard_Real UMax = UM;
2564 Standard_Real VMin = Vm;
2565 Standard_Real VMax = VM;
2566 Standard_Real epsilon = Precision::Confusion();
2568 Standard_Real umin,umax,vmin,vmax;
2569 S->Bounds(umin,umax,vmin,vmax);
2572 // compute infinite flags
2573 Standard_Boolean umininf = Precision::IsNegativeInfinite(UMin);
2574 Standard_Boolean umaxinf = Precision::IsPositiveInfinite(UMax);
2575 Standard_Boolean vmininf = Precision::IsNegativeInfinite(VMin);
2576 Standard_Boolean vmaxinf = Precision::IsPositiveInfinite(VMax);
2579 Standard_Boolean IsSuclosed = S->IsUClosed(), IsSvclosed = S->IsVClosed();
2580 if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2582 Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&S))->BasisSurface();
2583 IsSuclosed = BasisSurf->IsUClosed();
2584 IsSvclosed = BasisSurf->IsVClosed();
2587 Standard_Boolean uclosed =
2589 Abs(UMin - umin) < epsilon &&
2590 Abs(UMax - umax) < epsilon;
2592 Standard_Boolean vclosed =
2594 Abs(VMin - vmin) < epsilon &&
2595 Abs(VMax - vmax) < epsilon;
2597 // degenerated flags (for cones)
2598 Standard_Boolean vmindegen = isVminDegen, vmaxdegen = isVmaxDegen;
2599 Handle(Geom_Surface) theSurf = S;
2600 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
2601 theSurf = (*(Handle(Geom_RectangularTrimmedSurface)*)&S)->BasisSurface();
2602 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
2604 Handle(Geom_ConicalSurface) ConicalS = *((Handle(Geom_ConicalSurface)*) &theSurf);
2605 gp_Cone theCone = ConicalS->Cone();
2606 gp_Pnt theApex = theCone.Apex();
2607 Standard_Real Uapex, Vapex;
2608 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
2609 if (Abs(VMin - Vapex) <= Precision::Confusion())
2610 vmindegen = Standard_True;
2611 if (Abs(VMax - Vapex) <= Precision::Confusion())
2612 vmaxdegen = Standard_True;
2617 Standard_Real tol = Precision::Confusion();
2619 TopoDS_Vertex V00,V10,V11,V01;
2622 if (!vmininf) B.MakeVertex(V00,S->Value(UMin,VMin),tol);
2623 if (!vmaxinf) B.MakeVertex(V01,S->Value(UMin,VMax),tol);
2626 if (!vmininf) B.MakeVertex(V10,S->Value(UMax,VMin),tol);
2627 if (!vmaxinf) B.MakeVertex(V11,S->Value(UMax,VMax),tol);
2646 Handle(Geom2d_Line) Lumin,Lumax,Lvmin,Lvmax;
2648 Lumin = new Geom2d_Line(gp_Pnt2d(UMin,0),gp_Dir2d(0,1));
2650 Lumax = new Geom2d_Line(gp_Pnt2d(UMax,0),gp_Dir2d(0,1));
2652 Lvmin = new Geom2d_Line(gp_Pnt2d(0,VMin),gp_Dir2d(1,0));
2654 Lvmax = new Geom2d_Line(gp_Pnt2d(0,VMax),gp_Dir2d(1,0));
2656 Handle(Geom_Curve) Cumin,Cumax,Cvmin,Cvmax;
2657 Standard_Real TolApex = 1.e-5;
2658 //Standard_Boolean hasiso = ! S->IsKind(STANDARD_TYPE(Geom_OffsetSurface));
2659 Standard_Boolean hasiso = S->IsKind(STANDARD_TYPE(Geom_ElementarySurface));
2662 Cumin = S->UIso(UMin);
2664 Cumax = S->UIso(UMax);
2667 Cvmin = S->VIso(VMin);
2668 if (BRepOffset_Tool::Gabarit( Cvmin ) <= TolApex)
2669 vmindegen = Standard_True;
2673 Cvmax = S->VIso(VMax);
2674 if (BRepOffset_Tool::Gabarit( Cvmax ) <= TolApex)
2675 vmaxdegen = Standard_True;
2680 B.MakeFace(F,S,tol);
2683 TopoDS_Edge eumin,eumax,evmin,evmax;
2687 B.MakeEdge(eumin,Cumin,tol);
2691 B.UpdateEdge(eumin,Lumax,Lumin,F,tol);
2693 B.UpdateEdge(eumin,Lumin,F,tol);
2695 V00.Orientation(TopAbs_FORWARD);
2699 V01.Orientation(TopAbs_REVERSED);
2702 B.Range(eumin,VMin,VMax);
2710 B.MakeEdge(eumax,Cumax,tol);
2713 B.UpdateEdge(eumax,Lumax,F,tol);
2715 V10.Orientation(TopAbs_FORWARD);
2719 V11.Orientation(TopAbs_REVERSED);
2722 B.Range(eumax,VMin,VMax);
2727 if (hasiso && !vmindegen)
2728 B.MakeEdge(evmin,Cvmin,tol);
2732 B.UpdateEdge(evmin,Lvmin,Lvmax,F,tol);
2734 B.UpdateEdge(evmin,Lvmin,F,tol);
2736 V00.Orientation(TopAbs_FORWARD);
2740 V10.Orientation(TopAbs_REVERSED);
2743 B.Range(evmin,UMin,UMax);
2745 B.Degenerated(evmin, Standard_True);
2752 if (hasiso && !vmaxdegen)
2753 B.MakeEdge(evmax,Cvmax,tol);
2756 B.UpdateEdge(evmax,Lvmax,F,tol);
2758 V01.Orientation(TopAbs_FORWARD);
2762 V11.Orientation(TopAbs_REVERSED);
2765 B.Range(evmax,UMin,UMax);
2767 B.Degenerated(evmax, Standard_True);
2771 // make the wires and add them to the face
2772 eumin.Orientation(TopAbs_REVERSED);
2773 evmax.Orientation(TopAbs_REVERSED);
2777 if (!umininf && !umaxinf && vmininf && vmaxinf) {
2788 else if (umininf && umaxinf && !vmininf && !vmaxinf) {
2799 else if (!umininf || !umaxinf || !vmininf || !vmaxinf) {
2802 if (!umininf) B.Add(W,eumin);
2803 if (!vmininf) B.Add(W,evmin);
2804 if (!umaxinf) B.Add(W,eumax);
2805 if (!vmaxinf) B.Add(W,evmax);
2807 W.Closed(!umininf && !umaxinf && !vmininf && !vmaxinf);
2808 F.Closed(uclosed && vclosed);
2812 //=======================================================================
2813 //function : EnLargeGeometry
2815 //=======================================================================
2817 static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S,
2822 Standard_Boolean& IsV1degen,
2823 Standard_Boolean& IsV2degen,
2824 const Standard_Real uf1,
2825 const Standard_Real uf2,
2826 const Standard_Real vf1,
2827 const Standard_Real vf2,
2828 const Standard_Boolean GlobalEnlargeU,
2829 const Standard_Boolean GlobalEnlargeVfirst,
2830 const Standard_Boolean GlobalEnlargeVlast)
2832 const Standard_Real coeff = 4.;
2833 const Standard_Real TolApex = 1.e-5;
2835 Standard_Boolean SurfaceChange = Standard_False;
2836 if ( S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2837 Handle(Geom_Surface) BS = (*((Handle(Geom_RectangularTrimmedSurface)*)&S))->BasisSurface();
2838 EnlargeGeometry(BS,U1,U2,V1,V2,IsV1degen,IsV2degen,
2839 uf1,uf2,vf1,vf2,GlobalEnlargeU,GlobalEnlargeVfirst,GlobalEnlargeVlast);
2840 if (!GlobalEnlargeVfirst)
2842 if (!GlobalEnlargeVlast)
2844 if (!GlobalEnlargeVfirst || !GlobalEnlargeVlast)
2845 //(*((Handle(Geom_RectangularTrimmedSurface)*)&S))->SetTrim( U1, U2, V1, V2 );
2846 S = new Geom_RectangularTrimmedSurface( BS, U1, U2, V1, V2 );
2849 SurfaceChange = Standard_True;
2851 else if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)) {
2852 Handle(Geom_Surface) Surf = (*((Handle(Geom_OffsetSurface)*)&S))->BasisSurface();
2853 SurfaceChange = EnlargeGeometry(Surf,U1,U2,V1,V2,IsV1degen,IsV2degen,
2854 uf1,uf2,vf1,vf2,GlobalEnlargeU,GlobalEnlargeVfirst,GlobalEnlargeVlast);
2855 Handle(Geom_OffsetSurface)::DownCast(S)->SetBasisSurface(Surf);
2857 else if (S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
2858 S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution))
2860 Standard_Real du=0., dv=0.;
2861 Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
2862 Standard_Real u1, u2, v1, v2;
2863 Standard_Boolean enlargeU = GlobalEnlargeU, enlargeV = Standard_True;
2864 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2865 Standard_Boolean enlargeVfirst = GlobalEnlargeVfirst, enlargeVlast = GlobalEnlargeVlast;
2866 S->Bounds( u1, u2, v1, v2 );
2867 if (Precision::IsInfinite(u1) || Precision::IsInfinite(u2))
2872 enlargeU = Standard_False;
2874 else if (S->IsUClosed())
2875 enlargeU = Standard_False;
2878 viso = S->VIso( vf1 );
2879 GeomAdaptor_Curve gac( viso );
2880 du = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2881 uiso1 = S->UIso( uf1 );
2882 uiso2 = S->UIso( uf2 );
2883 if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
2884 enlargeUfirst = Standard_False;
2885 if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
2886 enlargeUlast = Standard_False;
2888 if (Precision::IsInfinite(v1) || Precision::IsInfinite(v2))
2893 enlargeV = Standard_False;
2895 else if (S->IsVClosed())
2896 enlargeV = Standard_False;
2899 uiso = S->UIso( uf1 );
2900 GeomAdaptor_Curve gac( uiso );
2901 dv = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2902 viso1 = S->VIso( vf1 );
2903 viso2 = S->VIso( vf2 );
2904 if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
2906 enlargeVfirst = Standard_False;
2907 IsV1degen = Standard_True;
2909 if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
2911 enlargeVlast = Standard_False;
2912 IsV2degen = Standard_True;
2915 S = new Geom_RectangularTrimmedSurface( S, u1, u2, v1, v2 );
2919 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), du, 1, Standard_True, Standard_False );
2921 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), du, 1, Standard_True, Standard_True );
2926 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), dv, 1, Standard_False, Standard_False );
2928 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), dv, 1, Standard_False, Standard_True );
2930 S->Bounds( U1, U2, V1, V2 );
2931 SurfaceChange = Standard_True;
2933 else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
2934 S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
2936 Standard_Boolean enlargeU = GlobalEnlargeU, enlargeV = Standard_True;
2937 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2938 Standard_Boolean enlargeVfirst = GlobalEnlargeVfirst, enlargeVlast = GlobalEnlargeVlast;
2940 enlargeU = Standard_False;
2942 enlargeV = Standard_False;
2944 Standard_Real duf = uf2-uf1, dvf = vf2-vf1;
2945 Standard_Real u1, u2, v1, v2;
2946 S->Bounds( u1, u2, v1, v2 );
2948 Standard_Real du=0., dv=0.;
2949 Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
2950 GeomAdaptor_Curve gac;
2953 viso = S->VIso( v1 );
2955 du = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2956 uiso1 = S->UIso( u1 );
2957 uiso2 = S->UIso( u2 );
2958 if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
2959 enlargeUfirst = Standard_False;
2960 if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
2961 enlargeUlast = Standard_False;
2965 uiso = S->UIso( u1 );
2967 dv = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2968 viso1 = S->VIso( v1 );
2969 viso2 = S->VIso( v2 );
2970 if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
2972 enlargeVfirst = Standard_False;
2973 IsV1degen = Standard_True;
2975 if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
2977 enlargeVlast = Standard_False;
2978 IsV2degen = Standard_True;
2984 if (enlargeUfirst && uf1-u1 < duf)
2985 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), du, 1, Standard_True, Standard_False );
2986 if (enlargeUlast && u2-uf2 < duf)
2987 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), du, 1, Standard_True, Standard_True );
2991 if (enlargeVfirst && vf1-v1 < dvf)
2992 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), dv, 1, Standard_False, Standard_False );
2993 if (enlargeVlast && v2-vf2 < dvf)
2994 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), dv, 1, Standard_False, Standard_True );
2997 S->Bounds( U1, U2, V1, V2 );
2998 SurfaceChange = Standard_True;
3000 // else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
3001 // S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface)) {
3002 // S->Bounds(U1,U2,V1,V2);
3005 Standard_Real UU1,UU2,VV1,VV2;
3006 S->Bounds(UU1,UU2,VV1,VV2);
3007 // Pas d extension au dela des bornes de la surface.
3013 return SurfaceChange;
3016 //=======================================================================
3017 //function : UpDatePCurve
3018 //purpose : Mise a jour des pcurves de F sur la surface de de BF.
3019 // F and BF has to be FORWARD,
3020 //=======================================================================
3022 static void UpdatePCurves (const TopoDS_Face& F,
3028 TopTools_IndexedMapOfShape Emap;
3029 Handle(Geom2d_Curve) NullPCurve;
3031 TopExp::MapShapes( F, TopAbs_EDGE, Emap );
3033 for (i = 1; i <= Emap.Extent(); i++)
3035 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
3036 CE.Orientation( TopAbs_FORWARD );
3037 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface( CE, F, f, l );
3040 if (BRep_Tool::IsClosed( CE, F ))
3043 Handle(Geom2d_Curve) C2R = BRep_Tool::CurveOnSurface( CE, F, f, l );
3044 B.UpdateEdge( CE, NullPCurve, NullPCurve, F, BRep_Tool::Tolerance(CE) );
3045 B.UpdateEdge( CE, C2, C2R, BF, BRep_Tool::Tolerance(CE) );
3049 B.UpdateEdge( CE, NullPCurve, F, BRep_Tool::Tolerance(CE) );
3050 B.UpdateEdge( CE, C2, BF, BRep_Tool::Tolerance(CE) );
3058 //=======================================================================
3059 //function :CompactUVBounds
3061 //=======================================================================
3063 static void CompactUVBounds (const TopoDS_Face& F,
3064 Standard_Real& UMin,
3065 Standard_Real& UMax,
3066 Standard_Real& VMin,
3067 Standard_Real& VMax)
3069 // Calcul serre pour que les bornes ne couvrent pas plus d une periode
3070 Standard_Real U1,U2;
3071 Standard_Real N = 33;
3074 TopExp_Explorer exp;
3075 for (exp.Init(F, TopAbs_EDGE); exp.More(); exp.Next()) {
3076 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3077 BRepAdaptor_Curve2d C(E,F);
3078 BRep_Tool::Range(E,U1,U2);
3080 Standard_Real U = U1;
3081 Standard_Real DU = (U2-U1)/(N-1);
3082 for (Standard_Integer j=1;j<N;j++) {
3090 B.Get(UMin,VMin,UMax,VMax);
3093 //=======================================================================
3094 //function : CheckBounds
3096 //=======================================================================
3098 void BRepOffset_Tool::CheckBounds(const TopoDS_Face& F,
3099 const BRepOffset_Analyse& Analyse,
3100 Standard_Boolean& enlargeU,
3101 Standard_Boolean& enlargeVfirst,
3102 Standard_Boolean& enlargeVlast)
3104 enlargeU = Standard_True;
3105 enlargeVfirst = Standard_True; enlargeVlast = Standard_True;
3107 Standard_Integer Ubound = 0, Vbound = 0;
3108 Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
3109 Standard_Real Vfirst = RealLast(), Vlast = RealFirst();
3111 Standard_Real UF1,UF2,VF1,VF2;
3112 CompactUVBounds(F,UF1,UF2,VF1,VF2);
3114 Handle(Geom_Surface) theSurf = BRep_Tool::Surface(F);
3115 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
3116 theSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&theSurf))->BasisSurface();
3118 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
3119 theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution) ||
3120 theSurf->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
3121 theSurf->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
3123 TopExp_Explorer Explo(F, TopAbs_EDGE);
3124 for (; Explo.More(); Explo.Next())
3126 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
3127 const BRepOffset_ListOfInterval& L = Analyse.Type(anEdge);
3128 if (!L.IsEmpty() || BRep_Tool::Degenerated(anEdge))
3130 BRepOffset_Type OT = L.First().Type();
3131 if (OT == BRepOffset_Tangent || BRep_Tool::Degenerated(anEdge))
3133 Standard_Real fpar, lpar;
3134 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, F, fpar, lpar);
3135 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
3136 aCurve = (*((Handle(Geom2d_TrimmedCurve)*)&aCurve))->BasisCurve();
3138 Handle(Geom2d_Line) theLine;
3139 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_Line))
3140 theLine = *((Handle(Geom2d_Line)*)&aCurve);
3141 else if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BezierCurve) ||
3142 aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BSplineCurve))
3144 Standard_Real newFpar, newLpar, deviation;
3145 theLine = ShapeCustom_Curve2d::ConvertToLine2d(aCurve, fpar, lpar, Precision::Confusion(),
3146 newFpar, newLpar, deviation);
3149 if (!theLine.IsNull())
3151 gp_Dir2d theDir = theLine->Direction();
3152 if (theDir.IsParallel( gp::DX2d(), Precision::Angular() ))
3155 if (BRep_Tool::Degenerated(anEdge))
3157 if (Abs(theLine->Location().Y() - VF1) <= Precision::Confusion())
3158 enlargeVfirst = Standard_False;
3159 else //theLine->Location().Y() is near VF2
3160 enlargeVlast = Standard_False;
3164 if (theLine->Location().Y() < Vfirst)
3165 Vfirst = theLine->Location().Y();
3166 if (theLine->Location().Y() > Vlast)
3167 Vlast = theLine->Location().Y();
3170 else if (theDir.IsParallel( gp::DY2d(), Precision::Angular() ))
3173 if (theLine->Location().X() < Ufirst)
3174 Ufirst = theLine->Location().X();
3175 if (theLine->Location().X() > Ulast)
3176 Ulast = theLine->Location().X();
3184 if (Ubound >= 2 || Vbound >= 2)
3187 Abs(UF1-Ufirst) <= Precision::Confusion() &&
3188 Abs(UF2-Ulast) <= Precision::Confusion())
3189 enlargeU = Standard_False;
3191 Abs(VF1-Vfirst) <= Precision::Confusion() &&
3192 Abs(VF2-Vlast) <= Precision::Confusion())
3194 enlargeVfirst = Standard_False;
3195 enlargeVlast = Standard_False;
3200 //=======================================================================
3201 //function : EnLargeFace
3203 //=======================================================================
3205 Standard_Boolean BRepOffset_Tool::EnLargeFace
3206 (const TopoDS_Face& F,
3208 const Standard_Boolean CanExtentSurface,
3209 const Standard_Boolean UpdatePCurve,
3210 const Standard_Boolean enlargeU,
3211 const Standard_Boolean enlargeVfirst,
3212 const Standard_Boolean enlargeVlast)
3214 //---------------------------
3215 // extension de la geometrie.
3216 //---------------------------
3218 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
3219 Standard_Real UU1,VV1,UU2,VV2;
3220 Standard_Boolean isVV1degen = Standard_False, isVV2degen = Standard_False;
3221 Standard_Real US1,VS1,US2,VS2;
3222 Standard_Real UF1,VF1,UF2,VF2;
3223 Standard_Real infini = 1.e8;
3224 Standard_Boolean SurfaceChange = Standard_False;
3226 if (S->IsUPeriodic() || S->IsVPeriodic()) {
3227 // Calcul serre pour que les bornes ne couvre pas plus d une periode
3228 CompactUVBounds(F,UF1,UF2,VF1,VF2);
3231 BRepTools::UVBounds(F,UF1,UF2,VF1,VF2);
3234 S->Bounds (US1,US2,VS1,VS2);
3235 UU1 = VV1 = - infini;
3238 if (CanExtentSurface) {
3239 SurfaceChange = EnlargeGeometry( S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2,
3240 enlargeU, enlargeVfirst, enlargeVlast );
3243 UU1 = Max(US1,UU1); UU2 = Min(UU2,US2);
3244 VV1 = Max(VS1,VV1); VV2 = Min(VS2,VV2);
3247 if (S->IsUPeriodic()) {
3248 Standard_Real Period = S->UPeriod();
3249 Standard_Real Delta = Period - (UF2 - UF1);
3250 Standard_Real alpha = 0.1;
3251 UU1 = UF1 - alpha*Delta; UU2 = UF2 + alpha*Delta;
3252 if ((UU2 - UU1) > Period) {
3256 if (S->IsVPeriodic()) {
3257 Standard_Real Period = S->VPeriod();
3258 Standard_Real Delta = Period - (VF2 - VF1);
3259 Standard_Real alpha = 0.1;
3260 VV1 = VF1 - alpha*Delta; VV2 = VF2 + alpha*Delta;
3261 if ((VV2 - VV1) > Period) {
3266 //Special treatment for conical surfaces
3267 Handle(Geom_Surface) theSurf = S;
3268 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
3269 theSurf = (*(Handle(Geom_RectangularTrimmedSurface)*)&S)->BasisSurface();
3270 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
3272 Handle(Geom_ConicalSurface) ConicalS = *((Handle(Geom_ConicalSurface)*) &theSurf);
3273 gp_Cone theCone = ConicalS->Cone();
3274 gp_Pnt theApex = theCone.Apex();
3275 Standard_Real Uapex, Vapex;
3276 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
3277 if (VV1 < Vapex && Vapex < VV2)
3279 //consider that VF1 and VF2 are on the same side from apex
3280 Standard_Real TolApex = 1.e-5;
3281 if (Vapex - VF1 >= TolApex ||
3282 Vapex - VF2 >= TolApex) //if (VF1 < Vapex || VF2 < Vapex)
3291 UU1 = UF1; UU2 = UF2;
3298 MakeFace(S,UU1,UU2,VV1,VV2,isVV1degen,isVV2degen,BF);
3301 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
3303 //----------------------------------------------------------------
3304 // utile pour les bouchons on ne doit pas changer leur geometrie.
3305 // (Ce que fait BRepLib_MakeFace si S est restreinte).
3306 // On remet S et on update les pcurves.
3307 //----------------------------------------------------------------
3308 TopExp_Explorer exp;
3309 exp.Init(BF,TopAbs_EDGE);
3310 Standard_Real f=0.,l=0.;
3311 for (; exp.More(); exp.Next()) {
3312 TopoDS_Edge CE = TopoDS::Edge(exp.Current());
3313 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,BF,f,l);
3314 B.UpdateEdge (CE,C2,S,L,BRep_Tool::Tolerance(CE));
3316 B.UpdateFace(BF,S,L,BRep_Tool::Tolerance(F));
3319 if (SurfaceChange && UpdatePCurve) {
3320 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3321 UpdatePCurves(TopoDS::Face(aLocalFace),BF);
3322 //UpdatePCurves(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),BF);
3324 BB.UpdateFace( F, S, L, BRep_Tool::Tolerance(F) );
3327 BF.Orientation(F.Orientation());
3328 return SurfaceChange;
3331 //=======================================================================
3332 //function : TryParameter
3334 //=======================================================================
3336 static Standard_Boolean TryParameter (const TopoDS_Edge& OE,
3338 const TopoDS_Edge& NE,
3339 Standard_Real TolConf)
3341 BRepAdaptor_Curve OC(OE);
3342 BRepAdaptor_Curve NC(NE);
3343 Standard_Real Of = OC.FirstParameter(); Standard_Real Ol = OC.LastParameter();
3344 Standard_Real Nf = NC.FirstParameter(); Standard_Real Nl = NC.LastParameter();
3345 Standard_Real U = 0.;
3346 gp_Pnt P = BRep_Tool::Pnt(V);
3347 Standard_Boolean OK = Standard_False;
3349 if (P.Distance(OC.Value(Of)) < TolConf) {
3350 if (Of > Nf && Of < Nl && P.Distance(NC.Value(Of)) < TolConf) {
3355 if (P.Distance(OC.Value(Ol)) < TolConf) {
3356 if (Ol > Nf && Ol < Nl && P.Distance(NC.Value(Ol)) < TolConf) {
3363 TopoDS_Shape aLocalShape = NE.Oriented(TopAbs_FORWARD);
3364 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
3365 // TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD));
3366 aLocalShape = V.Oriented(TopAbs_INTERNAL);
3367 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
3368 U,NE,BRep_Tool::Tolerance(NE));
3369 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
3370 // U,NE,BRep_Tool::Tolerance(NE));
3375 //=======================================================================
3378 //=======================================================================
3380 void BRepOffset_Tool::MapVertexEdges (const TopoDS_Shape& S,
3381 TopTools_DataMapOfShapeListOfShape& MEV)
3383 TopExp_Explorer exp;
3384 exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3385 TopTools_MapOfShape DejaVu;
3386 for ( ; exp.More(); exp.Next()) {
3387 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3388 if (DejaVu.Add(E)) {
3389 TopoDS_Vertex V1,V2;
3390 TopExp::Vertices (E,V1,V2);
3391 if (!MEV.IsBound(V1)) {
3392 TopTools_ListOfShape empty;
3396 if (!V1.IsSame(V2)) {
3397 if (!MEV.IsBound(V2)) {
3398 TopTools_ListOfShape empty;
3407 //=======================================================================
3410 //=======================================================================
3412 void BRepOffset_Tool::BuildNeighbour (const TopoDS_Wire& W,
3413 const TopoDS_Face& F,
3414 TopTools_DataMapOfShapeShape& NOnV1,
3415 TopTools_DataMapOfShapeShape& NOnV2)
3417 TopoDS_Vertex V1,V2,VP1,VP2,FV1,FV2;
3418 TopoDS_Edge CurE,FirstE,PrecE;
3419 BRepTools_WireExplorer wexp;
3421 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3422 TopoDS_Shape aLocalWire = W.Oriented(TopAbs_FORWARD);
3423 wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
3424 // wexp.Init(TopoDS::Wire(W.Oriented(TopAbs_FORWARD)),
3425 // TopoDS::Face(F.Oriented(TopAbs_FORWARD)));
3426 CurE = FirstE = PrecE = wexp.Current();
3427 TopExp::Vertices(CurE,V1,V2);
3428 FV1 = VP1 = V1; FV2 = VP2 = V2;
3430 while (wexp.More()) {
3431 CurE = wexp.Current();
3432 TopExp::Vertices(CurE,V1,V2);
3433 if (V1.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3434 if (V1.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3435 if (V2.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3436 if (V2.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3441 if (V1.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3442 if (V1.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3443 if (V2.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3444 if (V2.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3447 //=======================================================================
3448 //function : ExtentFace
3450 //=======================================================================
3452 void BRepOffset_Tool::ExtentFace (const TopoDS_Face& F,
3453 TopTools_DataMapOfShapeShape& ConstShapes,
3454 TopTools_DataMapOfShapeShape& ToBuild,
3455 const TopAbs_State Side,
3456 const Standard_Real TolConf,
3462 sprintf(name,"FTE_%d",NbFTE++);
3467 TopExp_Explorer exp,exp2;
3468 TopTools_DataMapOfShapeShape Build;
3469 TopTools_DataMapOfShapeShape Extent;
3470 TopoDS_Edge FirstE,PrecE,CurE,NE;
3474 // Construction de la boite englobante de la face a etendre et des bouchons pour
3475 // limiter les extensions.
3476 //Bnd_Box ContextBox;
3477 //BRepBndLib::Add(F,B);
3478 //TopTools_DataMapIteratorOfDataMapOfShape itTB(ToBuild);
3479 //for (; itTB.More(); itTB.Next()) {
3480 //BRepBndLib::Add(TopBuild.Value(), ContextBox);
3484 Standard_Boolean SurfaceChange;
3485 SurfaceChange = EnLargeFace (F,EF,Standard_True);
3487 TopoDS_Shape aLocalShape = EF.EmptyCopied();
3488 NF = TopoDS::Face(aLocalShape);
3489 // NF = TopoDS::Face(EF.EmptyCopied());
3490 NF.Orientation(TopAbs_FORWARD);
3492 if (SurfaceChange) {
3493 //------------------------------------------------
3494 // Mise a jour des pcurves sur la surface de base.
3495 //------------------------------------------------
3496 TopoDS_Face Fforward = F;
3497 Fforward.Orientation(TopAbs_FORWARD);
3498 TopTools_IndexedMapOfShape Emap;
3499 TopExp::MapShapes( Fforward, TopAbs_EDGE, Emap );
3501 for (Standard_Integer i = 1; i <= Emap.Extent(); i++) {
3502 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
3503 CE.Orientation(TopAbs_FORWARD);
3504 TopoDS_Edge Ecs; //patch
3505 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,Fforward,f,l);
3507 if (ConstShapes.IsBound(CE)) {
3508 Ecs = TopoDS::Edge(ConstShapes(CE));
3509 BRep_Tool::Range(Ecs,f,l);
3511 if (BRep_Tool::IsClosed(CE,Fforward)) {
3512 TopoDS_Shape aLocalShape = CE.Reversed();
3513 Handle(Geom2d_Curve) C2R =
3514 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),Fforward,f,l);
3515 // Handle(Geom2d_Curve) C2R =
3516 // BRep_Tool::CurveOnSurface(TopoDS::Edge(CE.Reversed()),F,f,l);
3517 B.UpdateEdge (CE,C2,C2R,EF,BRep_Tool::Tolerance(CE));
3519 B.UpdateEdge (Ecs,C2,C2R,EF,BRep_Tool::Tolerance(CE));
3522 B.UpdateEdge (CE,C2,EF,BRep_Tool::Tolerance(CE));
3524 B.UpdateEdge (Ecs,C2,EF,BRep_Tool::Tolerance(CE));
3533 for (exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
3536 const TopoDS_Wire& W = TopoDS::Wire(exp.Current());
3537 TopTools_DataMapOfShapeListOfShape MVE; // Vertex -> Edges incidentes.
3538 TopTools_DataMapOfShapeShape NOnV1;
3539 TopTools_DataMapOfShapeShape NOnV2;
3541 MapVertexEdges (W,MVE);
3542 BuildNeighbour (W,F,NOnV1,NOnV2);
3544 TopTools_ListOfShape LInt1,LInt2;
3545 TopoDS_Face StopFace;
3546 //------------------------------------------------
3547 // Construction edges
3548 //------------------------------------------------
3549 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3550 exp2.More(); exp2.Next()) {
3551 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3552 if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
3553 if (ToBuild.IsBound(E)) {
3554 TopTools_ListOfShape LOE;
3556 BRepOffset_Tool::TryProject (TopoDS::Face(ToBuild(E)),
3557 EF,LOE,LInt2,LInt1,Side,TolConf);
3558 if (!LInt1.IsEmpty())
3563 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3564 exp2.More(); exp2.Next()) {
3565 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3566 if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
3567 if (ToBuild.IsBound(E)) {
3568 EnLargeFace(TopoDS::Face(ToBuild(E)),StopFace,Standard_False);
3569 BRepOffset_Tool::Inter3D (EF,StopFace,LInt1,LInt2,Side,E,Standard_True);
3570 // No intersection, it may happen for example for a chosen (non-offseted) planar face and
3571 // its neighbour offseted cylindrical face, if the offset is directed so that
3572 // the radius of the cylinder becomes smaller.
3573 if (LInt1.IsEmpty())
3575 if (LInt1.Extent() > 1) {
3576 // l intersection est en plusieurs edges (franchissement de couture)
3577 SelectEdge (F,EF,E,LInt1);
3579 NE = TopoDS::Edge(LInt1.First());
3580 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &NE.TShape());
3581 TE->Tolerance( TE->Tolerance()*10. ); //????
3582 if (NE.Orientation() == E.Orientation()) {
3583 Build.Bind(E,NE.Oriented(TopAbs_FORWARD));
3586 Build.Bind(E,NE.Oriented(TopAbs_REVERSED));
3588 const TopoDS_Edge& EOnV1 = TopoDS::Edge(NOnV1(E));
3589 if (!ToBuild .IsBound(EOnV1) &&
3590 !ConstShapes.IsBound(EOnV1) &&
3591 !Build .IsBound(EOnV1)) {
3592 ExtentEdge (F,EF,EOnV1,NE);
3593 Build.Bind (EOnV1,NE.Oriented(TopAbs_FORWARD));
3595 const TopoDS_Edge& EOnV2 = TopoDS::Edge(NOnV2(E));
3596 if (!ToBuild .IsBound(EOnV2) &&
3597 !ConstShapes.IsBound(EOnV2) &&
3598 !Build .IsBound(EOnV2)) {
3599 ExtentEdge (F,EF,EOnV2,NE);
3600 Build.Bind (EOnV2,NE.Oriented (TopAbs_FORWARD));
3605 //------------------------------------------------
3606 // Construction Vertex.
3607 //------------------------------------------------
3608 TopTools_ListOfShape LV;
3611 TopoDS_Vertex V1,V2;
3613 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3614 exp2.More(); exp2.Next()) {
3615 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3616 TopExp::Vertices (E,V1,V2);
3617 BRep_Tool::Range (E,f,l);
3619 if (Build.IsBound(E)) {
3620 const TopoDS_Edge& NEOnV1 = TopoDS::Edge(NOnV1(E));
3621 if (Build.IsBound(NEOnV1) &&
3622 (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV1))) {
3623 if (E.IsSame(NEOnV1))
3624 V = TopExp::FirstVertex(TopoDS::Edge(Build(E)));
3629 if (!Build.IsBound(V1)) {
3630 Inter2d (EF,TopoDS::Edge(Build(E)),
3631 TopoDS::Edge(Build(NEOnV1)),LV,/*TolConf*/Precision::Confusion());
3632 if (Build(E).Orientation() == TopAbs_FORWARD) {
3633 V = TopoDS::Vertex(LV.First());
3636 V = TopoDS::Vertex(LV.Last());
3640 V = TopoDS::Vertex(Build(V1));
3641 if (MVE (V1).Extent() > 2) {
3642 V.Orientation(TopAbs_FORWARD);
3643 if (Build(E).Orientation() == TopAbs_REVERSED)
3644 V.Orientation(TopAbs_REVERSED);
3645 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3655 if (ConstShapes.IsBound(V1)) V = TopoDS::Vertex(ConstShapes(V1));
3656 V.Orientation(TopAbs_FORWARD);
3657 if (Build(E).Orientation() == TopAbs_REVERSED)
3658 V.Orientation(TopAbs_REVERSED);
3659 if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
3660 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3662 ConstShapes.Bind(V1,V);
3664 const TopoDS_Edge& NEOnV2 = TopoDS::Edge(NOnV2(E));
3665 if (Build.IsBound(NEOnV2) &&
3666 (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV2))) {
3667 if (E.IsSame(NEOnV2))
3668 V = TopExp::LastVertex(TopoDS::Edge(Build(E)));
3673 if (!Build.IsBound(V2)) {
3674 Inter2d (EF,TopoDS::Edge(Build(E)),
3675 TopoDS::Edge(Build(NEOnV2)),LV,/*TolConf*/Precision::Confusion());
3676 if (Build(E).Orientation() == TopAbs_FORWARD) {
3677 V = TopoDS::Vertex(LV.Last());
3680 V = TopoDS::Vertex(LV.First());
3684 V = TopoDS::Vertex(Build(V2));
3685 if (MVE (V2).Extent() > 2) {
3686 V.Orientation(TopAbs_REVERSED);
3687 if (Build(E).Orientation() == TopAbs_REVERSED)
3688 V.Orientation(TopAbs_FORWARD);
3689 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3699 if (ConstShapes.IsBound(V2)) V = TopoDS::Vertex(ConstShapes(V2));
3700 V.Orientation(TopAbs_REVERSED);
3701 if (Build(E).Orientation() == TopAbs_REVERSED)
3702 V.Orientation(TopAbs_FORWARD);
3703 if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
3704 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3706 ConstShapes.Bind(V2,V);
3712 TopoDS_Vertex NV1,NV2;
3713 TopAbs_Orientation Or;
3714 Standard_Real U1,U2;
3715 Standard_Real eps = Precision::Confusion();
3725 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3726 exp2.More(); exp2.Next()) {
3727 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3728 TopExp::Vertices (E,V1,V2);
3729 if (Build.IsBound(E)) {
3730 NE = TopoDS::Edge(Build(E));
3731 BRep_Tool::Range(NE,f,l);
3732 Or = NE.Orientation();
3733 //-----------------------------------------------------
3734 // Copy pour virer les vertex deja sur la nouvelle edge.
3735 //-----------------------------------------------------
3736 NV1 = TopoDS::Vertex(ConstShapes(V1));
3737 NV2 = TopoDS::Vertex(ConstShapes(V2));
3739 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_INTERNAL);
3740 TopoDS_Shape aLocalEdge = NE.Oriented(TopAbs_INTERNAL);
3742 U1 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalVertex),
3743 TopoDS::Edge (aLocalEdge));
3744 aLocalVertex = NV2.Oriented(TopAbs_INTERNAL);
3745 aLocalEdge = NE.Oriented(TopAbs_FORWARD);
3746 U2 = BRep_Tool::Parameter
3747 (TopoDS::Vertex(aLocalVertex),TopoDS::Edge (aLocalEdge));
3748 // U1 = BRep_Tool::Parameter
3749 // (TopoDS::Vertex(NV1.Oriented(TopAbs_INTERNAL)),
3750 // TopoDS::Edge (NE .Oriented(TopAbs_FORWARD)));
3751 // U2 = BRep_Tool::Parameter
3752 // (TopoDS::Vertex(NV2.Oriented(TopAbs_INTERNAL)),
3753 // TopoDS::Edge (NE.Oriented(TopAbs_FORWARD)));
3754 aLocalEdge = NE.EmptyCopied();
3755 NE = TopoDS::Edge(aLocalEdge);
3756 NE.Orientation(TopAbs_FORWARD);
3757 if (NV1.IsSame(NV2))
3762 if (Or == TopAbs_FORWARD) {U1 = f; U2 = l;}
3763 else {U1 = l; U2 = f;}
3764 if (Or == TopAbs_FORWARD)
3768 if (Abs(U1-l) < eps) U1 = f;
3769 if (Abs(U2-f) < eps) U2 = l;
3771 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3772 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3773 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3774 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3775 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3776 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3778 ConstShapes.Bind(E,NE);
3779 NE.Orientation(E.Orientation());
3785 if (Abs(U2-l) < eps) U2 = f;
3786 if (Abs(U1-f) < eps) U1 = l;
3788 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3789 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3790 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3791 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3792 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3793 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3795 ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
3796 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3801 //-------------------
3802 // edge is not ferme.
3803 //-------------------
3804 if (Or == TopAbs_FORWARD) {
3806 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3807 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3808 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3809 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3810 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3811 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3816 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3817 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3818 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3819 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3820 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3821 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3824 ConstShapes.Bind(E,NE);
3825 NE.Orientation(E.Orientation());
3829 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3830 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3831 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3832 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3833 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3834 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3836 ConstShapes.Bind(E,NE);
3837 NE.Orientation(E.Orientation());
3841 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3842 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3843 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3844 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3845 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3846 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3848 ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
3849 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3854 } // Build.IsBound(E)
3855 else if (ConstShapes.IsBound(E)) { // !Build.IsBound(E)
3856 NE = TopoDS::Edge(ConstShapes(E));
3857 BuildPCurves(NE,NF);
3858 Or = NE.Orientation();
3859 if (Or == TopAbs_REVERSED) {
3860 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3863 NE.Orientation(E.Orientation());
3868 ConstShapes.Bind(E,NE.Oriented(TopAbs_FORWARD));
3872 B.Add(NF,NW.Oriented(W.Orientation()));
3874 NF.Orientation(F.Orientation());
3875 BRepTools::Update(NF); // Maj des UVPoints
3880 sprintf(name,"FOB_%d",NbFOB++);
3881 DBRep::Set(name,NF);
3887 //=======================================================================
3888 //function : Deboucle3D
3890 //=======================================================================
3892 TopoDS_Shape BRepOffset_Tool::Deboucle3D(const TopoDS_Shape& S,
3893 const TopTools_MapOfShape& Boundary)
3895 return BRepAlgo_Tool::Deboucle3D(S,Boundary);
3898 //=======================================================================
3899 //function : IsInOut
3901 //=======================================================================
3903 static Standard_Boolean IsInOut (BRepTopAdaptor_FClass2d& FC,
3904 Geom2dAdaptor_Curve AC,
3905 const TopAbs_State& S )
3907 Standard_Real Def = 100*Precision::Confusion();
3908 GCPnts_QuasiUniformDeflection QU(AC,Def);
3910 for (Standard_Integer i = 1; i <= QU.NbPoints(); i++) {
3911 gp_Pnt2d P = AC.Value(QU.Parameter(i));
3912 if (FC.Perform(P) != S) {
3913 return Standard_False;
3916 return Standard_True;
3919 //=======================================================================
3920 //function : CorrectOrientation
3922 //=======================================================================
3924 void BRepOffset_Tool::CorrectOrientation(const TopoDS_Shape& SI,
3925 const TopTools_IndexedMapOfShape& NewEdges,
3926 Handle(BRepAlgo_AsDes)& AsDes,
3927 BRepAlgo_Image& InitOffset,
3928 const Standard_Real Offset)
3931 TopExp_Explorer exp;
3932 exp.Init(SI,TopAbs_FACE);
3933 Standard_Real f=0.,l=0.;
3935 for (; exp.More(); exp.Next()) {
3937 const TopoDS_Face& FI = TopoDS::Face(exp.Current());
3938 const TopTools_ListOfShape& LOF = InitOffset.Image(FI);
3939 TopTools_ListIteratorOfListOfShape it(LOF);
3940 for (; it.More(); it.Next()) {
3941 const TopoDS_Face& OF = TopoDS::Face(it.Value());
3942 TopTools_ListOfShape& LOE = AsDes->ChangeDescendant(OF);
3943 TopTools_ListIteratorOfListOfShape itE(LOE);
3945 Standard_Boolean YaInt = Standard_False;
3946 for (; itE.More(); itE.Next()) {
3947 const TopoDS_Edge& OE = TopoDS::Edge(itE.Value());
3948 if (NewEdges.Contains(OE)) {YaInt = Standard_True; break;}
3951 TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
3952 BRepTopAdaptor_FClass2d FC (TopoDS::Face(aLocalFace),
3953 Precision::Confusion());
3954 // BRepTopAdaptor_FClass2d FC (TopoDS::Face(FI.Oriented(TopAbs_FORWARD)),
3955 // Precision::Confusion());
3956 for (itE.Initialize(LOE); itE.More(); itE.Next()) {
3957 TopoDS_Shape& OE = itE.Value();
3958 if (NewEdges.Contains(OE)) {
3959 Handle(Geom2d_Curve) CO2d =
3960 BRep_Tool::CurveOnSurface(TopoDS::Edge(OE),OF,f,l);
3961 Geom2dAdaptor_Curve AC(CO2d,f,l);
3964 if (IsInOut(FC,AC,TopAbs_OUT)) OE.Reverse();
3967 // if (IsInOut(FC,AC,TopAbs_IN)) OE.Reverse();