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
9 // under the terms of the GNU Lesser General Public 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_Conic.hxx>
79 #include <Geom_TrimmedCurve.hxx>
80 #include <GCPnts_QuasiUniformDeflection.hxx>
82 #include <GeomLib.hxx>
83 #include <GeomAPI.hxx>
84 #include <GeomAPI_ProjectPointOnCurve.hxx>
85 #include <Geom2d_TrimmedCurve.hxx>
86 #include <Geom2d_Line.hxx>
87 #include <Geom2d_Curve.hxx>
88 #include <Geom2d_Circle.hxx>
89 #include <Geom2d_Ellipse.hxx>
90 #include <Geom2d_Parabola.hxx>
91 #include <Geom2d_Hyperbola.hxx>
92 #include <Geom2d_BezierCurve.hxx>
93 #include <Geom2d_BSplineCurve.hxx>
95 #include <Geom2dAdaptor_Curve.hxx>
96 #include <Geom2dInt_GInter.hxx>
98 #include <GeomAdaptor_Surface.hxx>
99 #include <GeomProjLib.hxx>
100 #include <GeomInt_IntSS.hxx>
101 #include <ProjLib_ProjectedCurve.hxx>
102 #include <ProjLib_HProjectedCurve.hxx>
104 #include <ElSLib.hxx>
105 #include <ElCLib.hxx>
108 #include <gp_Pnt.hxx>
109 #include <gp_Vec.hxx>
112 #include <Precision.hxx>
113 #include <Standard_ConstructionError.hxx>
115 #include <BRep_TEdge.hxx>
116 #include <Extrema_ExtPC2d.hxx>
118 #include <Geom_SurfaceOfLinearExtrusion.hxx>
119 #include <Geom_SurfaceOfRevolution.hxx>
120 #include <GCPnts_AbscissaPoint.hxx>
122 //tma: for new boolean operation
123 #include <TopTools_SequenceOfShape.hxx>
124 #include <Geom_BSplineCurve.hxx>
125 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
126 #include <Geom2dConvert_CompCurveToBSplineCurve.hxx>
127 #include <GeomConvert_ApproxCurve.hxx>
128 #include <Geom2dConvert_ApproxCurve.hxx>
129 #include <TopoDS_Compound.hxx>
130 #include <GCPnts_UniformAbscissa.hxx>
131 #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
132 #include <BRep_CurveRepresentation.hxx>
134 #include <BRepOffset_ListOfInterval.hxx>
135 #include <BRepOffset_Interval.hxx>
136 #include <TColgp_Array1OfPnt2d.hxx>
137 #include <ShapeCustom_Curve2d.hxx>
138 #include <GeomAPI_ExtremaCurveCurve.hxx>
140 #include <BOPDS_DS.hxx>
141 #include <BOPAlgo_PaveFiller.hxx>
142 #include <BOPTools_AlgoTools2D.hxx>
149 Standard_Boolean AffichInter = Standard_False;
150 static Standard_Boolean AffichExtent = Standard_False;
151 static Standard_Integer NbNewEdges = 1;
152 static Standard_Integer NbFaces = 1;
153 static Standard_Integer NbFOB = 1;
154 static Standard_Integer NbFTE = 1;
155 static Standard_Integer NbExtE = 1;
157 //char* name = new char[100];
161 //=======================================================================
162 //function : EdgeVertices
164 //=======================================================================
166 void BRepOffset_Tool::EdgeVertices (const TopoDS_Edge& E,
170 if (E.Orientation() == TopAbs_REVERSED) {
171 TopExp::Vertices(E,V2,V1);
174 TopExp::Vertices(E,V1,V2);
178 //=======================================================================
179 //function : OriEdgeInFace
181 //=======================================================================
183 TopAbs_Orientation BRepOffset_Tool::OriEdgeInFace (const TopoDS_Edge& E,
184 const TopoDS_Face& F )
188 Exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
190 for (; Exp.More() ;Exp.Next()) {
191 if (Exp.Current().IsSame(E)) {
192 return Exp.Current().Orientation();
195 Standard_ConstructionError::Raise("BRepOffset_Tool::OriEdgeInFace");
196 return E.Orientation();
200 //=======================================================================
201 //function : FindPeriod
203 //=======================================================================
205 static void FindPeriod (const TopoDS_Face& F,
214 for (exp.Init(F,TopAbs_EDGE); exp.More(); exp.Next()) {
215 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
218 const Handle(Geom2d_Curve) C = BRep_Tool::CurveOnSurface(E,F,pf,pl);
219 if (C.IsNull()) return;
220 Geom2dAdaptor_Curve PC(C,pf,pl);
221 Standard_Real i, nbp = 20;
222 if (PC.GetType() == GeomAbs_Line) nbp = 2;
223 Standard_Real step = (pl - pf) / nbp;
227 for (i = 2; i < nbp; i++) {
234 B.Get(umin,vmin,umax,vmax);
238 //=======================================================================
239 //function : PutInBounds
240 //purpose : Recadre la courbe 2d dans les bounds de la face
241 //=======================================================================
243 static void PutInBounds (const TopoDS_Face& F,
244 const TopoDS_Edge& E,
245 Handle(Geom2d_Curve)& C2d)
247 Standard_Real umin,umax,vmin,vmax;
249 BRep_Tool::Range(E,f,l);
251 TopLoc_Location L; // Recup S avec la location pour eviter la copie.
252 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
254 if (S->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
255 S = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface();
260 if (!S->IsUPeriodic() && !S->IsVPeriodic()) return;
262 FindPeriod (F,umin,umax,vmin,vmax);
264 if (S->IsUPeriodic()) {
265 Standard_Real period = S->UPeriod();
266 Standard_Real eps = period*1.e-6;
267 gp_Pnt2d Pf = C2d->Value(f);
268 gp_Pnt2d Pl = C2d->Value(l);
269 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
270 Standard_Real minC = Min(Pf.X(),Pl.X()); minC = Min(minC,Pm.X());
271 Standard_Real maxC = Max(Pf.X(),Pl.X()); maxC = Max(maxC,Pm.X());
272 Standard_Real du = 0.;
273 if (minC< umin - eps) {
274 du = (int((umin - minC)/period) + 1)*period;
276 if (minC > umax + eps) {
277 du = -(int((minC - umax)/period) + 1)*period;
282 minC += du; maxC += du;
284 // Ajuste au mieux la courbe dans le domaine.
285 if (maxC > umax +100*eps) {
286 Standard_Real d1 = maxC - umax;
287 Standard_Real d2 = umin - minC + period;
288 if (d2 < d1) du =-period;
298 if (S->IsVPeriodic()) {
299 Standard_Real period = S->VPeriod();
300 Standard_Real eps = period*1.e-6;
301 gp_Pnt2d Pf = C2d->Value(f);
302 gp_Pnt2d Pl = C2d->Value(l);
303 gp_Pnt2d Pm = C2d->Value(0.34*f + 0.66*l);
304 Standard_Real minC = Min(Pf.Y(),Pl.Y()); minC = Min(minC,Pm.Y());
305 Standard_Real maxC = Max(Pf.Y(),Pl.Y()); maxC = Max(maxC,Pm.Y());
306 Standard_Real dv = 0.;
307 if (minC< vmin - eps) {
308 dv = (int((vmin - minC)/period) + 1)*period;
310 if (minC > vmax + eps) {
311 dv = -(int((minC - vmax)/period) + 1)*period;
316 minC += dv; maxC += dv;
318 // Ajuste au mieux la courbe dans le domaine.
319 if (maxC > vmax +100*eps) {
320 Standard_Real d1 = maxC - vmax;
321 Standard_Real d2 = vmin - minC + period;
322 if (d2 < d1) dv =-period;
331 //=======================================================================
334 //=======================================================================
336 Standard_Real BRepOffset_Tool::Gabarit(const Handle(Geom_Curve)& aCurve)
338 GeomAdaptor_Curve GC( aCurve );
340 BndLib_Add3dCurve::Add( GC, Precision::Confusion(), aBox );
341 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, dist;
342 aBox.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
343 dist = Max( (aXmax-aXmin), (aYmax-aYmin) );
344 dist = Max( dist, (aZmax-aZmin) );
348 //=======================================================================
349 //function : BuildPCurves
351 //=======================================================================
353 static void BuildPCurves (const TopoDS_Edge& E,
354 const TopoDS_Face& F)
357 Handle (Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface (E,F,ff,ll);
358 if (!C2d.IsNull()) return;
360 //Standard_Real Tolerance = Max(Precision::Confusion(),BRep_Tool::Tolerance(E));
361 Standard_Real Tolerance = Precision::Confusion();
363 BRepAdaptor_Surface AS(F,0);
364 BRepAdaptor_Curve AC(E);
366 //Try to find pcurve on a bound of BSpline or Bezier surface
367 Handle( Geom_Surface ) theSurf = BRep_Tool::Surface( F );
368 Handle( Standard_Type ) typS = theSurf->DynamicType();
369 if (typS == STANDARD_TYPE(Geom_OffsetSurface))
370 typS = (*((Handle(Geom_OffsetSurface)*)&theSurf))->BasisSurface()->DynamicType();
371 if (typS == STANDARD_TYPE(Geom_BezierSurface) || typS == STANDARD_TYPE(Geom_BSplineSurface))
373 gp_Pnt fpoint = AC.Value( AC.FirstParameter() );
374 gp_Pnt lpoint = AC.Value( AC.LastParameter() );
375 TopoDS_Face theFace = BRepLib_MakeFace( theSurf, Precision::Confusion() );
376 Standard_Real U1 = 0., U2 = 0., TolProj = 1.e-4; //1.e-5;
378 TopExp_Explorer Explo;
379 Explo.Init( theFace, TopAbs_EDGE );
380 for (; Explo.More(); Explo.Next())
382 TopoDS_Edge anEdge = TopoDS::Edge( Explo.Current() );
383 BRepAdaptor_Curve aCurve( anEdge );
384 Extrema_ExtPC fextr( fpoint, aCurve );
385 if (!fextr.IsDone() || fextr.NbExt() < 1)
387 Standard_Real dist2, dist2min = RealLast();
389 for (i = 1; i <= fextr.NbExt(); i++)
391 dist2 = fextr.SquareDistance(i);
392 if (dist2 < dist2min)
395 U1 = fextr.Point(i).Parameter();
398 if (dist2min > TolProj * TolProj)
400 Extrema_ExtPC lextr( lpoint, aCurve );
401 if (!lextr.IsDone() || lextr.NbExt() <1)
403 dist2min = RealLast();
404 for (i = 1; i <= lextr.NbExt(); i++)
406 dist2 = lextr.SquareDistance(i);
407 if (dist2 < dist2min)
410 U2 = lextr.Point(i).Parameter();
413 if (dist2min <= TolProj * TolProj)
418 } // for (; Explo.More(); Explo.Current())
420 if (! theEdge.IsNull())
422 //Construction of pcurve
425 Standard_Real temp = U1;
430 C2d = BRep_Tool::CurveOnSurface( theEdge, theFace, f, l );
431 C2d = new Geom2d_TrimmedCurve( C2d, U1, U2 );
433 if (theSurf->IsUPeriodic() || theSurf->IsVPeriodic())
434 PutInBounds( F, E, C2d );
437 B.UpdateEdge( E, C2d, F, BRep_Tool::Tolerance(E) );
438 BRepLib::SameRange( E );
444 Handle(BRepAdaptor_HSurface) HS = new BRepAdaptor_HSurface(AS);
445 Handle(BRepAdaptor_HCurve) HC = new BRepAdaptor_HCurve(AC);
447 ProjLib_ProjectedCurve Proj(HS,HC,Tolerance);
449 switch ( Proj.GetType()) {
452 C2d = new Geom2d_Line(Proj.Line());
456 C2d = new Geom2d_Circle(Proj.Circle());
459 case GeomAbs_Ellipse:
460 C2d = new Geom2d_Ellipse(Proj.Ellipse());
463 case GeomAbs_Parabola:
464 C2d = new Geom2d_Parabola(Proj.Parabola());
467 case GeomAbs_Hyperbola:
468 C2d = new Geom2d_Hyperbola(Proj.Hyperbola());
471 case GeomAbs_BezierCurve:
475 case GeomAbs_BSplineCurve:
476 C2d = Proj.BSpline();
482 if (AS.IsUPeriodic() || AS.IsVPeriodic()) {
483 PutInBounds(F,E,C2d);
487 B.UpdateEdge (E,C2d,F,BRep_Tool::Tolerance(E));
490 Standard_ConstructionError::Raise("BRepOffset_Tool::BuildPCurves");
491 cout <<"Echec ProjLib"<<endl;
495 //=======================================================================
498 //=======================================================================
500 void BRepOffset_Tool::OrientSection (const TopoDS_Edge& E,
501 const TopoDS_Face& F1,
502 const TopoDS_Face& F2,
503 TopAbs_Orientation& O1,
504 TopAbs_Orientation& O2)
510 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
511 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
512 Handle (Geom2d_Curve) C1 = BRep_Tool::CurveOnSurface(E,F1,f,l);
513 Handle (Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(E,F2,f,l);
514 Handle (Geom_Curve) C = BRep_Tool::Curve(E,L,f,l);
516 BRepAdaptor_Curve BAcurve( E );
518 GCPnts_AbscissaPoint AP(BAcurve,GCPnts_AbscissaPoint::Length(BAcurve)/2.0,f);
519 Standard_Real ParOnC;
522 ParOnC = AP.Parameter();
524 ParOnC = BOPTools_AlgoTools2D::IntermediatePoint(f, l);
526 gp_Vec T1 = C->DN(ParOnC,1).Transformed(L.Transformation());
527 if (T1.SquareMagnitude() > gp::Resolution()) {
531 gp_Pnt2d P = C1->Value(ParOnC);
535 S1->D1(P.X(),P.Y(),P3,D1U,D1V);
537 if (F1.Orientation() == TopAbs_REVERSED) DN1.Reverse();
539 P = C2->Value(ParOnC);
540 S2->D1(P.X(),P.Y(),P3,D1U,D1V);
542 if (F2.Orientation() == TopAbs_REVERSED) DN2.Reverse();
544 gp_Vec ProVec = DN2^T1;
545 Standard_Real Prod = DN1.Dot(ProVec);
550 O1 = TopAbs_REVERSED;
553 Prod = DN2.Dot(ProVec);
558 O2 = TopAbs_REVERSED;
560 if (F1.Orientation() == TopAbs_REVERSED) O1 = TopAbs::Reverse(O1);
561 if (F2.Orientation() == TopAbs_REVERSED) O2 = TopAbs::Reverse(O2);
564 //=======================================================================
565 //function : HasCommonShape
567 //=======================================================================
569 Standard_Boolean BRepOffset_Tool::HasCommonShapes (const TopoDS_Face& F1,
570 const TopoDS_Face& F2,
571 TopTools_ListOfShape& LE,
572 TopTools_ListOfShape& LV)
574 Standard_Boolean Common = Standard_False;
575 LE.Clear(); LV.Clear();
577 TopExp_Explorer exp1;
578 exp1.Init(F1,TopAbs_EDGE);
580 for (; exp1.More(); exp1.Next()) {
581 TopExp_Explorer exp2;
582 exp2.Init(F2,TopAbs_EDGE);
583 for (; exp2.More(); exp2.Next()) {
584 if (exp1.Current().IsSame(exp2.Current())) {
585 Common = Standard_True;
586 LE.Append(exp1.Current());
590 for (exp1.Init(F1,TopAbs_VERTEX); exp1.More(); exp1.Next()) {
591 TopExp_Explorer exp2;
592 exp2.Init(F2,TopAbs_EDGE);
593 for (exp2.Init(F2,TopAbs_VERTEX); exp2.More(); exp2.Next()) {
594 if (exp1.Current().IsSame(exp2.Current())) {
595 Common = Standard_True;
596 LV.Append(exp1.Current());
603 //=======================================================================
606 //=======================================================================
608 static Standard_Boolean ToSmall (const Handle(Geom_Curve)& C)
610 Standard_Real Tol = 10*Precision::Confusion();
611 Standard_Real m = (C->FirstParameter()*0.668 + C->LastParameter()*0.332);
612 gp_Pnt P1 = C->Value(C->FirstParameter());
613 gp_Pnt P2 = C->Value(C->LastParameter());
614 gp_Pnt P3 = C->Value(m);
615 if (P1.Distance(P2) > Tol) return Standard_False;
616 if (P2.Distance(P3) > Tol) return Standard_False;
617 return Standard_True;
621 //=======================================================================
622 //function : IsOnSurface
624 //=======================================================================
626 static Standard_Boolean IsOnSurface(const Handle(Geom_Curve)& C,
627 const Handle(Geom_Surface)& S,
628 Standard_Real TolConf,
629 Standard_Real& TolReached)
631 Standard_Real f = C->FirstParameter();
632 Standard_Real l = C->LastParameter();
633 Standard_Integer n = 5;
634 Standard_Real du = (f-l)/(n-1);
640 GeomAdaptor_Surface AS(S);
642 switch ( AS.GetType()) {
645 gp_Ax3 Ax = AS.Plane().Position();
646 for ( Standard_Integer i = 0; i < n; i++) {
647 P = C->Value(f+i*du);
648 ElSLib::PlaneParameters(Ax,P,U,V);
649 TolReached = P.Distance(ElSLib::PlaneValue(U,V,Ax));
650 if ( TolReached > TolConf)
651 return Standard_False;
655 case GeomAbs_Cylinder:
657 gp_Ax3 Ax = AS.Cylinder().Position();
658 Standard_Real Rad = AS.Cylinder().Radius();
659 for ( Standard_Integer i = 0; i < n; i++) {
660 P = C->Value(f+i*du);
661 ElSLib::CylinderParameters(Ax,Rad,P,U,V);
662 TolReached = P.Distance(ElSLib::CylinderValue(U,V,Ax,Rad));
663 if ( TolReached > TolConf)
664 return Standard_False;
670 gp_Ax3 Ax = AS.Cone().Position();
671 Standard_Real Rad = AS.Cone().RefRadius();
672 Standard_Real Alp = AS.Cone().SemiAngle();
673 for ( Standard_Integer i = 0; i < n; i++) {
674 P = C->Value(f+i*du);
675 ElSLib::ConeParameters(Ax,Rad,Alp,P,U,V);
676 TolReached = P.Distance(ElSLib::ConeValue(U,V,Ax,Rad,Alp));
677 if ( TolReached > TolConf)
678 return Standard_False;
684 gp_Ax3 Ax = AS.Sphere().Position();
685 Standard_Real Rad = AS.Sphere().Radius();
686 for ( Standard_Integer i = 0; i < n; i++) {
687 P = C->Value(f+i*du);
688 ElSLib::SphereParameters(Ax,Rad,P,U,V);
689 TolReached = P.Distance(ElSLib::SphereValue(U,V,Ax,Rad));
690 if ( TolReached > TolConf)
691 return Standard_False;
697 gp_Ax3 Ax = AS.Torus().Position();
698 Standard_Real R1 = AS.Torus().MajorRadius();
699 Standard_Real R2 = AS.Torus().MinorRadius();
700 for ( Standard_Integer i = 0; i < n; i++) {
701 P = C->Value(f+i*du);
702 ElSLib::TorusParameters(Ax,R1,R2,P,U,V);
703 TolReached = P.Distance(ElSLib::TorusValue(U,V,Ax,R1,R2));
704 if ( TolReached > TolConf)
705 return Standard_False;
712 return Standard_False;
716 return Standard_True;
720 //=======================================================================
721 //function : PipeInter
723 //=======================================================================
725 void BRepOffset_Tool::PipeInter(const TopoDS_Face& F1,
726 const TopoDS_Face& F2,
727 TopTools_ListOfShape& L1,
728 TopTools_ListOfShape& L2,
729 const TopAbs_State Side)
734 char* name = new char[100];
735 sprintf(name,"FF_%d",NbFaces++);
737 sprintf(name,"FF_%d",NbFaces++);
742 Handle (Geom_Curve) CI;
744 TopAbs_Orientation O1,O2;
745 L1.Clear(); L2.Clear();
747 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
748 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
750 GeomInt_IntSS Inter (S1,S2, Precision::Confusion(),1,1,1);
752 if (Inter.IsDone()) {
753 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
755 if (ToSmall(CI)) continue;
756 TopoDS_Edge E = BRepLib_MakeEdge(CI);
757 if (Inter.HasLineOnS1(i)) {
758 Handle(Geom2d_Curve) C2 = Inter.LineOnS1(i);
759 PutInBounds (F1,E,C2);
760 B.UpdateEdge (E,C2,F1,BRep_Tool::Tolerance(E));
765 if (Inter.HasLineOnS2(i)) {
766 Handle(Geom2d_Curve) C2 = Inter.LineOnS2(i);
767 PutInBounds (F2,E,C2);
768 B.UpdateEdge (E,C2,F2,BRep_Tool::Tolerance(E));
773 OrientSection (E,F1,F2,O1,O2);
774 if (Side == TopAbs_OUT) {
775 O1 = TopAbs::Reverse(O1);
776 O2 = TopAbs::Reverse(O2);
778 L1.Append (E.Oriented(O1));
779 L2.Append (E.Oriented(O2));
783 char* name = new char[100];
784 sprintf(name,"EI_%d",NbNewEdges++);
785 DBRep::Set(name,E.Oriented(O1));
793 //=======================================================================
794 //function : IsAutonomVertex
795 //purpose : Checks wether a vertex is "autonom" or not
796 //=======================================================================
798 static Standard_Boolean IsAutonomVertex(const TopoDS_Shape& aVertex,
799 const TopoDS_Shape& F1,
800 const TopoDS_Shape& F2,
801 const BOPDS_PDS& pDS)
803 Standard_Integer index, indF1, indF2;
804 Standard_Integer aNbVVs, aNbEEs, aNbEFs, aInt;
806 index = pDS->Index(aVertex);
808 Standard_Integer i, i1, i2;
809 i1=pDS->NbSourceShapes();
811 for (i=i1; i<i2; ++i) {
812 const TopoDS_Shape& aSx=pDS->Shape(i);
813 if(aSx.IsSame(aVertex)) {
820 indF1 = pDS->Index(F1);
821 indF2 = pDS->Index(F2);
823 if (!pDS->IsNewShape(index)) {
824 return Standard_False;
826 //check if vertex with index "index" is not created in VV or EE or EF interference
828 BOPDS_VectorOfInterfVV& aVVs=pDS->InterfVV();
829 aNbVVs = aVVs.Extent();
830 for(aInt = 0; aInt < aNbVVs; aInt++) {
831 const BOPDS_InterfVV& aVV = aVVs(aInt);
832 if (aVV.HasIndexNew()) {
833 if (aVV.IndexNew() == index) {
834 return Standard_False;
839 BOPDS_VectorOfInterfEE& aEEs=pDS->InterfEE();
840 aNbEEs = aEEs.Extent();
841 for(aInt = 0; aInt < aNbEEs; aInt++) {
842 const BOPDS_InterfEE& aEE = aEEs(aInt);
843 IntTools_CommonPrt aCP = aEE.CommonPart();
844 if(aCP.Type() == TopAbs_VERTEX) {
845 if (aEE.IndexNew() == index) {
846 return Standard_False;
851 BOPDS_VectorOfInterfEF& aEFs=pDS->InterfEF();
852 aNbEFs = aEFs.Extent();
853 for(aInt = 0; aInt < aNbEFs; aInt++) {
854 const BOPDS_InterfEF& aEF = aEFs(aInt);
855 IntTools_CommonPrt aCP = aEF.CommonPart();
856 if(aCP.Type() == TopAbs_VERTEX) {
857 if (aEF.IndexNew() == index) {
858 return Standard_False;
862 return Standard_True;
866 //=======================================================================
867 //function : AreConnex
868 //purpose : define if two shapes are connex by a vertex (vertices)
869 //=======================================================================
871 static Standard_Boolean AreConnex(const TopoDS_Wire& W1,
872 const TopoDS_Wire& W2,
873 const TopoDS_Shape& F1,
874 const TopoDS_Shape& F2,
875 const BOPDS_PDS& pDS)
877 TopoDS_Vertex V11, V12, V21, V22;
878 TopExp::Vertices( W1, V11, V12 );
879 TopExp::Vertices( W2, V21, V22 );
881 if (V11.IsSame(V21) || V11.IsSame(V22) ||
882 V12.IsSame(V21) || V12.IsSame(V22))
884 Standard_Boolean isCV1 = V11.IsSame(V21) || V11.IsSame(V22);
885 Standard_Boolean isCV2 = V12.IsSame(V21) || V12.IsSame(V22);
886 if (isCV1 && !IsAutonomVertex(V11, F1, F2, pDS))
889 return Standard_False;
890 if (!IsAutonomVertex(V12, F1, F2, pDS))
891 return Standard_False;
893 if (!isCV1 && !IsAutonomVertex(V12, F1, F2, pDS))
894 return Standard_False;
896 TopoDS_Vertex CV = (V11.IsSame(V21) || V11.IsSame(V22))? V11 : V12;
898 TopoDS_Iterator itw( W1 );
899 for (; itw.More(); itw.Next())
901 E1 = TopoDS::Edge(itw.Value());
902 TopoDS_Vertex V1, V2;
903 TopExp::Vertices( E1, V1, V2 );
904 if (V1.IsSame(CV) || V2.IsSame(CV))
907 itw.Initialize( W2 );
908 E2 = TopoDS::Edge(itw.Value());
911 Handle(Geom_Curve) C1 = BRep_Tool::Curve( E1, f, l );
912 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
913 C1 = (*((Handle(Geom_TrimmedCurve)*)&C1))->BasisCurve();
915 Handle(Geom_Curve) C2 = BRep_Tool::Curve( E2, f, l );
916 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
917 C2 = (*((Handle(Geom_TrimmedCurve)*)&C2))->BasisCurve();
919 if (C1->IsInstance(STANDARD_TYPE(Geom_Line)) &&
920 C2->IsInstance(STANDARD_TYPE(Geom_Line)))
922 Handle(Geom_Line) L1 = *((Handle(Geom_Line)*) &C1);
923 gp_Ax1 Axis1 = L1->Position();
924 Handle(Geom_Line) L2 = *((Handle(Geom_Line)*) &C2);
925 gp_Ax1 Axis2 = L2->Position();
926 if (! Axis1.IsParallel( Axis2, Precision::Angular() ))
927 return Standard_False;
930 return Standard_True;
933 return Standard_False;
936 //=======================================================================
937 //function : AreClosed
938 //purpose : define if two edges are connex by two vertices
939 //=======================================================================
941 static Standard_Boolean AreClosed(const TopoDS_Edge& E1,
942 const TopoDS_Edge& E2)
944 TopoDS_Vertex V11, V12, V21, V22;
945 TopExp::Vertices( E1, V11, V12 );
946 TopExp::Vertices( E2, V21, V22 );
948 if ((V11.IsSame(V21) && V12.IsSame(V22)) ||
949 (V11.IsSame(V22) && V12.IsSame(V21)))
950 return Standard_True;
952 return Standard_False;
955 //=======================================================================
956 //function : BSplineEdges
958 //=======================================================================
960 static Standard_Boolean BSplineEdges(const TopoDS_Edge& E1,
961 const TopoDS_Edge& E2,
962 const Standard_Integer par1,
963 const Standard_Integer par2,
964 Standard_Real& angle)
966 Standard_Real first1, last1, first2, last2, Param1, Param2;
968 Handle(Geom_Curve) C1 = BRep_Tool::Curve( E1, first1, last1 );
969 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
970 C1 = (*((Handle(Geom_TrimmedCurve)*)&C1))->BasisCurve();
972 Handle(Geom_Curve) C2 = BRep_Tool::Curve( E2, first2, last2 );
973 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
974 C2 = (*((Handle(Geom_TrimmedCurve)*)&C2))->BasisCurve();
976 if (!C1->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)) ||
977 !C2->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)))
978 return Standard_False;
980 Param1 = (par1 == 0)? first1 : last1;
981 Param2 = (par2 == 0)? first2 : last2;
985 C1->D1( Param1, Pnt1, Der1 );
986 C2->D1( Param2, Pnt2, Der2 );
988 if (Der1.Magnitude() <= gp::Resolution() ||
989 Der2.Magnitude() <= gp::Resolution())
992 angle = Der1.Angle(Der2);
994 return Standard_True;
997 //=======================================================================
998 //function : AngleWireEdge
1000 //=======================================================================
1002 static Standard_Real AngleWireEdge(const TopoDS_Wire& aWire,
1003 const TopoDS_Edge& anEdge)
1005 TopoDS_Vertex V11, V12, V21, V22, CV;
1006 TopExp::Vertices( aWire, V11, V12 );
1007 TopExp::Vertices( anEdge, V21, V22 );
1008 CV = (V11.IsSame(V21) || V11.IsSame(V22))? V11 : V12;
1009 TopoDS_Edge FirstEdge;
1010 TopoDS_Iterator itw(aWire);
1011 for (; itw.More(); itw.Next())
1013 FirstEdge = TopoDS::Edge(itw.Value());
1014 TopoDS_Vertex v1, v2;
1015 TopExp::Vertices( FirstEdge, v1, v2 );
1016 if (v1.IsSame(CV) || v2.IsSame(CV))
1023 Standard_Real Angle;
1024 if (V11.IsSame(CV) && V21.IsSame(CV))
1026 BSplineEdges( FirstEdge, anEdge, 0, 0, Angle );
1027 Angle = M_PI - Angle;
1029 else if (V11.IsSame(CV) && V22.IsSame(CV))
1030 BSplineEdges( FirstEdge, anEdge, 0, 1, Angle );
1031 else if (V12.IsSame(CV) && V21.IsSame(CV))
1032 BSplineEdges( FirstEdge, anEdge, 1, 0, Angle );
1035 BSplineEdges( FirstEdge, anEdge, 1, 1, Angle );
1036 Angle = M_PI - Angle;
1042 //=======================================================================
1043 //function : ReconstructPCurves
1045 //=======================================================================
1047 static void ReconstructPCurves(const TopoDS_Edge& anEdge)
1050 Handle(Geom_Curve) C3d = BRep_Tool::Curve(anEdge, f, l);
1052 BRep_ListIteratorOfListOfCurveRepresentation
1053 itcr( (Handle(BRep_TEdge)::DownCast(anEdge.TShape()))->ChangeCurves() );
1054 for (; itcr.More(); itcr.Next())
1056 Handle( BRep_CurveRepresentation ) CurveRep = itcr.Value();
1057 if (CurveRep->IsCurveOnSurface())
1059 Handle(Geom_Surface) theSurf = CurveRep->Surface();
1060 TopLoc_Location theLoc = CurveRep->Location();
1061 theLoc = anEdge.Location() * theLoc;
1062 theSurf = Handle(Geom_Surface)::DownCast
1063 (theSurf->Transformed(theLoc.Transformation()));
1064 Handle(Geom2d_Curve) ProjPCurve =
1065 GeomProjLib::Curve2d( C3d, f, l, theSurf );
1066 CurveRep->PCurve( ProjPCurve );
1071 //=======================================================================
1072 //function : ConcatPCurves
1074 //=======================================================================
1076 static Handle(Geom2d_Curve) ConcatPCurves(const TopoDS_Edge& E1,
1077 const TopoDS_Edge& E2,
1078 const TopoDS_Face& F,
1079 const Standard_Boolean After,
1080 Standard_Real& newFirst,
1081 Standard_Real& newLast)
1083 Standard_Real Tol = 1.e-7;
1084 GeomAbs_Shape Continuity = GeomAbs_C1;
1085 Standard_Integer MaxDeg = 14;
1086 Standard_Integer MaxSeg = 16;
1088 Standard_Real first1, last1, first2, last2;
1089 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1091 PCurve1 = BRep_Tool::CurveOnSurface( E1, F, first1, last1 );
1092 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
1093 PCurve1 = (*((Handle(Geom2d_TrimmedCurve)*)&PCurve1))->BasisCurve();
1095 PCurve2 = BRep_Tool::CurveOnSurface( E2, F, first2, last2 );
1096 if (PCurve2->IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve)))
1097 PCurve2 = (*((Handle(Geom2d_TrimmedCurve)*)&PCurve2))->BasisCurve();
1099 if (PCurve1 == PCurve2)
1101 newPCurve = PCurve1;
1102 newFirst = Min( first1, first2 );
1103 newLast = Max( last1, last2 );
1105 else if (PCurve1->DynamicType() == PCurve2->DynamicType() &&
1106 (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)) ||
1107 PCurve1->IsKind(STANDARD_TYPE(Geom2d_Conic))))
1109 newPCurve = PCurve1;
1111 P1 = PCurve2->Value( first2 );
1112 P2 = PCurve2->Value( last2 );
1113 if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Line)))
1115 Handle(Geom2d_Line) Lin1 = *((Handle(Geom2d_Line)*) &PCurve1);
1116 gp_Lin2d theLin = Lin1->Lin2d();
1117 first2 = ElCLib::Parameter( theLin, P1 );
1118 last2 = ElCLib::Parameter( theLin, P2 );
1120 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Circle)))
1122 Handle(Geom2d_Circle) Circ1 = *((Handle(Geom2d_Circle)*) &PCurve1);
1123 gp_Circ2d theCirc = Circ1->Circ2d();
1124 first2 = ElCLib::Parameter( theCirc, P1 );
1125 last2 = ElCLib::Parameter( theCirc, P2 );
1127 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Ellipse)))
1129 Handle(Geom2d_Ellipse) Ell1 = *((Handle(Geom2d_Ellipse)*) &PCurve1);
1130 gp_Elips2d theElips = Ell1->Elips2d();
1131 first2 = ElCLib::Parameter( theElips, P1 );
1132 last2 = ElCLib::Parameter( theElips, P2 );
1134 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Parabola)))
1136 Handle(Geom2d_Parabola) Parab1 = *((Handle(Geom2d_Parabola)*) &PCurve1);
1137 gp_Parab2d theParab = Parab1->Parab2d();
1138 first2 = ElCLib::Parameter( theParab, P1 );
1139 last2 = ElCLib::Parameter( theParab, P2 );
1141 else if (PCurve1->IsInstance(STANDARD_TYPE(Geom2d_Hyperbola)))
1143 Handle(Geom2d_Hyperbola) Hypr1 = *((Handle(Geom2d_Hyperbola)*) &PCurve1);
1144 gp_Hypr2d theHypr = Hypr1->Hypr2d();
1145 first2 = ElCLib::Parameter( theHypr, P1 );
1146 last2 = ElCLib::Parameter( theHypr, P2 );
1148 newFirst = Min( first1, first2 );
1149 newLast = Max( last1, last2 );
1153 Handle(Geom2d_TrimmedCurve) TC1 = new Geom2d_TrimmedCurve( PCurve1, first1, last1 );
1154 Handle(Geom2d_TrimmedCurve) TC2 = new Geom2d_TrimmedCurve( PCurve2, first2, last2 );
1155 Geom2dConvert_CompCurveToBSplineCurve Concat2d( TC1 );
1156 Concat2d.Add( TC2, Precision::Confusion(), After );
1157 newPCurve = Concat2d.BSplineCurve();
1158 if (newPCurve->Continuity() < GeomAbs_C1)
1160 Geom2dConvert_ApproxCurve Approx2d( newPCurve, Tol, Continuity, MaxSeg, MaxDeg );
1161 if (Approx2d.HasResult())
1162 newPCurve = Approx2d.Curve();
1164 newFirst = newPCurve->FirstParameter();
1165 newLast = newPCurve->LastParameter();
1171 //=======================================================================
1173 //purpose : glue two edges.
1174 //=======================================================================
1176 static TopoDS_Edge Glue(const TopoDS_Edge& E1,
1177 const TopoDS_Edge& E2,
1178 const TopoDS_Vertex& Vfirst,
1179 const TopoDS_Vertex& Vlast,
1180 const Standard_Boolean After,
1181 const TopoDS_Face& F1,
1182 const Standard_Boolean addPCurve1,
1183 const TopoDS_Face& F2,
1184 const Standard_Boolean addPCurve2)
1186 Standard_Real Tol = 1.e-7;
1187 GeomAbs_Shape Continuity = GeomAbs_C1;
1188 Standard_Integer MaxDeg = 14;
1189 Standard_Integer MaxSeg = 16;
1191 Handle(Geom_Curve) C1, C2, newCurve;
1192 Handle(Geom2d_Curve) PCurve1, PCurve2, newPCurve;
1193 Standard_Real first1, last1, first2, last2, fparam=0., lparam=0.;
1194 Standard_Boolean IsCanonic = Standard_False;
1196 C1 = BRep_Tool::Curve( E1, first1, last1 );
1197 if (C1->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
1198 C1 = (*((Handle(Geom_TrimmedCurve)*)&C1))->BasisCurve();
1200 C2 = BRep_Tool::Curve( E2, first2, last2 );
1201 if (C2->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
1202 C2 = (*((Handle(Geom_TrimmedCurve)*)&C2))->BasisCurve();
1207 fparam = Min( first1, first2 );
1208 lparam = Max( last1, last2 );
1210 else if (C1->DynamicType() == C2->DynamicType() &&
1211 (C1->IsInstance(STANDARD_TYPE(Geom_Line)) ||
1212 C1->IsKind(STANDARD_TYPE(Geom_Conic))))
1214 IsCanonic = Standard_True;
1219 Handle(Geom_TrimmedCurve) TC1 = new Geom_TrimmedCurve( C1, first1, last1 );
1220 Handle(Geom_TrimmedCurve) TC2 = new Geom_TrimmedCurve( C2, first2, last2 );
1221 GeomConvert_CompCurveToBSplineCurve Concat( TC1 );
1222 Concat.Add( TC2, Precision::Confusion(), After );
1223 newCurve = Concat.BSplineCurve();
1224 if (newCurve->Continuity() < GeomAbs_C1)
1226 GeomConvert_ApproxCurve Approx3d( newCurve, Tol, Continuity, MaxSeg, MaxDeg );
1227 if (Approx3d.HasResult())
1228 newCurve = Approx3d.Curve();
1230 fparam = newCurve->FirstParameter();
1231 lparam = newCurve->LastParameter();
1234 TopoDS_Edge newEdge;
1238 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast );
1240 newEdge = BRepLib_MakeEdge( newCurve, Vfirst, Vlast, fparam, lparam );
1242 Standard_Real newFirst, newLast;
1245 newPCurve = ConcatPCurves( E1, E2, F1, After, newFirst, newLast );
1246 BB.UpdateEdge( newEdge, newPCurve, F1, 0. );
1247 BB.Range( newEdge, F1, newFirst, newLast );
1251 newPCurve = ConcatPCurves( E1, E2, F2, After, newFirst, newLast );
1252 BB.UpdateEdge( newEdge, newPCurve, F2, 0. );
1253 BB.Range( newEdge, F2, newFirst, newLast );
1260 //=======================================================================
1261 //function : FindNewVerticesOnBoundsOfFace
1263 //=======================================================================
1265 static void FindNewVerticesOnBoundsOfFace(const BOPDS_PDS& pDS,
1266 const TopoDS_Face& aFace,
1267 TopTools_DataMapOfShapeShape& VEmap)
1269 TopTools_IndexedMapOfShape OldVertices;
1270 TopExp::MapShapes( aFace, TopAbs_VERTEX, OldVertices );
1271 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
1272 TopoDS_Vertex V1, V2;
1274 TopExp_Explorer Explo( aFace, TopAbs_EDGE );
1275 for (; Explo.More(); Explo.Next()) {
1276 const TopoDS_Shape& aE = Explo.Current();
1277 Standard_Integer nE = pDS->Index(aE);
1279 const BOPDS_ListOfPaveBlock& aLPB = pDS->PaveBlocks(nE);
1280 aItLPB.Initialize(aLPB);
1281 for (; aItLPB.More(); aItLPB.Next()) {
1282 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
1283 const TopoDS_Edge& aESp = *(TopoDS_Edge*)&pDS->Shape(aPB->Edge());
1285 TopExp::Vertices( aESp, V1, V2 );
1286 if (!OldVertices.Contains( V1 )) {
1287 VEmap.Bind( V1, aE );
1290 if (!OldVertices.Contains( V2 )) {
1291 VEmap.Bind( V2, aE );
1297 //=======================================================================
1298 //function : CheckIntersFF
1300 //=======================================================================
1302 static Standard_Boolean CheckIntersFF(const BOPDS_PDS& pDS,
1303 const TopoDS_Edge& RefEdge,
1304 const TopoDS_Face& F1,
1305 const TopoDS_Face& F2,
1306 TopTools_IndexedMapOfShape& TrueEdges)
1308 Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
1309 Standard_Boolean isPlane1 = Standard_False, isPlane2 = Standard_False;
1311 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F1);
1312 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1313 aSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&aSurf))->BasisSurface();
1314 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1315 isPlane1 = Standard_True;
1316 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1317 isEl1 = Standard_True;
1319 aSurf = BRep_Tool::Surface(F2);
1320 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1321 aSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&aSurf))->BasisSurface();
1322 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1323 isPlane2 = Standard_True;
1324 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1325 isEl2 = Standard_True;
1327 if (isPlane1 || isPlane2)
1328 return Standard_True;
1331 return Standard_True;
1333 BOPDS_VectorOfInterfFF& aFFs = pDS->InterfFF();
1334 Standard_Integer aNb = aFFs.Extent();
1335 Standard_Integer i, j, nbe = 0;
1337 TopTools_SequenceOfShape Edges;
1339 for (i = 0; i < aNb; ++i)
1341 BOPDS_InterfFF& aFFi=aFFs(i);
1342 const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
1343 Standard_Integer aNbCurves = aBCurves.Extent();
1345 for (j = 0; j < aNbCurves; ++j)
1347 const BOPDS_Curve& aBC=aBCurves(j);
1348 const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
1350 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1351 aPBIt.Initialize(aSectEdges);
1353 for (; aPBIt.More(); aPBIt.Next())
1355 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
1356 Standard_Integer nSect = aPB->Edge();
1357 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
1358 Edges.Append( anEdge );
1365 return Standard_True;
1367 //define tangents of RefEdge on start and on end
1368 BRepAdaptor_Curve cref(RefEdge);
1369 gp_Vec RefTangFirst = cref.DN(cref.FirstParameter(), 1);
1370 gp_Vec RefTangLast = cref.DN(cref.LastParameter(), 1);
1372 //find the start edge and take it from Edges
1373 TopoDS_Edge StartEdge; //, StartEonF1, StartEonF2, EndEonF1, EndEonF2;
1375 TopTools_DataMapOfShapeShape VEmapF1, VEmapF2;
1376 FindNewVerticesOnBoundsOfFace( pDS, F1, VEmapF1 );
1377 FindNewVerticesOnBoundsOfFace( pDS, F2, VEmapF2 );
1379 Standard_Real AngTol = 0.1;
1380 Standard_Boolean V1onBound = Standard_False;
1381 Standard_Boolean V2onBound = Standard_False;
1382 TopoDS_Vertex V1, V2, Vcur;
1383 gp_Vec TangFirst, TangLast, TangCur;
1384 for (i = 1; i <= Edges.Length(); i++)
1386 StartEdge = TopoDS::Edge(Edges(i));
1387 TopExp::Vertices( StartEdge, V1, V2 );
1388 V1onBound = VEmapF1.IsBound(V1) || VEmapF2.IsBound(V1); // && ?
1389 V2onBound = VEmapF1.IsBound(V2) || VEmapF2.IsBound(V2); // && ?
1390 if (V1onBound || V2onBound)
1392 BRepAdaptor_Curve CE(StartEdge);
1393 TangFirst = CE.DN( CE.FirstParameter(), 1 );
1394 TangLast = CE.DN( CE.LastParameter(), 1 );
1397 if (TangFirst.IsParallel( RefTangFirst, AngTol ) ||
1398 TangFirst.IsParallel( RefTangLast, AngTol ))
1399 break; //start edged found
1403 if (TangLast.IsParallel( RefTangLast, AngTol ) ||
1404 TangLast.IsParallel( RefTangFirst, AngTol ))
1405 break; //start edged found
1410 if (i > Edges.Length()) //start edged not found
1411 return Standard_False;
1413 if (V1onBound && V2onBound)
1415 if ((TangFirst.IsParallel(RefTangFirst,AngTol) && TangLast.IsParallel(RefTangLast,AngTol)) ||
1416 (TangFirst.IsParallel(RefTangLast,AngTol) && TangLast.IsParallel(RefTangFirst,AngTol)))
1418 TrueEdges.Add( Edges(i) );
1419 return Standard_True;
1422 return Standard_False;
1425 //StartEonF1 = (V1onBound)? VEmapF1( V1 ) : VEmapF1( V2 );
1426 //StartEonF2 = (V1onBound)? VEmapF2( V1 ) : VEmapF2( V2 );
1428 TrueEdges.Add( Edges(i) );
1430 Vcur = (V1onBound)? V2 : V1;
1431 TangCur = (V1onBound)? TangLast : TangFirst;
1435 //build the chain from StartEdge till the opposite bound of face
1438 TColStd_SequenceOfInteger Candidates;
1439 for (i = 1; i <= Edges.Length(); i++)
1441 TopoDS_Edge anEdge = TopoDS::Edge(Edges(i));
1442 TopExp::Vertices( anEdge, V1, V2 );
1443 if (V1.IsSame(Vcur) || V2.IsSame(Vcur))
1444 Candidates.Append(i);
1446 if (Candidates.IsEmpty())
1449 return Standard_False;
1452 Standard_Integer minind = 1;
1453 if (Candidates.Length() > 1)
1455 Standard_Real MinAngle = RealLast();
1456 for (i = 1; i <= Candidates.Length(); i++)
1458 TopoDS_Edge anEdge = TopoDS::Edge(Edges(Candidates(i)));
1459 TopExp::Vertices( anEdge, V1, V2 );
1460 Standard_Boolean ConnectByFirst = (Vcur.IsSame(V1))? Standard_True : Standard_False;
1461 BRepAdaptor_Curve CE(anEdge);
1462 gp_Vec aTang = (ConnectByFirst)?
1463 CE.DN( CE.FirstParameter(), 1 ) : CE.DN( CE.LastParameter(), 1 );
1464 if (!ConnectByFirst)
1466 Standard_Real anAngle = TangCur.Angle(aTang);
1467 if (anAngle < MinAngle)
1474 TopoDS_Edge CurEdge = TopoDS::Edge(Edges(Candidates(minind)));
1475 TrueEdges.Add( CurEdge );
1476 Edges.Remove(Candidates(minind));
1477 TopExp::Vertices( CurEdge, V1, V2 );
1478 Standard_Boolean ConnectByFirst = (Vcur.IsSame(V1))? Standard_True : Standard_False;
1479 Vcur = (ConnectByFirst)? V2 : V1;
1480 BRepAdaptor_Curve CE(CurEdge);
1481 TangCur = (ConnectByFirst)? CE.DN( CE.LastParameter(), 1 ) : CE.DN( CE.FirstParameter(), 1 );
1482 if (!ConnectByFirst)
1484 //check if Vcur is on bounds of faces
1485 if (VEmapF1.IsBound(Vcur) || VEmapF2.IsBound(Vcur))
1489 if (TangCur.IsParallel( RefTangFirst, AngTol ) ||
1490 TangCur.IsParallel( RefTangLast, AngTol ))
1491 return Standard_True;
1494 return Standard_False;
1497 //=======================================================================
1498 //function : AssembleEdge
1500 //=======================================================================
1502 static TopoDS_Edge AssembleEdge(const BOPDS_PDS& pDS,
1503 const TopoDS_Face& F1,
1504 const TopoDS_Face& F2,
1505 const Standard_Boolean addPCurve1,
1506 const Standard_Boolean addPCurve2,
1507 const TopTools_SequenceOfShape& EdgesForConcat)
1509 TopoDS_Edge CurEdge = TopoDS::Edge( EdgesForConcat(1) );
1510 for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
1512 TopoDS_Edge anEdge = TopoDS::Edge( EdgesForConcat(j) );
1513 Standard_Boolean After = Standard_False;
1514 TopoDS_Vertex Vfirst, Vlast;
1515 if (AreClosed( CurEdge, anEdge ))
1517 TopoDS_Vertex V1, V2;
1518 TopExp::Vertices( CurEdge, V1, V2 );
1519 if (IsAutonomVertex( V1, F1, F2, pDS ))
1521 After = Standard_False;
1522 Vfirst = Vlast = V2;
1526 After = Standard_True;
1527 Vfirst = Vlast = V1;
1532 TopoDS_Vertex CV, V11, V12, V21, V22;
1533 TopExp::CommonVertex( CurEdge, anEdge, CV );
1534 TopExp::Vertices( CurEdge, V11, V12 );
1535 TopExp::Vertices( anEdge, V21, V22 );
1536 if (V11.IsSame(CV) && V21.IsSame(CV))
1541 else if (V11.IsSame(CV) && V22.IsSame(CV))
1546 else if (V12.IsSame(CV) && V21.IsSame(CV))
1556 } //end of else (open wire)
1558 TopoDS_Edge NewEdge = Glue(CurEdge, anEdge,
1559 Vfirst, Vlast, After,
1560 F1, addPCurve1, F2, addPCurve2);
1562 } //end of for (Standard_Integer j = 2; j <= EdgesForConcat.Length(); j++)
1567 //=======================================================================
1568 //function : Inter3D
1570 //=======================================================================
1572 void BRepOffset_Tool::Inter3D(const TopoDS_Face& F1,
1573 const TopoDS_Face& F2,
1574 TopTools_ListOfShape& L1,
1575 TopTools_ListOfShape& L2,
1576 const TopAbs_State Side,
1577 const TopoDS_Edge& RefEdge,
1578 const Standard_Boolean IsRefEdgeDefined)
1583 char* name = new char[100];
1584 sprintf(name,"FF_%d",NbFaces++);
1585 DBRep::Set(name,F1);
1586 sprintf(name,"FF_%d",NbFaces++);
1587 DBRep::Set(name,F2);
1591 TopoDS_Face cpF1=F1;
1592 TopoDS_Face cpF2=F2;
1593 // create 3D curves on faces
1594 BRepLib::BuildCurves3d(cpF1);
1595 BRepLib::BuildCurves3d(cpF2);
1597 BOPAlgo_PaveFiller aPF1, aPF2;
1598 BOPCol_ListOfShape aLS;
1601 aPF1.SetArguments(aLS);
1605 BOPAlgo_PaveFiller *pPF = &aPF1;
1608 TopTools_IndexedMapOfShape TrueEdges;
1609 if (IsRefEdgeDefined && !CheckIntersFF( pPF->PDS(), RefEdge, cpF1, cpF2, TrueEdges ))
1615 aPF2.SetArguments(aLS);
1618 CheckIntersFF( pPF->PDS(), RefEdge, cpF1, cpF2, TrueEdges );
1621 Standard_Boolean addPCurve1 = 1;
1622 Standard_Boolean addPCurve2 = 1;
1624 const BOPDS_PDS& pDS = pPF->PDS();
1625 BOPDS_VectorOfInterfFF& aFFs=pDS->InterfFF();
1626 Standard_Integer aNb = aFFs.Extent();
1627 Standard_Integer i = 0, j = 0, k;
1629 L1.Clear(); L2.Clear();
1630 TopAbs_Orientation O1,O2;
1632 for (i = 0; i < aNb; i++) {
1633 BOPDS_InterfFF& aFFi=aFFs(i);
1634 const BOPDS_VectorOfCurve& aBCurves=aFFi.Curves();
1636 Standard_Integer aNbCurves = aBCurves.Extent();
1638 for (j = 0; j < aNbCurves; j++) {
1639 const BOPDS_Curve& aBC=aBCurves(j);
1640 const BOPDS_ListOfPaveBlock& aSectEdges = aBC.PaveBlocks();
1642 BOPDS_ListIteratorOfListOfPaveBlock aPBIt;
1643 aPBIt.Initialize(aSectEdges);
1645 for (; aPBIt.More(); aPBIt.Next()) {
1646 const Handle(BOPDS_PaveBlock)& aPB = aPBIt.Value();
1647 Standard_Integer nSect = aPB->Edge();
1648 const TopoDS_Edge& anEdge = *(TopoDS_Edge*)&pDS->Shape(nSect);
1649 if (!TrueEdges.IsEmpty() && !TrueEdges.Contains(anEdge))
1653 const Handle(Geom_Curve)& aC3DE = BRep_Tool::Curve(anEdge, f, l);
1654 Handle(Geom_TrimmedCurve) aC3DETrim;
1657 aC3DETrim = new Geom_TrimmedCurve(aC3DE, f, l);
1660 Standard_Real aTolEdge = BRep_Tool::Tolerance(anEdge);
1662 if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, cpF1)) {
1663 Handle(Geom2d_Curve) aC2d = aBC.Curve().FirstCurve2d();
1664 if(!aC3DETrim.IsNull()) {
1665 Handle(Geom2d_Curve) aC2dNew;
1667 if(aC3DE->IsPeriodic()) {
1668 BOPTools_AlgoTools2D::AdjustPCurveOnFace(cpF1, f, l, aC2d, aC2dNew);
1671 BOPTools_AlgoTools2D::AdjustPCurveOnFace(cpF1, aC3DETrim, aC2d, aC2dNew);
1675 aBB.UpdateEdge(anEdge, aC2d, cpF1, aTolEdge);
1678 if (!BOPTools_AlgoTools2D::HasCurveOnSurface(anEdge, cpF2)) {
1679 Handle(Geom2d_Curve) aC2d = aBC.Curve().SecondCurve2d();
1680 if(!aC3DETrim.IsNull()) {
1681 Handle(Geom2d_Curve) aC2dNew;
1683 if(aC3DE->IsPeriodic()) {
1684 BOPTools_AlgoTools2D::AdjustPCurveOnFace(cpF2, f, l, aC2d, aC2dNew);
1687 BOPTools_AlgoTools2D::AdjustPCurveOnFace(cpF2, aC3DETrim, aC2d, aC2dNew);
1691 aBB.UpdateEdge(anEdge, aC2d, cpF2, aTolEdge);
1694 OrientSection (anEdge, F1, F2, O1, O2);
1695 if (Side == TopAbs_OUT) {
1696 O1 = TopAbs::Reverse(O1);
1697 O2 = TopAbs::Reverse(O2);
1700 L1.Append (anEdge.Oriented(O1));
1701 L2.Append (anEdge.Oriented(O2));
1705 char* name = new char[100];
1706 sprintf(name,"EI_%d",NbNewEdges++);
1707 DBRep::Set(name,anEdge.Oriented(O1));
1715 Standard_Real aSameParTol = Precision::Confusion();
1716 Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
1718 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(cpF1);
1719 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1720 aSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&aSurf))->BasisSurface();
1721 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1722 addPCurve1 = Standard_False;
1723 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1724 isEl1 = Standard_True;
1726 aSurf = BRep_Tool::Surface(cpF2);
1727 if (aSurf->IsInstance(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
1728 aSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&aSurf))->BasisSurface();
1729 if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane)))
1730 addPCurve2 = Standard_False;
1731 else if (aSurf->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
1732 isEl2 = Standard_True;
1734 if (L1.Extent() > 1 && (!isEl1 || !isEl2)) {
1735 TopTools_SequenceOfShape eseq;
1736 TopTools_SequenceOfShape EdgesForConcat;
1738 if (!TrueEdges.IsEmpty())
1740 for (i = TrueEdges.Extent(); i >= 1; i--)
1741 EdgesForConcat.Append( TrueEdges(i) );
1742 TopoDS_Edge theEdge =
1743 AssembleEdge( pDS, cpF1, cpF2, addPCurve1, addPCurve2, EdgesForConcat );
1744 eseq.Append(theEdge);
1749 TopTools_SequenceOfShape wseq;
1750 TopTools_SequenceOfShape edges;
1751 TopTools_ListIteratorOfListOfShape itl(L1);
1752 for (; itl.More(); itl.Next())
1753 edges.Append( itl.Value() );
1754 while (!edges.IsEmpty())
1756 TopoDS_Edge anEdge = TopoDS::Edge( edges.First() );
1757 TopoDS_Wire aWire = BRepLib_MakeWire( anEdge ), resWire;
1758 TColStd_SequenceOfInteger Candidates;
1759 for (k = 1; k <= wseq.Length(); k++)
1761 resWire = TopoDS::Wire(wseq(k));
1762 if (AreConnex( resWire, aWire, cpF1, cpF2, pDS ))
1764 Candidates.Append( 1 );
1768 if (Candidates.IsEmpty())
1770 wseq.Append( aWire );
1775 for (j = 2; j <= edges.Length(); j++)
1777 anEdge = TopoDS::Edge( edges(j) );
1778 //if (anEdge.IsSame(edges(Candidates.First())))
1780 aWire = BRepLib_MakeWire( anEdge );
1781 if (AreConnex( resWire, aWire, cpF1, cpF2, pDS ))
1782 Candidates.Append( j );
1784 Standard_Integer minind = 1;
1785 if (Candidates.Length() > 1)
1787 Standard_Real MinAngle = RealLast();
1788 for (j = 1; j <= Candidates.Length(); j++)
1790 anEdge = TopoDS::Edge( edges(Candidates(j)) );
1791 Standard_Real anAngle = AngleWireEdge( resWire, anEdge );
1792 if (anAngle < MinAngle)
1799 TopoDS_Wire NewWire = BRepLib_MakeWire( resWire, TopoDS::Edge(edges(Candidates(minind))) );
1801 edges.Remove(Candidates(minind));
1803 } //end of while (!edges.IsEmpty())
1805 for (i = 1; i <= wseq.Length(); i++)
1807 TopoDS_Wire aWire = TopoDS::Wire(wseq(i));
1808 TopTools_SequenceOfShape EdgesForConcat;
1811 TopoDS_Vertex StartVertex;
1812 TopoDS_Edge StartEdge;
1813 Standard_Boolean StartFound = Standard_False;
1814 TopTools_ListOfShape Elist;
1816 TopoDS_Iterator itw(aWire);
1817 for (; itw.More(); itw.Next())
1819 TopoDS_Edge anEdge = TopoDS::Edge(itw.Value());
1821 Elist.Append(anEdge);
1824 TopoDS_Vertex V1, V2;
1825 TopExp::Vertices( anEdge, V1, V2 );
1826 if (!IsAutonomVertex( V1, cpF1, cpF2, pDS ))
1830 StartFound = Standard_True;
1832 else if (!IsAutonomVertex( V2, cpF1, cpF2, pDS ))
1836 StartFound = Standard_True;
1839 Elist.Append(anEdge);
1841 } //end of for (; itw.More(); itw.Next())
1844 itl.Initialize(Elist);
1845 StartEdge = TopoDS::Edge(itl.Value());
1847 TopoDS_Vertex V1, V2;
1848 TopExp::Vertices( StartEdge, V1, V2 );
1851 EdgesForConcat.Append( StartEdge );
1852 while (!Elist.IsEmpty())
1854 for (itl.Initialize(Elist); itl.More(); itl.Next())
1856 TopoDS_Edge anEdge = TopoDS::Edge(itl.Value());
1857 TopoDS_Vertex V1, V2;
1858 TopExp::Vertices( anEdge, V1, V2 );
1859 if (V1.IsSame(StartVertex))
1862 EdgesForConcat.Append( anEdge );
1866 else if (V2.IsSame(StartVertex))
1869 EdgesForConcat.Append( anEdge );
1874 } //end of while (!Elist.IsEmpty())
1875 } //end of if (aWire.Closed())
1878 BRepTools_WireExplorer Wexp( aWire );
1879 for (; Wexp.More(); Wexp.Next())
1880 EdgesForConcat.Append( Wexp.Current() );
1883 TopoDS_Edge theEdge =
1884 AssembleEdge( pDS, cpF1, cpF2, addPCurve1, addPCurve2, EdgesForConcat );
1885 eseq.Append( theEdge );
1887 } //end of else (when TrueEdges is empty)
1889 if (eseq.Length() < L1.Extent())
1893 for (i = 1; i <= eseq.Length(); i++)
1895 TopoDS_Edge anEdge = TopoDS::Edge(eseq(i));
1896 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1897 Standard_Real EdgeTol = BRep_Tool::Tolerance(anEdge);
1899 cout<<"Tolerance of glued E = "<<EdgeTol<<endl;
1901 if (EdgeTol > 1.e-2)
1904 if (EdgeTol >= 1.e-4)
1906 ReconstructPCurves(anEdge);
1907 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1909 cout<<"After projection tol of E = "<<BRep_Tool::Tolerance(anEdge)<<endl;
1913 OrientSection( anEdge, F1, F2, O1, O2 );
1914 if (Side == TopAbs_OUT)
1916 O1 = TopAbs::Reverse(O1);
1917 O2 = TopAbs::Reverse(O2);
1920 L1.Append( anEdge.Oriented(O1) );
1921 L2.Append( anEdge.Oriented(O2) );
1924 } //end of if (L1.Extent() > 1)
1928 TopTools_ListIteratorOfListOfShape itl(L1);
1929 for (; itl.More(); itl.Next())
1931 const TopoDS_Edge& anEdge = TopoDS::Edge( itl.Value() );
1932 BRepLib::SameParameter(anEdge, aSameParTol, Standard_True);
1937 //=======================================================================
1938 //function : TryProject
1940 //=======================================================================
1942 Standard_Boolean BRepOffset_Tool::TryProject
1943 (const TopoDS_Face& F1,
1944 const TopoDS_Face& F2,
1945 const TopTools_ListOfShape& Edges,
1946 TopTools_ListOfShape& LInt1,
1947 TopTools_ListOfShape& LInt2,
1948 const TopAbs_State Side,
1949 const Standard_Real TolConf)
1954 char* name = new char[100];
1955 sprintf(name,"FF_%d",NbFaces++);
1956 DBRep::Set(name,F1);
1957 sprintf(name,"FF_%d",NbFaces++);
1958 DBRep::Set(name,F2);
1962 // try to find if the edges <Edges> are laying on the face F1.
1963 LInt1.Clear(); LInt2.Clear();
1964 TopTools_ListIteratorOfListOfShape it(Edges);
1965 Standard_Boolean isOk = Standard_True;
1966 Standard_Boolean Ok = Standard_True;
1967 TopAbs_Orientation O1,O2;
1968 Handle(Geom_Surface) Bouchon = BRep_Tool::Surface(F1);
1971 for ( ; it.More(); it.Next()) {
1974 TopoDS_Edge CurE = TopoDS::Edge(it.Value());
1975 Handle(Geom_Curve) C = BRep_Tool::Curve(CurE,L,f,l);
1977 BRepLib::BuildCurve3d(CurE,BRep_Tool::Tolerance(CurE));
1978 C = BRep_Tool::Curve(CurE,L,f,l);
1980 C = new Geom_TrimmedCurve(C,f,l);
1981 if ( !L.IsIdentity()) C->Transform(L);
1982 Standard_Real TolReached;
1983 isOk = IsOnSurface(C,Bouchon,TolConf,TolReached);
1986 B.UpdateEdge(CurE,TolReached);
1987 BuildPCurves(CurE,F1);
1988 OrientSection (CurE,F1,F2,O1,O2);
1989 if (Side == TopAbs_OUT) {
1990 O1 = TopAbs::Reverse(O1);
1991 O2 = TopAbs::Reverse(O2);
1993 LInt1.Append (CurE.Oriented(O1));
1994 LInt2.Append (CurE.Oriented(O2));
1998 char* name = new char[100];
1999 sprintf(name,"EI_%d",NbNewEdges++);
2000 DBRep::Set(name,CurE.Oriented(O1));
2005 Ok = Standard_False;
2011 //=======================================================================
2012 //function : InterOrExtent
2014 //=======================================================================
2016 void BRepOffset_Tool::InterOrExtent(const TopoDS_Face& F1,
2017 const TopoDS_Face& F2,
2018 TopTools_ListOfShape& L1,
2019 TopTools_ListOfShape& L2,
2020 const TopAbs_State Side)
2025 char* name = new char[100];
2026 sprintf(name,"FF_%d",NbFaces++);
2027 DBRep::Set(name,F1);
2028 sprintf(name,"FF_%d",NbFaces++);
2029 DBRep::Set(name,F2);
2033 Handle (Geom_Curve) CI;
2035 TopAbs_Orientation O1,O2;
2036 L1.Clear(); L2.Clear();
2037 Handle (Geom_Surface) S1 = BRep_Tool::Surface(F1);
2038 Handle (Geom_Surface) S2 = BRep_Tool::Surface(F2);
2040 if (S1->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2041 Handle(Geom_RectangularTrimmedSurface) RTS ;
2042 RTS = *((Handle(Geom_RectangularTrimmedSurface)*) &S1);
2043 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
2044 S1 = RTS->BasisSurface();
2047 if (S2->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2048 Handle(Geom_RectangularTrimmedSurface) RTS ;
2049 RTS = *((Handle(Geom_RectangularTrimmedSurface)*) &S2);
2050 if (RTS->BasisSurface()->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
2051 S2 = RTS->BasisSurface();
2055 GeomInt_IntSS Inter (S1,S2, Precision::Confusion());
2057 if (Inter.IsDone()) {
2058 for (Standard_Integer i = 1; i <= Inter.NbLines(); i++) {
2061 if (ToSmall(CI)) continue;
2062 TopoDS_Edge E = BRepLib_MakeEdge(CI);
2063 BuildPCurves (E,F1);
2064 BuildPCurves (E,F2);
2065 OrientSection (E,F1,F2,O1,O2);
2066 if (Side == TopAbs_OUT) {
2067 O1 = TopAbs::Reverse(O1);
2068 O2 = TopAbs::Reverse(O2);
2070 L1.Append (E.Oriented(O1));
2071 L2.Append (E.Oriented(O2));
2075 char* name = new char[100];
2076 sprintf(name,"EI_%d",NbNewEdges++);
2077 DBRep::Set(name,E.Oriented(O1));
2084 //=======================================================================
2085 //function : ExtentEdge
2087 //=======================================================================
2089 static void ExtentEdge(const TopoDS_Face& F,
2090 const TopoDS_Face& EF,
2091 const TopoDS_Edge& E,
2094 BRepAdaptor_Curve CE(E);
2095 GeomAbs_CurveType Type = CE.GetType();
2096 TopoDS_Shape aLocalEdge = E.EmptyCopied();
2097 NE = TopoDS::Edge(aLocalEdge);
2098 // NE = TopoDS::Edge(E.EmptyCopied());
2100 if (Type == GeomAbs_Line || Type == GeomAbs_Circle || Type == GeomAbs_Ellipse ||
2101 Type == GeomAbs_Hyperbola || Type == GeomAbs_Parabola) {
2104 // Extension en tangence jusqu'au bord de la surface.
2105 Standard_Real PMax = 1.e2;
2107 Handle(Geom_Surface) S = BRep_Tool::Surface(F,L);
2108 Standard_Real umin,umax,vmin,vmax;
2110 S->Bounds(umin,umax,vmin,vmax);
2111 umin = Max(umin,-PMax);vmin = Max(vmin,-PMax);
2112 umax = Min(umax, PMax);vmax = Min(vmax, PMax);
2116 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E,F,f,l);
2118 //calcul point cible . ie point d'intersection du prolongement tangent et des bords.
2121 C2d->D1(CE.FirstParameter(),P,Tang);
2122 Standard_Real tx,ty,tmin;
2123 tx = ty = Precision::Infinite();
2124 if (Abs(Tang.X()) > Precision::Confusion())
2125 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
2126 if (Abs(Tang.Y()) > Precision::Confusion())
2127 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
2130 gp_Pnt2d PF2d (P.X() - Tang.X(),P.Y() - Tang.Y());
2132 C2d->D1(CE.LastParameter(),P,Tang);
2133 tx = ty = Precision::Infinite();
2134 if (Abs(Tang.X()) > Precision::Confusion())
2135 tx = Min (Abs((umax - P.X())/Tang.X()), Abs((umin - P.X())/Tang.X()));
2136 if (Abs(Tang.Y()) > Precision::Confusion())
2137 ty = Min (Abs((vmax - P.Y())/Tang.Y()), Abs((vmin - P.Y())/Tang.Y()));
2140 gp_Pnt2d PL2d (P.X() + Tang.X(),P.Y() + Tang.Y());
2142 Handle(Geom_Curve) CC = GeomAPI::To3d(C2d,gp_Pln(gp::XOY()));
2143 gp_Pnt PF(PF2d.X(),PF2d.Y(),0.);
2144 gp_Pnt PL(PL2d.X(),PL2d.Y(),0.);
2146 Handle(Geom_BoundedCurve) ExtC = Handle(Geom_BoundedCurve)::DownCast(CC);
2147 if (ExtC.IsNull()) return;
2149 GeomLib::ExtendCurveToPoint(ExtC,PF,1,0);
2150 GeomLib::ExtendCurveToPoint(ExtC,PL,1,1);
2152 Handle(Geom2d_Curve) CNE2d = GeomAPI::To2d(ExtC,gp_Pln(gp::XOY()));
2154 //Construction de la nouvelle arrete;
2157 // B.UpdateEdge (NE,CNE2d,F,BRep_Tool::Tolerance(E));
2158 B.UpdateEdge (NE,CNE2d,EF,BRep_Tool::Tolerance(E));
2159 B.Range (NE,CNE2d->FirstParameter(), CNE2d->LastParameter());
2160 NE.Orientation(E.Orientation());
2163 char* name = new char[100];
2164 sprintf (name,"F_%d",NbExtE);
2165 DBRep::Set(name,EF);
2166 sprintf (name,"OE_%d",NbExtE);
2167 DBRep::Set (name,E);
2168 sprintf (name,"ExtE_%d",NbExtE++);
2169 DBRep::Set(name,NE);
2174 //=======================================================================
2175 //function : ProjectVertexOnEdge
2177 //=======================================================================
2179 static Standard_Boolean ProjectVertexOnEdge(TopoDS_Vertex& V,
2180 const TopoDS_Edge& E,
2181 Standard_Real TolConf)
2191 Standard_Real U = 0.;
2193 Standard_Boolean found = Standard_False;
2195 gp_Pnt P = BRep_Tool::Pnt (V);
2196 BRepAdaptor_Curve C = BRepAdaptor_Curve(E);
2197 f = C.FirstParameter(); l = C.LastParameter();
2199 if (V.Orientation() == TopAbs_FORWARD) {
2200 if (Abs(f) < Precision::Infinite()) {
2201 gp_Pnt PF = C.Value (f);
2202 if (PF.IsEqual(P,TolConf)) {
2204 found = Standard_True;
2208 if (V.Orientation() == TopAbs_REVERSED) {
2209 if (!found && Abs(l) < Precision::Infinite()) {
2210 gp_Pnt PL = C.Value (l);
2211 if (PL.IsEqual(P,TolConf)) {
2213 found = Standard_True;
2218 Extrema_ExtPC Proj(P,C);
2219 if (Proj.IsDone() && Proj.NbExt() > 0) {
2220 Standard_Real Dist2,Dist2Min = Proj.SquareDistance(1);
2221 U = Proj.Point(1).Parameter();
2222 for (Standard_Integer i = 2; i <= Proj.NbExt(); i++) {
2223 Dist2 = Proj.SquareDistance(i);
2224 if (Dist2 < Dist2Min) {
2226 U = Proj.Point(i).Parameter();
2229 found = Standard_True;
2235 Standard_Real Dist = P.Distance(C.Value(U));
2236 if (Dist > TolConf) {
2237 cout << " ProjectVertexOnEdge :distance vertex edge :"<<Dist<<endl;
2239 if (U < f - Precision::Confusion() ||
2240 U > l + Precision::Confusion()) {
2241 cout << " ProjectVertexOnEdge : hors borne :"<<endl;
2242 cout << " f = "<<f<<" l ="<<l<< " U ="<<U<<endl;
2246 cout <<"BRepOffset_Tool::ProjectVertexOnEdge Parameter no found"<<endl;
2247 if (Abs(f) < Precision::Infinite() &&
2248 Abs(l) < Precision::Infinite()) {
2256 TopoDS_Shape aLocalShape = E.Oriented(TopAbs_FORWARD);
2257 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
2258 aLocalShape = V.Oriented(TopAbs_INTERNAL);
2259 // TopoDS_Edge EE = TopoDS::Edge(E.Oriented(TopAbs_FORWARD));
2260 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
2261 U,EE,BRep_Tool::Tolerance(E));
2267 //=======================================================================
2268 //function : Inter2d
2270 //=======================================================================
2272 void BRepOffset_Tool::Inter2d (const TopoDS_Face& F,
2273 const TopoDS_Edge& E1,
2274 const TopoDS_Edge& E2,
2275 TopTools_ListOfShape& LV,
2276 const Standard_Real TolConf)
2280 DBRep::Set("E1",E1);
2281 DBRep::Set("E2",E2);
2286 Standard_Real fl1[2],fl2[2];
2289 // Si l edge a ete etendu les pcurves ne sont pas forcement
2295 // Construction des curves 3d si elles n existent pas
2296 // utile pour coder correctement les parametres des vertex
2297 // d intersection sur les edges.
2298 //TopLoc_Location L;
2299 //Standard_Real f,l;
2300 //Handle(Geom_Curve) C3d1 = BRep_Tool::Curve(E1,L,f,l);
2301 //if (C3d1.IsNull()) {
2302 // BRepLib::BuildCurve3d(E1,BRep_Tool::Tolerance(E1));
2304 //Handle(Geom_Curve) C3d2 = BRep_Tool::Curve(E2,L,f,l);
2305 //if (C3d2.IsNull()) {
2306 // BRepLib::BuildCurve3d(E2,BRep_Tool::Tolerance(E2));
2309 Standard_Integer NbPC1 = 1, NbPC2 = 1;
2310 if (BRep_Tool::IsClosed(E1,F)) NbPC1++;
2311 if (BRep_Tool::IsClosed(E2,F)) NbPC2++;
2313 Handle(Geom_Surface) S = BRep_Tool::Surface(F);
2314 Handle(Geom2d_Curve) C1, C2;
2315 Standard_Boolean YaSol = Standard_False;
2316 Standard_Integer itry = 0;
2318 while (!YaSol && itry < 2) {
2319 for ( Standard_Integer i = 1; i <= NbPC1 ; i++) {
2320 TopoDS_Shape aLocalEdge = E1.Reversed();
2321 if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
2322 else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdge),
2324 // if (i == 1) C1 = BRep_Tool::CurveOnSurface(E1,F,fl1[0],fl1[1]);
2325 // else C1 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E1.Reversed()),
2326 // F,fl1[0],fl1[1]);
2327 for ( Standard_Integer j = 1; j <= NbPC2; j++ ) {
2328 TopoDS_Shape aLocalEdge = E2.Reversed();
2329 if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2330 else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalEdge),
2332 // if (j == 1) C2 = BRep_Tool::CurveOnSurface(E2,F,fl2[0],fl2[1]);
2333 // else C2 = BRep_Tool::CurveOnSurface(TopoDS::Edge(E2.Reversed()),
2334 // F,fl2[0],fl2[1]);
2336 if (C1.IsNull() || C2.IsNull()) {
2337 cout <<"Inter2d : Pas de pcurve"<<endl;
2339 DBRep::Set("E1",E1);
2340 DBRep::Set("E2",E2);
2346 Standard_Real U1 = 0.,U2 = 0.;
2349 fl1[0] = C1->FirstParameter(); fl1[1] = C1->LastParameter();
2350 fl2[0] = C2->FirstParameter(); fl2[1] = C2->LastParameter();
2352 Geom2dAdaptor_Curve AC1(C1,fl1[0],fl1[1]);
2353 Geom2dAdaptor_Curve AC2(C2,fl2[0],fl2[1]);
2356 gp_Pnt2d P1[2],P2[2];
2357 P1[0] = C1->Value(fl1[0]); P1[1] = C1->Value(fl1[1]);
2358 P2[0] = C2->Value(fl2[0]); P2[1] = C2->Value(fl2[1]);
2360 Standard_Integer i1 ;
2361 for ( i1 = 0; i1 < 2; i1++) {
2362 for (Standard_Integer i2 = 0; i2 < 2; i2++) {
2363 if (Abs(fl1[i1]) < Precision::Infinite() &&
2364 Abs(fl2[i2]) < Precision::Infinite() ) {
2365 if (P1[i1].IsEqual(P2[i2],TolConf)) {
2366 YaSol = Standard_True;
2367 U1 = fl1[i1]; U2 = fl2[i2];
2368 P2d = C1->Value(U1);
2374 for (i1 = 0; i1 < 2; i1++)
2376 Extrema_ExtPC2d extr( P1[i1], AC2 );
2377 if (extr.IsDone() && extr.NbExt() > 0)
2379 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2380 Standard_Integer IndexMin = 1;
2381 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2383 Dist2 = extr.SquareDistance(ind);
2384 if (Dist2 < Dist2Min)
2390 if (Dist2Min <= Precision::SquareConfusion())
2392 YaSol = Standard_True;
2395 U2 = (extr.Point(IndexMin)).Parameter();
2401 for (Standard_Integer i2 = 0; i2 < 2; i2++)
2403 Extrema_ExtPC2d extr( P2[i2], AC1 );
2404 if (extr.IsDone() && extr.NbExt() > 0)
2406 Standard_Real Dist2, Dist2Min = extr.SquareDistance(1);
2407 Standard_Integer IndexMin = 1;
2408 for (Standard_Integer ind = 2; ind <= extr.NbExt(); ind++)
2410 Dist2 = extr.SquareDistance(ind);
2411 if (Dist2 < Dist2Min)
2417 if (Dist2Min <= Precision::SquareConfusion())
2419 YaSol = Standard_True;
2422 U1 = (extr.Point(IndexMin)).Parameter();
2430 Geom2dInt_GInter Inter (AC1,AC2,TolConf,TolConf);
2432 if (!Inter.IsEmpty() && Inter.NbPoints() > 0) {
2433 YaSol = Standard_True;
2434 U1 = Inter.Point(1).ParamOnFirst();
2435 U2 = Inter.Point(1).ParamOnSecond();
2436 P2d = Inter.Point(1).Value();
2438 else if (!Inter.IsEmpty() && Inter.NbSegments() > 0) {
2439 YaSol = Standard_True;
2440 IntRes2d_IntersectionSegment Seg = Inter.Segment(1);
2441 IntRes2d_IntersectionPoint IntP1 = Seg.FirstPoint();
2442 IntRes2d_IntersectionPoint IntP2 = Seg.LastPoint();
2443 Standard_Real U1on1 = IntP1.ParamOnFirst();
2444 Standard_Real U1on2 = IntP2.ParamOnFirst();
2445 Standard_Real U2on1 = IntP1.ParamOnSecond();
2446 Standard_Real U2on2 = IntP2.ParamOnSecond();
2448 cout << " BRepOffset_Tool::Inter2d SEGMENT d intersection" << endl;
2449 cout << " ===> Parametres sur Curve1 : ";
2450 cout << U1on1 << " " << U1on2 << endl;
2451 cout << " ===> Parametres sur Curve2 : ";
2452 cout << U2on1 << " " << U2on2 << endl;
2454 U1 = (U1on1 + U1on2)/2.;
2455 U2 = (U2on1 + U2on2)/2.;
2456 gp_Pnt2d P2d1 = C1->Value(U1);
2457 gp_Pnt2d P2d2 = C2->Value(U2);
2458 P2d.SetX( (P2d1.X() + P2d2.X()) / 2.);
2459 P2d.SetY( (P2d1.Y() + P2d2.Y()) / 2.);
2463 gp_Pnt P = S->Value(P2d.X(),P2d.Y());
2464 TopoDS_Vertex V = BRepLib_MakeVertex(P);
2465 V.Orientation(TopAbs_INTERNAL);
2466 TopoDS_Shape aLocalEdge = E1.Oriented(TopAbs_FORWARD);
2467 B.UpdateVertex(V,U1,TopoDS::Edge(aLocalEdge),TolConf);
2468 aLocalEdge = E2.Oriented(TopAbs_FORWARD);
2469 B.UpdateVertex(V,U2,TopoDS::Edge(aLocalEdge),TolConf);
2470 // B.UpdateVertex(V,U1,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)),TolConf);
2471 // B.UpdateVertex(V,U2,TopoDS::Edge(E2.Oriented(TopAbs_FORWARD)),TolConf);
2479 if (LV.Extent() > 1) {
2480 //------------------------------------------------
2481 // garde seulement les vertex les plus proches du
2482 //debut et de la fin.
2483 //------------------------------------------------
2484 TopTools_ListIteratorOfListOfShape it(LV);
2485 TopoDS_Vertex VF,VL;
2486 Standard_Real UMin = Precision::Infinite();
2487 Standard_Real UMax = -Precision::Infinite();
2490 for ( ; it.More(); it.Next()) {
2491 TopoDS_Vertex CV = TopoDS::Vertex(it.Value());
2492 TopoDS_Shape aLocalEdge = E1.Oriented(TopAbs_FORWARD);
2493 U = BRep_Tool::Parameter(CV,TopoDS::Edge(aLocalEdge));
2494 // U = BRep_Tool::Parameter(CV,TopoDS::Edge(E1.Oriented(TopAbs_FORWARD)));
2502 LV.Clear();LV.Append(VF); LV.Append(VL);
2507 cout <<"Inter2d : Pas de solution"<<endl;
2509 DBRep::Set("E1",E1);
2510 DBRep::Set("E2",E2);
2517 //=======================================================================
2518 //function : SelectEdge
2520 //=======================================================================
2522 static void SelectEdge (const TopoDS_Face& /*F*/,
2523 const TopoDS_Face& /*EF*/,
2524 const TopoDS_Edge& E,
2525 TopTools_ListOfShape& LInt)
2527 //------------------------------------------------------------
2528 // detrompeur sur les intersections sur les faces periodiques
2529 //------------------------------------------------------------
2530 TopTools_ListIteratorOfListOfShape it(LInt);
2531 Standard_Real dU = 1.0e100;
2534 Standard_Real Fst, Lst, tmp;
2535 BRep_Tool::Range(E, Fst, Lst);
2536 BRepAdaptor_Curve Ad1(E);
2538 gp_Pnt PFirst = Ad1.Value( Fst );
2539 gp_Pnt PLast = Ad1.Value( Lst );
2541 //----------------------------------------------------------------------
2542 // Selection de l edge qui couvre le plus le domaine de l edge initiale.
2543 //----------------------------------------------------------------------
2544 for (; it.More(); it.Next()) {
2545 const TopoDS_Edge& EI = TopoDS::Edge(it.Value());
2547 BRep_Tool::Range(EI, Fst, Lst);
2548 BRepAdaptor_Curve Ad2(EI);
2549 gp_Pnt P1 = Ad2.Value(Fst);
2550 gp_Pnt P2 = Ad2.Value(Lst);
2552 tmp = P1.Distance(PFirst) + P2.Distance(PLast);
2564 //=======================================================================
2567 //=======================================================================
2569 static void MakeFace(const Handle(Geom_Surface)& S,
2570 const Standard_Real Um,
2571 const Standard_Real UM,
2572 const Standard_Real Vm,
2573 const Standard_Real VM,
2574 const Standard_Boolean isVminDegen,
2575 const Standard_Boolean isVmaxDegen,
2578 Standard_Real UMin = Um;
2579 Standard_Real UMax = UM;
2580 Standard_Real VMin = Vm;
2581 Standard_Real VMax = VM;
2582 Standard_Real epsilon = Precision::Confusion();
2584 Standard_Real umin,umax,vmin,vmax;
2585 S->Bounds(umin,umax,vmin,vmax);
2588 // compute infinite flags
2589 Standard_Boolean umininf = Precision::IsNegativeInfinite(UMin);
2590 Standard_Boolean umaxinf = Precision::IsPositiveInfinite(UMax);
2591 Standard_Boolean vmininf = Precision::IsNegativeInfinite(VMin);
2592 Standard_Boolean vmaxinf = Precision::IsPositiveInfinite(VMax);
2595 Standard_Boolean IsSuclosed = S->IsUClosed(), IsSvclosed = S->IsVClosed();
2596 if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface))
2598 Handle(Geom_Surface) BasisSurf = (*((Handle(Geom_OffsetSurface)*)&S))->BasisSurface();
2599 IsSuclosed = BasisSurf->IsUClosed();
2600 IsSvclosed = BasisSurf->IsVClosed();
2603 Standard_Boolean uclosed =
2605 Abs(UMin - umin) < epsilon &&
2606 Abs(UMax - umax) < epsilon;
2608 Standard_Boolean vclosed =
2610 Abs(VMin - vmin) < epsilon &&
2611 Abs(VMax - vmax) < epsilon;
2613 // degenerated flags (for cones)
2614 Standard_Boolean vmindegen = isVminDegen, vmaxdegen = isVmaxDegen;
2615 Handle(Geom_Surface) theSurf = S;
2616 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
2617 theSurf = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface();
2618 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
2620 Handle(Geom_ConicalSurface) ConicalS = *((Handle(Geom_ConicalSurface)*) &theSurf);
2621 gp_Cone theCone = ConicalS->Cone();
2622 gp_Pnt theApex = theCone.Apex();
2623 Standard_Real Uapex, Vapex;
2624 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
2625 if (Abs(VMin - Vapex) <= Precision::Confusion())
2626 vmindegen = Standard_True;
2627 if (Abs(VMax - Vapex) <= Precision::Confusion())
2628 vmaxdegen = Standard_True;
2633 Standard_Real tol = Precision::Confusion();
2635 TopoDS_Vertex V00,V10,V11,V01;
2638 if (!vmininf) B.MakeVertex(V00,S->Value(UMin,VMin),tol);
2639 if (!vmaxinf) B.MakeVertex(V01,S->Value(UMin,VMax),tol);
2642 if (!vmininf) B.MakeVertex(V10,S->Value(UMax,VMin),tol);
2643 if (!vmaxinf) B.MakeVertex(V11,S->Value(UMax,VMax),tol);
2662 Handle(Geom2d_Line) Lumin,Lumax,Lvmin,Lvmax;
2664 Lumin = new Geom2d_Line(gp_Pnt2d(UMin,0),gp_Dir2d(0,1));
2666 Lumax = new Geom2d_Line(gp_Pnt2d(UMax,0),gp_Dir2d(0,1));
2668 Lvmin = new Geom2d_Line(gp_Pnt2d(0,VMin),gp_Dir2d(1,0));
2670 Lvmax = new Geom2d_Line(gp_Pnt2d(0,VMax),gp_Dir2d(1,0));
2672 Handle(Geom_Curve) Cumin,Cumax,Cvmin,Cvmax;
2673 Standard_Real TolApex = 1.e-5;
2674 //Standard_Boolean hasiso = ! S->IsKind(STANDARD_TYPE(Geom_OffsetSurface));
2675 Standard_Boolean hasiso = S->IsKind(STANDARD_TYPE(Geom_ElementarySurface));
2678 Cumin = S->UIso(UMin);
2680 Cumax = S->UIso(UMax);
2683 Cvmin = S->VIso(VMin);
2684 if (BRepOffset_Tool::Gabarit( Cvmin ) <= TolApex)
2685 vmindegen = Standard_True;
2689 Cvmax = S->VIso(VMax);
2690 if (BRepOffset_Tool::Gabarit( Cvmax ) <= TolApex)
2691 vmaxdegen = Standard_True;
2696 B.MakeFace(F,S,tol);
2699 TopoDS_Edge eumin,eumax,evmin,evmax;
2703 B.MakeEdge(eumin,Cumin,tol);
2707 B.UpdateEdge(eumin,Lumax,Lumin,F,tol);
2709 B.UpdateEdge(eumin,Lumin,F,tol);
2711 V00.Orientation(TopAbs_FORWARD);
2715 V01.Orientation(TopAbs_REVERSED);
2718 B.Range(eumin,VMin,VMax);
2726 B.MakeEdge(eumax,Cumax,tol);
2729 B.UpdateEdge(eumax,Lumax,F,tol);
2731 V10.Orientation(TopAbs_FORWARD);
2735 V11.Orientation(TopAbs_REVERSED);
2738 B.Range(eumax,VMin,VMax);
2743 if (hasiso && !vmindegen)
2744 B.MakeEdge(evmin,Cvmin,tol);
2748 B.UpdateEdge(evmin,Lvmin,Lvmax,F,tol);
2750 B.UpdateEdge(evmin,Lvmin,F,tol);
2752 V00.Orientation(TopAbs_FORWARD);
2756 V10.Orientation(TopAbs_REVERSED);
2759 B.Range(evmin,UMin,UMax);
2761 B.Degenerated(evmin, Standard_True);
2768 if (hasiso && !vmaxdegen)
2769 B.MakeEdge(evmax,Cvmax,tol);
2772 B.UpdateEdge(evmax,Lvmax,F,tol);
2774 V01.Orientation(TopAbs_FORWARD);
2778 V11.Orientation(TopAbs_REVERSED);
2781 B.Range(evmax,UMin,UMax);
2783 B.Degenerated(evmax, Standard_True);
2787 // make the wires and add them to the face
2788 eumin.Orientation(TopAbs_REVERSED);
2789 evmax.Orientation(TopAbs_REVERSED);
2793 if (!umininf && !umaxinf && vmininf && vmaxinf) {
2804 else if (umininf && umaxinf && !vmininf && !vmaxinf) {
2815 else if (!umininf || !umaxinf || !vmininf || !vmaxinf) {
2818 if (!umininf) B.Add(W,eumin);
2819 if (!vmininf) B.Add(W,evmin);
2820 if (!umaxinf) B.Add(W,eumax);
2821 if (!vmaxinf) B.Add(W,evmax);
2823 W.Closed(!umininf && !umaxinf && !vmininf && !vmaxinf);
2824 F.Closed(uclosed && vclosed);
2828 //=======================================================================
2829 //function : EnLargeGeometry
2831 //=======================================================================
2833 static Standard_Boolean EnlargeGeometry(Handle(Geom_Surface)& S,
2838 Standard_Boolean& IsV1degen,
2839 Standard_Boolean& IsV2degen,
2840 const Standard_Real uf1,
2841 const Standard_Real uf2,
2842 const Standard_Real vf1,
2843 const Standard_Real vf2,
2844 const Standard_Boolean GlobalEnlargeU,
2845 const Standard_Boolean GlobalEnlargeVfirst,
2846 const Standard_Boolean GlobalEnlargeVlast)
2848 const Standard_Real coeff = 4.;
2849 const Standard_Real TolApex = 1.e-5;
2851 Standard_Boolean SurfaceChange = Standard_False;
2852 if ( S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
2853 Handle(Geom_Surface) BS = (*((Handle(Geom_RectangularTrimmedSurface)*)&S))->BasisSurface();
2854 EnlargeGeometry(BS,U1,U2,V1,V2,IsV1degen,IsV2degen,
2855 uf1,uf2,vf1,vf2,GlobalEnlargeU,GlobalEnlargeVfirst,GlobalEnlargeVlast);
2856 if (!GlobalEnlargeVfirst)
2858 if (!GlobalEnlargeVlast)
2860 if (!GlobalEnlargeVfirst || !GlobalEnlargeVlast)
2861 //(*((Handle(Geom_RectangularTrimmedSurface)*)&S))->SetTrim( U1, U2, V1, V2 );
2862 S = new Geom_RectangularTrimmedSurface( BS, U1, U2, V1, V2 );
2865 SurfaceChange = Standard_True;
2867 else if (S->DynamicType() == STANDARD_TYPE(Geom_OffsetSurface)) {
2868 Handle(Geom_Surface) Surf = (*((Handle(Geom_OffsetSurface)*)&S))->BasisSurface();
2869 SurfaceChange = EnlargeGeometry(Surf,U1,U2,V1,V2,IsV1degen,IsV2degen,
2870 uf1,uf2,vf1,vf2,GlobalEnlargeU,GlobalEnlargeVfirst,GlobalEnlargeVlast);
2871 Handle(Geom_OffsetSurface)::DownCast(S)->SetBasisSurface(Surf);
2873 else if (S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
2874 S->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution))
2876 Standard_Real du=0., dv=0.;
2877 Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
2878 Standard_Real u1, u2, v1, v2;
2879 Standard_Boolean enlargeU = GlobalEnlargeU, enlargeV = Standard_True;
2880 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2881 Standard_Boolean enlargeVfirst = GlobalEnlargeVfirst, enlargeVlast = GlobalEnlargeVlast;
2882 S->Bounds( u1, u2, v1, v2 );
2883 if (Precision::IsInfinite(u1) || Precision::IsInfinite(u2))
2888 enlargeU = Standard_False;
2890 else if (S->IsUClosed())
2891 enlargeU = Standard_False;
2894 viso = S->VIso( vf1 );
2895 GeomAdaptor_Curve gac( viso );
2896 du = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2897 uiso1 = S->UIso( uf1 );
2898 uiso2 = S->UIso( uf2 );
2899 if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
2900 enlargeUfirst = Standard_False;
2901 if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
2902 enlargeUlast = Standard_False;
2904 if (Precision::IsInfinite(v1) || Precision::IsInfinite(v2))
2909 enlargeV = Standard_False;
2911 else if (S->IsVClosed())
2912 enlargeV = Standard_False;
2915 uiso = S->UIso( uf1 );
2916 GeomAdaptor_Curve gac( uiso );
2917 dv = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2918 viso1 = S->VIso( vf1 );
2919 viso2 = S->VIso( vf2 );
2920 if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
2922 enlargeVfirst = Standard_False;
2923 IsV1degen = Standard_True;
2925 if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
2927 enlargeVlast = Standard_False;
2928 IsV2degen = Standard_True;
2931 S = new Geom_RectangularTrimmedSurface( S, u1, u2, v1, v2 );
2935 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), du, 1, Standard_True, Standard_False );
2937 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), du, 1, Standard_True, Standard_True );
2942 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), dv, 1, Standard_False, Standard_False );
2944 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), dv, 1, Standard_False, Standard_True );
2946 S->Bounds( U1, U2, V1, V2 );
2947 SurfaceChange = Standard_True;
2949 else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
2950 S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
2952 Standard_Boolean enlargeU = GlobalEnlargeU, enlargeV = Standard_True;
2953 Standard_Boolean enlargeUfirst = enlargeU, enlargeUlast = enlargeU;
2954 Standard_Boolean enlargeVfirst = GlobalEnlargeVfirst, enlargeVlast = GlobalEnlargeVlast;
2956 enlargeU = Standard_False;
2958 enlargeV = Standard_False;
2960 Standard_Real duf = uf2-uf1, dvf = vf2-vf1;
2961 Standard_Real u1, u2, v1, v2;
2962 S->Bounds( u1, u2, v1, v2 );
2964 Standard_Real du=0., dv=0.;
2965 Handle( Geom_Curve ) uiso, viso, uiso1, uiso2, viso1, viso2;
2966 GeomAdaptor_Curve gac;
2969 viso = S->VIso( v1 );
2971 du = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2972 uiso1 = S->UIso( u1 );
2973 uiso2 = S->UIso( u2 );
2974 if (BRepOffset_Tool::Gabarit( uiso1 ) <= TolApex)
2975 enlargeUfirst = Standard_False;
2976 if (BRepOffset_Tool::Gabarit( uiso2 ) <= TolApex)
2977 enlargeUlast = Standard_False;
2981 uiso = S->UIso( u1 );
2983 dv = GCPnts_AbscissaPoint::Length( gac ) / coeff;
2984 viso1 = S->VIso( v1 );
2985 viso2 = S->VIso( v2 );
2986 if (BRepOffset_Tool::Gabarit( viso1 ) <= TolApex)
2988 enlargeVfirst = Standard_False;
2989 IsV1degen = Standard_True;
2991 if (BRepOffset_Tool::Gabarit( viso2 ) <= TolApex)
2993 enlargeVlast = Standard_False;
2994 IsV2degen = Standard_True;
3000 if (enlargeUfirst && uf1-u1 < duf)
3001 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), du, 1, Standard_True, Standard_False );
3002 if (enlargeUlast && u2-uf2 < duf)
3003 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), du, 1, Standard_True, Standard_True );
3007 if (enlargeVfirst && vf1-v1 < dvf)
3008 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), dv, 1, Standard_False, Standard_False );
3009 if (enlargeVlast && v2-vf2 < dvf)
3010 GeomLib::ExtendSurfByLength( *((Handle(Geom_BoundedSurface)*)&S), dv, 1, Standard_False, Standard_True );
3013 S->Bounds( U1, U2, V1, V2 );
3014 SurfaceChange = Standard_True;
3016 // else if (S->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
3017 // S->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface)) {
3018 // S->Bounds(U1,U2,V1,V2);
3021 Standard_Real UU1,UU2,VV1,VV2;
3022 S->Bounds(UU1,UU2,VV1,VV2);
3023 // Pas d extension au dela des bornes de la surface.
3029 return SurfaceChange;
3032 //=======================================================================
3033 //function : UpDatePCurve
3034 //purpose : Mise a jour des pcurves de F sur la surface de de BF.
3035 // F and BF has to be FORWARD,
3036 //=======================================================================
3038 static void UpdatePCurves (const TopoDS_Face& F,
3044 TopTools_IndexedMapOfShape Emap;
3045 Handle(Geom2d_Curve) NullPCurve;
3047 TopExp::MapShapes( F, TopAbs_EDGE, Emap );
3049 for (i = 1; i <= Emap.Extent(); i++)
3051 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
3052 CE.Orientation( TopAbs_FORWARD );
3053 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface( CE, F, f, l );
3056 if (BRep_Tool::IsClosed( CE, F ))
3059 Handle(Geom2d_Curve) C2R = BRep_Tool::CurveOnSurface( CE, F, f, l );
3060 B.UpdateEdge( CE, NullPCurve, NullPCurve, F, BRep_Tool::Tolerance(CE) );
3061 B.UpdateEdge( CE, C2, C2R, BF, BRep_Tool::Tolerance(CE) );
3065 B.UpdateEdge( CE, NullPCurve, F, BRep_Tool::Tolerance(CE) );
3066 B.UpdateEdge( CE, C2, BF, BRep_Tool::Tolerance(CE) );
3074 //=======================================================================
3075 //function :CompactUVBounds
3077 //=======================================================================
3079 static void CompactUVBounds (const TopoDS_Face& F,
3080 Standard_Real& UMin,
3081 Standard_Real& UMax,
3082 Standard_Real& VMin,
3083 Standard_Real& VMax)
3085 // Calcul serre pour que les bornes ne couvrent pas plus d une periode
3086 Standard_Real U1,U2;
3087 Standard_Real N = 33;
3090 TopExp_Explorer exp;
3091 for (exp.Init(F, TopAbs_EDGE); exp.More(); exp.Next()) {
3092 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3093 BRepAdaptor_Curve2d C(E,F);
3094 BRep_Tool::Range(E,U1,U2);
3096 Standard_Real U = U1;
3097 Standard_Real DU = (U2-U1)/(N-1);
3098 for (Standard_Integer j=1;j<N;j++) {
3106 B.Get(UMin,VMin,UMax,VMax);
3109 //=======================================================================
3110 //function : CheckBounds
3112 //=======================================================================
3114 void BRepOffset_Tool::CheckBounds(const TopoDS_Face& F,
3115 const BRepOffset_Analyse& Analyse,
3116 Standard_Boolean& enlargeU,
3117 Standard_Boolean& enlargeVfirst,
3118 Standard_Boolean& enlargeVlast)
3120 enlargeU = Standard_True;
3121 enlargeVfirst = Standard_True; enlargeVlast = Standard_True;
3123 Standard_Integer Ubound = 0, Vbound = 0;
3124 Standard_Real Ufirst = RealLast(), Ulast = RealFirst();
3125 Standard_Real Vfirst = RealLast(), Vlast = RealFirst();
3127 Standard_Real UF1,UF2,VF1,VF2;
3128 CompactUVBounds(F,UF1,UF2,VF1,VF2);
3130 Handle(Geom_Surface) theSurf = BRep_Tool::Surface(F);
3131 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
3132 theSurf = (*((Handle(Geom_RectangularTrimmedSurface)*)&theSurf))->BasisSurface();
3134 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion) ||
3135 theSurf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfRevolution) ||
3136 theSurf->DynamicType() == STANDARD_TYPE(Geom_BezierSurface) ||
3137 theSurf->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface))
3139 TopExp_Explorer Explo(F, TopAbs_EDGE);
3140 for (; Explo.More(); Explo.Next())
3142 const TopoDS_Edge& anEdge = TopoDS::Edge(Explo.Current());
3143 const BRepOffset_ListOfInterval& L = Analyse.Type(anEdge);
3144 if (!L.IsEmpty() || BRep_Tool::Degenerated(anEdge))
3146 BRepOffset_Type OT = L.First().Type();
3147 if (OT == BRepOffset_Tangent || BRep_Tool::Degenerated(anEdge))
3149 Standard_Real fpar, lpar;
3150 Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, F, fpar, lpar);
3151 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
3152 aCurve = (*((Handle(Geom2d_TrimmedCurve)*)&aCurve))->BasisCurve();
3154 Handle(Geom2d_Line) theLine;
3155 if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_Line))
3156 theLine = *((Handle(Geom2d_Line)*)&aCurve);
3157 else if (aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BezierCurve) ||
3158 aCurve->DynamicType() == STANDARD_TYPE(Geom2d_BSplineCurve))
3160 Standard_Real newFpar, newLpar, deviation;
3161 theLine = ShapeCustom_Curve2d::ConvertToLine2d(aCurve, fpar, lpar, Precision::Confusion(),
3162 newFpar, newLpar, deviation);
3165 if (!theLine.IsNull())
3167 gp_Dir2d theDir = theLine->Direction();
3168 if (theDir.IsParallel( gp::DX2d(), Precision::Angular() ))
3171 if (BRep_Tool::Degenerated(anEdge))
3173 if (Abs(theLine->Location().Y() - VF1) <= Precision::Confusion())
3174 enlargeVfirst = Standard_False;
3175 else //theLine->Location().Y() is near VF2
3176 enlargeVlast = Standard_False;
3180 if (theLine->Location().Y() < Vfirst)
3181 Vfirst = theLine->Location().Y();
3182 if (theLine->Location().Y() > Vlast)
3183 Vlast = theLine->Location().Y();
3186 else if (theDir.IsParallel( gp::DY2d(), Precision::Angular() ))
3189 if (theLine->Location().X() < Ufirst)
3190 Ufirst = theLine->Location().X();
3191 if (theLine->Location().X() > Ulast)
3192 Ulast = theLine->Location().X();
3200 if (Ubound >= 2 || Vbound >= 2)
3203 Abs(UF1-Ufirst) <= Precision::Confusion() &&
3204 Abs(UF2-Ulast) <= Precision::Confusion())
3205 enlargeU = Standard_False;
3207 Abs(VF1-Vfirst) <= Precision::Confusion() &&
3208 Abs(VF2-Vlast) <= Precision::Confusion())
3210 enlargeVfirst = Standard_False;
3211 enlargeVlast = Standard_False;
3216 //=======================================================================
3217 //function : EnLargeFace
3219 //=======================================================================
3221 Standard_Boolean BRepOffset_Tool::EnLargeFace
3222 (const TopoDS_Face& F,
3224 const Standard_Boolean CanExtentSurface,
3225 const Standard_Boolean UpdatePCurve,
3226 const Standard_Boolean enlargeU,
3227 const Standard_Boolean enlargeVfirst,
3228 const Standard_Boolean enlargeVlast)
3230 //---------------------------
3231 // extension de la geometrie.
3232 //---------------------------
3234 Handle (Geom_Surface) S = BRep_Tool::Surface(F,L);
3235 Standard_Real UU1,VV1,UU2,VV2;
3236 Standard_Boolean isVV1degen = Standard_False, isVV2degen = Standard_False;
3237 Standard_Real US1,VS1,US2,VS2;
3238 Standard_Real UF1,VF1,UF2,VF2;
3239 Standard_Real infini = 1.e8;
3240 Standard_Boolean SurfaceChange = Standard_False;
3242 if (S->IsUPeriodic() || S->IsVPeriodic()) {
3243 // Calcul serre pour que les bornes ne couvre pas plus d une periode
3244 CompactUVBounds(F,UF1,UF2,VF1,VF2);
3247 BRepTools::UVBounds(F,UF1,UF2,VF1,VF2);
3250 S->Bounds (US1,US2,VS1,VS2);
3251 UU1 = VV1 = - infini;
3254 if (CanExtentSurface) {
3255 SurfaceChange = EnlargeGeometry( S, UU1, UU2, VV1, VV2, isVV1degen, isVV2degen, UF1, UF2, VF1, VF2,
3256 enlargeU, enlargeVfirst, enlargeVlast );
3259 UU1 = Max(US1,UU1); UU2 = Min(UU2,US2);
3260 VV1 = Max(VS1,VV1); VV2 = Min(VS2,VV2);
3263 if (S->IsUPeriodic()) {
3264 Standard_Real Period = S->UPeriod();
3265 Standard_Real Delta = Period - (UF2 - UF1);
3266 Standard_Real alpha = 0.1;
3267 UU1 = UF1 - alpha*Delta; UU2 = UF2 + alpha*Delta;
3268 if ((UU2 - UU1) > Period) {
3272 if (S->IsVPeriodic()) {
3273 Standard_Real Period = S->VPeriod();
3274 Standard_Real Delta = Period - (VF2 - VF1);
3275 Standard_Real alpha = 0.1;
3276 VV1 = VF1 - alpha*Delta; VV2 = VF2 + alpha*Delta;
3277 if ((VV2 - VV1) > Period) {
3282 //Special treatment for conical surfaces
3283 Handle(Geom_Surface) theSurf = S;
3284 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface))
3285 theSurf = (*(Handle_Geom_RectangularTrimmedSurface*)&S)->BasisSurface();
3286 if (theSurf->DynamicType() == STANDARD_TYPE(Geom_ConicalSurface))
3288 Handle(Geom_ConicalSurface) ConicalS = *((Handle(Geom_ConicalSurface)*) &theSurf);
3289 gp_Cone theCone = ConicalS->Cone();
3290 gp_Pnt theApex = theCone.Apex();
3291 Standard_Real Uapex, Vapex;
3292 ElSLib::Parameters( theCone, theApex, Uapex, Vapex );
3293 if (VV1 < Vapex && Vapex < VV2)
3295 //consider that VF1 and VF2 are on the same side from apex
3296 Standard_Real TolApex = 1.e-5;
3297 if (Vapex - VF1 >= TolApex ||
3298 Vapex - VF2 >= TolApex) //if (VF1 < Vapex || VF2 < Vapex)
3307 UU1 = UF1; UU2 = UF2;
3314 MakeFace(S,UU1,UU2,VV1,VV2,isVV1degen,isVV2degen,BF);
3317 if (S->DynamicType() == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
3319 //----------------------------------------------------------------
3320 // utile pour les bouchons on ne doit pas changer leur geometrie.
3321 // (Ce que fait BRepLib_MakeFace si S est restreinte).
3322 // On remet S et on update les pcurves.
3323 //----------------------------------------------------------------
3324 TopExp_Explorer exp;
3325 exp.Init(BF,TopAbs_EDGE);
3326 Standard_Real f=0.,l=0.;
3327 for (; exp.More(); exp.Next()) {
3328 TopoDS_Edge CE = TopoDS::Edge(exp.Current());
3329 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,BF,f,l);
3330 B.UpdateEdge (CE,C2,S,L,BRep_Tool::Tolerance(CE));
3332 B.UpdateFace(BF,S,L,BRep_Tool::Tolerance(F));
3335 if (SurfaceChange && UpdatePCurve) {
3336 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3337 UpdatePCurves(TopoDS::Face(aLocalFace),BF);
3338 //UpdatePCurves(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),BF);
3340 BB.UpdateFace( F, S, L, BRep_Tool::Tolerance(F) );
3343 BF.Orientation(F.Orientation());
3344 return SurfaceChange;
3347 //=======================================================================
3348 //function : TryParameter
3350 //=======================================================================
3352 static Standard_Boolean TryParameter (const TopoDS_Edge& OE,
3354 const TopoDS_Edge& NE,
3355 Standard_Real TolConf)
3357 BRepAdaptor_Curve OC(OE);
3358 BRepAdaptor_Curve NC(NE);
3359 Standard_Real Of = OC.FirstParameter(); Standard_Real Ol = OC.LastParameter();
3360 Standard_Real Nf = NC.FirstParameter(); Standard_Real Nl = NC.LastParameter();
3361 Standard_Real U = 0.;
3362 gp_Pnt P = BRep_Tool::Pnt(V);
3363 Standard_Boolean OK = Standard_False;
3365 if (P.Distance(OC.Value(Of)) < TolConf) {
3366 if (Of > Nf && Of < Nl && P.Distance(NC.Value(Of)) < TolConf) {
3371 if (P.Distance(OC.Value(Ol)) < TolConf) {
3372 if (Ol > Nf && Ol < Nl && P.Distance(NC.Value(Ol)) < TolConf) {
3379 TopoDS_Shape aLocalShape = NE.Oriented(TopAbs_FORWARD);
3380 TopoDS_Edge EE = TopoDS::Edge(aLocalShape);
3381 // TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD));
3382 aLocalShape = V.Oriented(TopAbs_INTERNAL);
3383 B.UpdateVertex(TopoDS::Vertex(aLocalShape),
3384 U,NE,BRep_Tool::Tolerance(NE));
3385 // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)),
3386 // U,NE,BRep_Tool::Tolerance(NE));
3391 //=======================================================================
3394 //=======================================================================
3396 void BRepOffset_Tool::MapVertexEdges (const TopoDS_Shape& S,
3397 TopTools_DataMapOfShapeListOfShape& MEV)
3399 TopExp_Explorer exp;
3400 exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3401 TopTools_MapOfShape DejaVu;
3402 for ( ; exp.More(); exp.Next()) {
3403 const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
3404 if (DejaVu.Add(E)) {
3405 TopoDS_Vertex V1,V2;
3406 TopExp::Vertices (E,V1,V2);
3407 if (!MEV.IsBound(V1)) {
3408 TopTools_ListOfShape empty;
3412 if (!V1.IsSame(V2)) {
3413 if (!MEV.IsBound(V2)) {
3414 TopTools_ListOfShape empty;
3423 //=======================================================================
3426 //=======================================================================
3428 void BRepOffset_Tool::BuildNeighbour (const TopoDS_Wire& W,
3429 const TopoDS_Face& F,
3430 TopTools_DataMapOfShapeShape& NOnV1,
3431 TopTools_DataMapOfShapeShape& NOnV2)
3433 TopoDS_Vertex V1,V2,VP1,VP2,FV1,FV2;
3434 TopoDS_Edge CurE,FirstE,PrecE;
3435 BRepTools_WireExplorer wexp;
3437 TopoDS_Shape aLocalFace = F.Oriented(TopAbs_FORWARD);
3438 TopoDS_Shape aLocalWire = W.Oriented(TopAbs_FORWARD);
3439 wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace));
3440 // wexp.Init(TopoDS::Wire(W.Oriented(TopAbs_FORWARD)),
3441 // TopoDS::Face(F.Oriented(TopAbs_FORWARD)));
3442 CurE = FirstE = PrecE = wexp.Current();
3443 TopExp::Vertices(CurE,V1,V2);
3444 FV1 = VP1 = V1; FV2 = VP2 = V2;
3446 while (wexp.More()) {
3447 CurE = wexp.Current();
3448 TopExp::Vertices(CurE,V1,V2);
3449 if (V1.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3450 if (V1.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV1.Bind(CurE,PrecE);}
3451 if (V2.IsSame(VP1)) { NOnV1.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3452 if (V2.IsSame(VP2)) { NOnV2.Bind(PrecE,CurE); NOnV2.Bind(CurE,PrecE);}
3457 if (V1.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3458 if (V1.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV1.Bind(CurE,FirstE);}
3459 if (V2.IsSame(FV1)) { NOnV1.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3460 if (V2.IsSame(FV2)) { NOnV2.Bind(FirstE,CurE); NOnV2.Bind(CurE,FirstE);}
3463 //=======================================================================
3464 //function : ExtentFace
3466 //=======================================================================
3468 void BRepOffset_Tool::ExtentFace (const TopoDS_Face& F,
3469 TopTools_DataMapOfShapeShape& ConstShapes,
3470 TopTools_DataMapOfShapeShape& ToBuild,
3471 const TopAbs_State Side,
3472 const Standard_Real TolConf,
3478 char* name = new char[100];
3479 sprintf(name,"FTE_%d",NbFTE++);
3484 TopExp_Explorer exp,exp2;
3485 TopTools_DataMapOfShapeShape Build;
3486 TopTools_DataMapOfShapeShape Extent;
3487 TopoDS_Edge FirstE,PrecE,CurE,NE;
3491 // Construction de la boite englobante de la face a etendre et des bouchons pour
3492 // limiter les extensions.
3493 //Bnd_Box ContextBox;
3494 //BRepBndLib::Add(F,B);
3495 //TopTools_DataMapIteratorOfDataMapOfShape itTB(ToBuild);
3496 //for (; itTB.More(); itTB.Next()) {
3497 //BRepBndLib::Add(TopBuild.Value(), ContextBox);
3501 Standard_Boolean SurfaceChange;
3502 SurfaceChange = EnLargeFace (F,EF,Standard_True);
3504 TopoDS_Shape aLocalShape = EF.EmptyCopied();
3505 NF = TopoDS::Face(aLocalShape);
3506 // NF = TopoDS::Face(EF.EmptyCopied());
3507 NF.Orientation(TopAbs_FORWARD);
3509 if (SurfaceChange) {
3510 //------------------------------------------------
3511 // Mise a jour des pcurves sur la surface de base.
3512 //------------------------------------------------
3513 TopoDS_Face Fforward = F;
3514 Fforward.Orientation(TopAbs_FORWARD);
3515 TopTools_IndexedMapOfShape Emap;
3516 TopExp::MapShapes( Fforward, TopAbs_EDGE, Emap );
3518 for (Standard_Integer i = 1; i <= Emap.Extent(); i++) {
3519 TopoDS_Edge CE = TopoDS::Edge( Emap(i) );
3520 CE.Orientation(TopAbs_FORWARD);
3521 TopoDS_Edge Ecs; //patch
3522 Handle(Geom2d_Curve) C2 = BRep_Tool::CurveOnSurface(CE,Fforward,f,l);
3524 if (ConstShapes.IsBound(CE)) {
3525 Ecs = TopoDS::Edge(ConstShapes(CE));
3526 BRep_Tool::Range(Ecs,f,l);
3528 if (BRep_Tool::IsClosed(CE,Fforward)) {
3529 TopoDS_Shape aLocalShape = CE.Reversed();
3530 Handle(Geom2d_Curve) C2R =
3531 BRep_Tool::CurveOnSurface(TopoDS::Edge(aLocalShape),Fforward,f,l);
3532 // Handle(Geom2d_Curve) C2R =
3533 // BRep_Tool::CurveOnSurface(TopoDS::Edge(CE.Reversed()),F,f,l);
3534 B.UpdateEdge (CE,C2,C2R,EF,BRep_Tool::Tolerance(CE));
3536 B.UpdateEdge (Ecs,C2,C2R,EF,BRep_Tool::Tolerance(CE));
3539 B.UpdateEdge (CE,C2,EF,BRep_Tool::Tolerance(CE));
3541 B.UpdateEdge (Ecs,C2,EF,BRep_Tool::Tolerance(CE));
3550 for (exp.Init(F.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
3553 const TopoDS_Wire& W = TopoDS::Wire(exp.Current());
3554 TopTools_DataMapOfShapeListOfShape MVE; // Vertex -> Edges incidentes.
3555 TopTools_DataMapOfShapeShape NOnV1;
3556 TopTools_DataMapOfShapeShape NOnV2;
3558 MapVertexEdges (W,MVE);
3559 BuildNeighbour (W,F,NOnV1,NOnV2);
3561 TopTools_ListOfShape LInt1,LInt2;
3562 TopoDS_Face StopFace;
3563 //------------------------------------------------
3564 // Construction edges
3565 //------------------------------------------------
3566 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3567 exp2.More(); exp2.Next()) {
3568 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3569 if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
3570 if (ToBuild.IsBound(E)) {
3571 TopTools_ListOfShape LOE;
3573 BRepOffset_Tool::TryProject (TopoDS::Face(ToBuild(E)),
3574 EF,LOE,LInt2,LInt1,Side,TolConf);
3575 if (!LInt1.IsEmpty())
3580 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3581 exp2.More(); exp2.Next()) {
3582 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3583 if (ConstShapes.IsBound(E)) ToBuild.UnBind(E);
3584 if (ToBuild.IsBound(E)) {
3585 EnLargeFace(TopoDS::Face(ToBuild(E)),StopFace,Standard_False);
3586 BRepOffset_Tool::Inter3D (EF,StopFace,LInt1,LInt2,Side,E,Standard_True);
3587 // No intersection, it may happen for example for a chosen (non-offseted) planar face and
3588 // its neighbour offseted cylindrical face, if the offset is directed so that
3589 // the radius of the cylinder becomes smaller.
3590 if (LInt1.IsEmpty())
3592 if (LInt1.Extent() > 1) {
3593 // l intersection est en plusieurs edges (franchissement de couture)
3594 SelectEdge (F,EF,E,LInt1);
3596 NE = TopoDS::Edge(LInt1.First());
3597 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &NE.TShape());
3598 TE->Tolerance( TE->Tolerance()*10. ); //????
3599 if (NE.Orientation() == E.Orientation()) {
3600 Build.Bind(E,NE.Oriented(TopAbs_FORWARD));
3603 Build.Bind(E,NE.Oriented(TopAbs_REVERSED));
3605 const TopoDS_Edge& EOnV1 = TopoDS::Edge(NOnV1(E));
3606 if (!ToBuild .IsBound(EOnV1) &&
3607 !ConstShapes.IsBound(EOnV1) &&
3608 !Build .IsBound(EOnV1)) {
3609 ExtentEdge (F,EF,EOnV1,NE);
3610 Build.Bind (EOnV1,NE.Oriented(TopAbs_FORWARD));
3612 const TopoDS_Edge& EOnV2 = TopoDS::Edge(NOnV2(E));
3613 if (!ToBuild .IsBound(EOnV2) &&
3614 !ConstShapes.IsBound(EOnV2) &&
3615 !Build .IsBound(EOnV2)) {
3616 ExtentEdge (F,EF,EOnV2,NE);
3617 Build.Bind (EOnV2,NE.Oriented (TopAbs_FORWARD));
3622 //------------------------------------------------
3623 // Construction Vertex.
3624 //------------------------------------------------
3625 TopTools_ListOfShape LV;
3628 TopoDS_Vertex V1,V2;
3630 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3631 exp2.More(); exp2.Next()) {
3632 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3633 TopExp::Vertices (E,V1,V2);
3634 BRep_Tool::Range (E,f,l);
3636 if (Build.IsBound(E)) {
3637 const TopoDS_Edge& NEOnV1 = TopoDS::Edge(NOnV1(E));
3638 if (Build.IsBound(NEOnV1) &&
3639 (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV1))) {
3640 if (E.IsSame(NEOnV1))
3641 V = TopExp::FirstVertex(TopoDS::Edge(Build(E)));
3646 if (!Build.IsBound(V1)) {
3647 Inter2d (EF,TopoDS::Edge(Build(E)),
3648 TopoDS::Edge(Build(NEOnV1)),LV,/*TolConf*/Precision::Confusion());
3649 if (Build(E).Orientation() == TopAbs_FORWARD) {
3650 V = TopoDS::Vertex(LV.First());
3653 V = TopoDS::Vertex(LV.Last());
3657 V = TopoDS::Vertex(Build(V1));
3658 if (MVE (V1).Extent() > 2) {
3659 V.Orientation(TopAbs_FORWARD);
3660 if (Build(E).Orientation() == TopAbs_REVERSED)
3661 V.Orientation(TopAbs_REVERSED);
3662 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3672 if (ConstShapes.IsBound(V1)) V = TopoDS::Vertex(ConstShapes(V1));
3673 V.Orientation(TopAbs_FORWARD);
3674 if (Build(E).Orientation() == TopAbs_REVERSED)
3675 V.Orientation(TopAbs_REVERSED);
3676 if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
3677 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3679 ConstShapes.Bind(V1,V);
3681 const TopoDS_Edge& NEOnV2 = TopoDS::Edge(NOnV2(E));
3682 if (Build.IsBound(NEOnV2) &&
3683 (ToBuild.IsBound(E) || ToBuild.IsBound(NEOnV2))) {
3684 if (E.IsSame(NEOnV2))
3685 V = TopExp::LastVertex(TopoDS::Edge(Build(E)));
3690 if (!Build.IsBound(V2)) {
3691 Inter2d (EF,TopoDS::Edge(Build(E)),
3692 TopoDS::Edge(Build(NEOnV2)),LV,/*TolConf*/Precision::Confusion());
3693 if (Build(E).Orientation() == TopAbs_FORWARD) {
3694 V = TopoDS::Vertex(LV.Last());
3697 V = TopoDS::Vertex(LV.First());
3701 V = TopoDS::Vertex(Build(V2));
3702 if (MVE (V2).Extent() > 2) {
3703 V.Orientation(TopAbs_REVERSED);
3704 if (Build(E).Orientation() == TopAbs_REVERSED)
3705 V.Orientation(TopAbs_FORWARD);
3706 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3716 if (ConstShapes.IsBound(V2)) V = TopoDS::Vertex(ConstShapes(V2));
3717 V.Orientation(TopAbs_REVERSED);
3718 if (Build(E).Orientation() == TopAbs_REVERSED)
3719 V.Orientation(TopAbs_FORWARD);
3720 if (!TryParameter (E,V,TopoDS::Edge(Build(E)),TolConf))
3721 ProjectVertexOnEdge(V,TopoDS::Edge(Build(E)),TolConf);
3723 ConstShapes.Bind(V2,V);
3729 TopoDS_Vertex NV1,NV2;
3730 TopAbs_Orientation Or;
3731 Standard_Real U1,U2;
3732 Standard_Real eps = Precision::Confusion();
3742 for (exp2.Init(W.Oriented(TopAbs_FORWARD),TopAbs_EDGE);
3743 exp2.More(); exp2.Next()) {
3744 const TopoDS_Edge& E = TopoDS::Edge(exp2.Current());
3745 TopExp::Vertices (E,V1,V2);
3746 if (Build.IsBound(E)) {
3747 NE = TopoDS::Edge(Build(E));
3748 BRep_Tool::Range(NE,f,l);
3749 Or = NE.Orientation();
3750 //-----------------------------------------------------
3751 // Copy pour virer les vertex deja sur la nouvelle edge.
3752 //-----------------------------------------------------
3753 NV1 = TopoDS::Vertex(ConstShapes(V1));
3754 NV2 = TopoDS::Vertex(ConstShapes(V2));
3756 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_INTERNAL);
3757 TopoDS_Shape aLocalEdge = NE.Oriented(TopAbs_INTERNAL);
3759 U1 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalVertex),
3760 TopoDS::Edge (aLocalEdge));
3761 aLocalVertex = NV2.Oriented(TopAbs_INTERNAL);
3762 aLocalEdge = NE.Oriented(TopAbs_FORWARD);
3763 U2 = BRep_Tool::Parameter
3764 (TopoDS::Vertex(aLocalVertex),TopoDS::Edge (aLocalEdge));
3765 // U1 = BRep_Tool::Parameter
3766 // (TopoDS::Vertex(NV1.Oriented(TopAbs_INTERNAL)),
3767 // TopoDS::Edge (NE .Oriented(TopAbs_FORWARD)));
3768 // U2 = BRep_Tool::Parameter
3769 // (TopoDS::Vertex(NV2.Oriented(TopAbs_INTERNAL)),
3770 // TopoDS::Edge (NE.Oriented(TopAbs_FORWARD)));
3771 aLocalEdge = NE.EmptyCopied();
3772 NE = TopoDS::Edge(aLocalEdge);
3773 NE.Orientation(TopAbs_FORWARD);
3774 if (NV1.IsSame(NV2))
3779 if (Or == TopAbs_FORWARD) {U1 = f; U2 = l;}
3780 else {U1 = l; U2 = f;}
3781 if (Or == TopAbs_FORWARD)
3785 if (Abs(U1-l) < eps) U1 = f;
3786 if (Abs(U2-f) < eps) U2 = l;
3788 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3789 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3790 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3791 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3792 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3793 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3795 ConstShapes.Bind(E,NE);
3796 NE.Orientation(E.Orientation());
3802 if (Abs(U2-l) < eps) U2 = f;
3803 if (Abs(U1-f) < eps) U1 = l;
3805 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3806 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3807 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3808 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3809 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3810 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3812 ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
3813 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3818 //-------------------
3819 // edge is not ferme.
3820 //-------------------
3821 if (Or == TopAbs_FORWARD) {
3823 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3824 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3825 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3826 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3827 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3828 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3833 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3834 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3835 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3836 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3837 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3838 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3841 ConstShapes.Bind(E,NE);
3842 NE.Orientation(E.Orientation());
3846 TopoDS_Shape aLocalVertex = NV1.Oriented(TopAbs_FORWARD );
3847 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3848 aLocalVertex = NV2.Oriented(TopAbs_REVERSED);
3849 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3850 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_FORWARD )));
3851 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_REVERSED)));
3853 ConstShapes.Bind(E,NE);
3854 NE.Orientation(E.Orientation());
3858 TopoDS_Shape aLocalVertex = NV2.Oriented(TopAbs_FORWARD );
3859 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3860 aLocalVertex = NV1.Oriented(TopAbs_REVERSED);
3861 B.Add (NE,TopoDS::Vertex(aLocalVertex));
3862 // B.Add (NE,TopoDS::Vertex(NV2.Oriented(TopAbs_FORWARD )));
3863 // B.Add (NE,TopoDS::Vertex(NV1.Oriented(TopAbs_REVERSED)));
3865 ConstShapes.Bind(E,NE.Oriented(TopAbs_REVERSED));
3866 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3871 } // Build.IsBound(E)
3872 else if (ConstShapes.IsBound(E)) { // !Build.IsBound(E)
3873 NE = TopoDS::Edge(ConstShapes(E));
3874 BuildPCurves(NE,NF);
3875 Or = NE.Orientation();
3876 if (Or == TopAbs_REVERSED) {
3877 NE.Orientation(TopAbs::Reverse(E.Orientation()));
3880 NE.Orientation(E.Orientation());
3885 ConstShapes.Bind(E,NE.Oriented(TopAbs_FORWARD));
3889 B.Add(NF,NW.Oriented(W.Orientation()));
3891 NF.Orientation(F.Orientation());
3892 BRepTools::Update(NF); // Maj des UVPoints
3897 char* name = new char[100];
3898 sprintf(name,"FOB_%d",NbFOB++);
3899 DBRep::Set(name,NF);
3905 //=======================================================================
3906 //function : Deboucle3D
3908 //=======================================================================
3910 TopoDS_Shape BRepOffset_Tool::Deboucle3D(const TopoDS_Shape& S,
3911 const TopTools_MapOfShape& Boundary)
3913 return BRepAlgo_Tool::Deboucle3D(S,Boundary);
3916 //=======================================================================
3917 //function : IsInOut
3919 //=======================================================================
3921 static Standard_Boolean IsInOut (BRepTopAdaptor_FClass2d& FC,
3922 Geom2dAdaptor_Curve AC,
3923 const TopAbs_State& S )
3925 Standard_Real Def = 100*Precision::Confusion();
3926 GCPnts_QuasiUniformDeflection QU(AC,Def);
3928 for (Standard_Integer i = 1; i <= QU.NbPoints(); i++) {
3929 gp_Pnt2d P = AC.Value(QU.Parameter(i));
3930 if (FC.Perform(P) != S) {
3931 return Standard_False;
3934 return Standard_True;
3937 //=======================================================================
3938 //function : CorrectOrientation
3940 //=======================================================================
3942 void BRepOffset_Tool::CorrectOrientation(const TopoDS_Shape& SI,
3943 const TopTools_IndexedMapOfShape& NewEdges,
3944 Handle(BRepAlgo_AsDes)& AsDes,
3945 BRepAlgo_Image& InitOffset,
3946 const Standard_Real Offset)
3949 TopExp_Explorer exp;
3950 exp.Init(SI,TopAbs_FACE);
3951 Standard_Real f=0.,l=0.;
3953 for (; exp.More(); exp.Next()) {
3955 const TopoDS_Face& FI = TopoDS::Face(exp.Current());
3956 const TopTools_ListOfShape& LOF = InitOffset.Image(FI);
3957 TopTools_ListIteratorOfListOfShape it(LOF);
3958 for (; it.More(); it.Next()) {
3959 const TopoDS_Face& OF = TopoDS::Face(it.Value());
3960 TopTools_ListOfShape& LOE = AsDes->ChangeDescendant(OF);
3961 TopTools_ListIteratorOfListOfShape itE(LOE);
3963 Standard_Boolean YaInt = Standard_False;
3964 for (; itE.More(); itE.Next()) {
3965 const TopoDS_Edge& OE = TopoDS::Edge(itE.Value());
3966 if (NewEdges.Contains(OE)) {YaInt = Standard_True; break;}
3969 TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD);
3970 BRepTopAdaptor_FClass2d FC (TopoDS::Face(aLocalFace),
3971 Precision::Confusion());
3972 // BRepTopAdaptor_FClass2d FC (TopoDS::Face(FI.Oriented(TopAbs_FORWARD)),
3973 // Precision::Confusion());
3974 for (itE.Initialize(LOE); itE.More(); itE.Next()) {
3975 TopoDS_Shape& OE = itE.Value();
3976 if (NewEdges.Contains(OE)) {
3977 Handle(Geom2d_Curve) CO2d =
3978 BRep_Tool::CurveOnSurface(TopoDS::Edge(OE),OF,f,l);
3979 Geom2dAdaptor_Curve AC(CO2d,f,l);
3982 if (IsInOut(FC,AC,TopAbs_OUT)) OE.Reverse();
3985 // if (IsInOut(FC,AC,TopAbs_IN)) OE.Reverse();