diff --git a/src/BRepAlgo/BRepAlgo_Tool.cxx b/src/BRepAlgo/BRepAlgo_Tool.cxx index bc4a6f662b..34a9b51ca9 100644 --- a/src/BRepAlgo/BRepAlgo_Tool.cxx +++ b/src/BRepAlgo/BRepAlgo_Tool.cxx @@ -52,8 +52,16 @@ TopoDS_Shape BRepAlgo_Tool::Deboucle3D(const TopoDS_Shape& S, Standard_Boolean JeGarde = Standard_True; for ( Standard_Integer i = 1; i <= Map.Extent() && JeGarde; i++) { - if (Map(i).Extent() < 2) { - const TopoDS_Edge& anEdge = TopoDS::Edge(Map.FindKey(i)); + const TopTools_ListOfShape& aLF = Map(i); + if (aLF.Extent() < 2) { + const TopoDS_Edge& anEdge = TopoDS::Edge(Map.FindKey(i)); + if (anEdge.Orientation() == TopAbs_INTERNAL) { + const TopoDS_Face& aFace = TopoDS::Face(aLF.First()); + if (aFace.Orientation() != TopAbs_INTERNAL) { + continue; + } + } + // if (!Boundary.Contains(anEdge) && !BRep_Tool::Degenerated(anEdge) ) JeGarde = Standard_False; diff --git a/src/BRepOffset/BRepOffset_Inter2d.cdl b/src/BRepOffset/BRepOffset_Inter2d.cdl index d3929ae1e2..30ea15943a 100644 --- a/src/BRepOffset/BRepOffset_Inter2d.cdl +++ b/src/BRepOffset/BRepOffset_Inter2d.cdl @@ -18,8 +18,8 @@ class Inter2d from BRepOffset - ---Purpose: Computes the intersections betwwen edges on a face - -- stores result is SD as AsDes from BRepOffset. + ---Purpose: Computes the intersections betwwen edges on a face + -- stores result is SD as AsDes from BRepOffset. uses AsDes from BRepAlgo, @@ -30,27 +30,28 @@ uses Real from Standard is - Compute(myclass ; AsDes : AsDes from BRepAlgo; - F : Face from TopoDS; - NewEdges : IndexedMapOfShape from TopTools; - Tol : Real from Standard); - - ---Purpose: Computes the intersections between the edges stored - -- is AsDes as descendants of . Intersections is computed - -- between two edges if one of them is bound in NewEdges. + Compute(myclass ; AsDes : AsDes from BRepAlgo; + F : Face from TopoDS; + NewEdges : IndexedMapOfShape from TopTools; + Tol : Real from Standard); + + ---Purpose: Computes the intersections between the edges stored + -- is AsDes as descendants of . Intersections is computed + -- between two edges if one of them is bound in NewEdges. -- Modified by skv - Fri Dec 26 16:53:16 2003 OCC4455 Begin -- Add another parameter: offset value. ConnexIntByInt(myclass ; - FI : Face from TopoDS; - OFI : in out Offset from BRepOffset; - MES : in out DataMapOfShapeShape from TopTools; - Build : DataMapOfShapeShape from TopTools; - AsDes : AsDes from BRepAlgo; - Offset: Real from Standard; - Tol : Real from Standard); + FI : Face from TopoDS; + OFI : in out Offset from BRepOffset; + MES : in out DataMapOfShapeShape from TopTools; + Build : DataMapOfShapeShape from TopTools; + AsDes : AsDes from BRepAlgo; + AsDes2d : AsDes from BRepAlgo; + Offset : Real from Standard; + Tol : Real from Standard); -- Modified by skv - Fri Dec 26 16:53:16 2003 OCC4455 End - + end Inter2d; diff --git a/src/BRepOffset/BRepOffset_Inter2d.cxx b/src/BRepOffset/BRepOffset_Inter2d.cxx index 2c6c6438a2..43d7e32f7f 100644 --- a/src/BRepOffset/BRepOffset_Inter2d.cxx +++ b/src/BRepOffset/BRepOffset_Inter2d.cxx @@ -95,7 +95,7 @@ static Standard_Integer NbNewVertices = 0; //======================================================================= static TopoDS_Vertex CommonVertex(TopoDS_Edge& E1, - TopoDS_Edge& E2) + TopoDS_Edge& E2) { TopoDS_Vertex V1[2],V2[2],V; // Modified by skv - Wed Dec 24 18:08:39 2003 OCC4455 Begin @@ -120,11 +120,11 @@ static TopoDS_Vertex CommonVertex(TopoDS_Edge& E1, //======================================================================= static void Store (const TopoDS_Edge& E1, - const TopoDS_Edge& E2, - TopTools_ListOfShape& LV1, - TopTools_ListOfShape& LV2, - Handle(BRepAlgo_AsDes) AsDes, - Standard_Real Tol) + const TopoDS_Edge& E2, + TopTools_ListOfShape& LV1, + TopTools_ListOfShape& LV2, + Handle(BRepAlgo_AsDes) AsDes, + Standard_Real Tol) { //------------------------------------------------------------- // Test if the points of intersection correspond to existing @@ -165,90 +165,90 @@ static void Store (const TopoDS_Edge& E1, // Find if the point of intersection corresponds to a vertex of E1. //----------------------------------------------------------------- for (it.Initialize(VOnE1); it.More(); it.Next()) { - P1 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value())); - if (P.IsEqual(P1,Tol)) { - V = TopoDS::Vertex(it.Value()); - V1 = V; - OnE1 = Standard_True; - break; - } + P1 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value())); + if (P.IsEqual(P1,Tol)) { + V = TopoDS::Vertex(it.Value()); + V1 = V; + OnE1 = Standard_True; + break; + } } } if (!VOnE2.IsEmpty()) { if (OnE1) { - //----------------------------------------------------------------- - // Find if the vertex found on E1 is not already on E2. - //----------------------------------------------------------------- - for (it.Initialize(VOnE2); it.More(); it.Next()) { - if (it.Value().IsSame(V)) { - OnE2 = Standard_True; - V2 = V; - break; - } - } + //----------------------------------------------------------------- + // Find if the vertex found on E1 is not already on E2. + //----------------------------------------------------------------- + for (it.Initialize(VOnE2); it.More(); it.Next()) { + if (it.Value().IsSame(V)) { + OnE2 = Standard_True; + V2 = V; + break; + } + } } for (it.Initialize(VOnE2); it.More(); it.Next()) { - //----------------------------------------------------------------- - // Find if the point of intersection corresponds to a vertex of E2. - //----------------------------------------------------------------- - P2 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value())); - if (P.IsEqual(P2,Tol)) { - V = TopoDS::Vertex(it.Value()); - V2 = V; - OnE2 = Standard_True; - break; - } + //----------------------------------------------------------------- + // Find if the point of intersection corresponds to a vertex of E2. + //----------------------------------------------------------------- + P2 = BRep_Tool::Pnt(TopoDS::Vertex(it.Value())); + if (P.IsEqual(P2,Tol)) { + V = TopoDS::Vertex(it.Value()); + V2 = V; + OnE2 = Standard_True; + break; + } } } if (OnE1 && OnE2) { if (!V1.IsSame(V2)) { - //--------------------------------------------------------------- - // Two vertices are actually the same. - // V2 will be replaced by V1. - // update the parameters of vertex on edges. - //--------------------------------------------------------------- - Standard_Real UV2; - TopoDS_Edge EWE2; - const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2); + //--------------------------------------------------------------- + // Two vertices are actually the same. + // V2 will be replaced by V1. + // update the parameters of vertex on edges. + //--------------------------------------------------------------- + Standard_Real UV2; + TopoDS_Edge EWE2; + const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2); - for (it.Initialize(EdgeWithV2); it.More(); it.Next()) { - EWE2 = TopoDS::Edge(it.Value()); - TopoDS_Shape aLocalShape =V2.Oriented(TopAbs_INTERNAL); - UV2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2); -// UV2 = -// BRep_Tool::Parameter(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),EWE2); - aLocalShape = V1.Oriented(TopAbs_INTERNAL); - B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol); -// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)), -// UV2,EWE2,Tol); - } - AsDes->Replace(V2,V1); + for (it.Initialize(EdgeWithV2); it.More(); it.Next()) { + EWE2 = TopoDS::Edge(it.Value()); + TopoDS_Shape aLocalShape =V2.Oriented(TopAbs_INTERNAL); + UV2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2); +// UV2 = +// BRep_Tool::Parameter(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),EWE2); + aLocalShape = V1.Oriented(TopAbs_INTERNAL); + B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol); +// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)), +// UV2,EWE2,Tol); + } + AsDes->Replace(V2,V1); } } if (!OnE1) { if (OnE2) { - TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL); - B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol); -// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)), -// U1,E1,Tol); + TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL); + B.UpdateVertex(TopoDS::Vertex(aLocalShape),U1,E1,Tol); +// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)), +// U1,E1,Tol); } NewVOnE1.Append(V.Oriented(O1)); } if (!OnE2) { if (OnE1) { - TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL); - B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol); -// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)), -// U2,E2,Tol); + TopoDS_Shape aLocalShape = V.Oriented(TopAbs_INTERNAL); + B.UpdateVertex(TopoDS::Vertex(aLocalShape),U2,E2,Tol); +// B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)), +// U2,E2,Tol); } NewVOnE2.Append(V.Oriented(O2)); } #ifdef DRAW - if (Inter2dAffichInt2d) { + if (Inter2dAffichInt2d) { if (!OnE1 && !OnE2) { char name[256]; - sprintf(name,"VV_%d",NbNewVertices++); + sprintf(name,"VV_%d",NbNewVertices++); DBRep::Set(name,V); } } @@ -265,11 +265,12 @@ static void Store (const TopoDS_Edge& E1, //======================================================================= static void EdgeInter(const TopoDS_Face& F, - const TopoDS_Edge& E1, - const TopoDS_Edge& E2, - const Handle(BRepAlgo_AsDes)& AsDes, - Standard_Real Tol, - Standard_Boolean WithOri) + const BRepAdaptor_Surface& BAsurf, + const TopoDS_Edge& E1, + const TopoDS_Edge& E2, + const Handle(BRepAlgo_AsDes)& AsDes, + Standard_Real Tol, + Standard_Boolean WithOri) { #ifdef DRAW if (Inter2dAffichInt2d) { @@ -314,117 +315,117 @@ static void EdgeInter(const TopoDS_Face& F, Standard_Boolean WithDegen = BRep_Tool::Degenerated(E1) || BRep_Tool::Degenerated(E2); if (WithDegen) - { - Standard_Integer ideg = (BRep_Tool::Degenerated(E1))? 1 : 2; - TopoDS_Iterator iter( EI[ideg] ); - if (iter.More()) - { - const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value()); - DegPoint = BRep_Tool::Pnt(vdeg); - } - else - { - BRepAdaptor_Curve CEdeg( EI[ideg], F ); - DegPoint = CEdeg.Value( CEdeg.FirstParameter() ); - } - } - BRepAdaptor_Surface BAsurf(F); + { + Standard_Integer ideg = (BRep_Tool::Degenerated(E1))? 1 : 2; + TopoDS_Iterator iter( EI[ideg] ); + if (iter.More()) + { + const TopoDS_Vertex& vdeg = TopoDS::Vertex(iter.Value()); + DegPoint = BRep_Tool::Pnt(vdeg); + } + else + { + BRepAdaptor_Curve CEdeg( EI[ideg], F ); + DegPoint = CEdeg.Value( CEdeg.FirstParameter() ); + } + } + Handle(Geom2d_Curve) pcurve1 = BRep_Tool::CurveOnSurface(E1, F, f[1], l[1]); Handle(Geom2d_Curve) pcurve2 = BRep_Tool::CurveOnSurface(E2, F, f[2], l[2]); Geom2dAdaptor_Curve GAC1(pcurve1, f[1], l[1]); Geom2dAdaptor_Curve GAC2(pcurve2, f[2], l[2]); Geom2dInt_GInter Inter2d( GAC1, GAC2, TolDub, TolDub ); for (i = 1; i <= Inter2d.NbPoints(); i++) - { - gp_Pnt P3d; - if (WithDegen) - P3d = DegPoint; - else - { - gp_Pnt2d P2d = Inter2d.Point(i).Value(); - P3d = BAsurf.Value( P2d.X(), P2d.Y() ); - } - ResPoints.Append( P3d ); - ResParamsOnE1.Append( Inter2d.Point(i).ParamOnFirst() ); - ResParamsOnE2.Append( Inter2d.Point(i).ParamOnSecond() ); - } + { + gp_Pnt P3d; + if (WithDegen) + P3d = DegPoint; + else + { + gp_Pnt2d P2d = Inter2d.Point(i).Value(); + P3d = BAsurf.Value( P2d.X(), P2d.Y() ); + } + ResPoints.Append( P3d ); + ResParamsOnE1.Append( Inter2d.Point(i).ParamOnFirst() ); + ResParamsOnE2.Append( Inter2d.Point(i).ParamOnSecond() ); + } for (i = 1; i <= ResPoints.Length(); i++) - { - Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter(); - Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter(); - if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2)) - { + { + Standard_Real aT1 = ResParamsOnE1(i); //ponc1.Parameter(); + Standard_Real aT2 = ResParamsOnE2(i); //ponc2.Parameter(); + if (Precision::IsInfinite(aT1) || Precision::IsInfinite(aT2)) + { #ifdef OCCT_DEBUG - cout << "Inter2d : Solution rejected due to infinite parameter"< l[1]+Tol) - { - cout << "out of limit"< l[1]+Tol) - { - cout << "out of limit"<IsInstance(STANDARD_TYPE(Geom2d_TrimmedCurve))) @@ -850,29 +851,29 @@ static Standard_Boolean ExtendPCurve(const Handle(Geom2d_Curve)& aPCurve, (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset)) { if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BezierCurve))) - { - Handle(Geom2d_BezierCurve) aBezier = *((Handle(Geom2d_BezierCurve)*)&NewPCurve); - if (aBezier->NbPoles() == 2) - { - TColgp_Array1OfPnt2d thePoles(1,2); - aBezier->Poles(thePoles); - gp_Vec2d aVec(thePoles(1), thePoles(2)); - NewPCurve = new Geom2d_Line(thePoles(1), aVec); - return Standard_True; - } - } + { + Handle(Geom2d_BezierCurve) aBezier = *((Handle(Geom2d_BezierCurve)*)&NewPCurve); + if (aBezier->NbPoles() == 2) + { + TColgp_Array1OfPnt2d thePoles(1,2); + aBezier->Poles(thePoles); + gp_Vec2d aVec(thePoles(1), thePoles(2)); + NewPCurve = new Geom2d_Line(thePoles(1), aVec); + return Standard_True; + } + } else if (NewPCurve->IsInstance(STANDARD_TYPE(Geom2d_BSplineCurve))) - { - Handle(Geom2d_BSplineCurve) aBSpline = *((Handle(Geom2d_BSplineCurve)*)&NewPCurve); - if (aBSpline->NbKnots() == 2 && aBSpline->NbPoles() == 2) - { - TColgp_Array1OfPnt2d thePoles(1,2); - aBSpline->Poles(thePoles); - gp_Vec2d aVec(thePoles(1), thePoles(2)); - NewPCurve = new Geom2d_Line(thePoles(1), aVec); - return Standard_True; - } - } + { + Handle(Geom2d_BSplineCurve) aBSpline = *((Handle(Geom2d_BSplineCurve)*)&NewPCurve); + if (aBSpline->NbKnots() == 2 && aBSpline->NbPoles() == 2) + { + TColgp_Array1OfPnt2d thePoles(1,2); + aBSpline->Poles(thePoles); + gp_Vec2d aVec(thePoles(1), thePoles(2)); + NewPCurve = new Geom2d_Line(thePoles(1), aVec); + return Standard_True; + } + } } FirstPar = aPCurve->FirstParameter(); @@ -955,161 +956,161 @@ static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real Handle( BRep_CurveRepresentation ) CurveRep = itr.Value(); Standard_Real FirstPar, LastPar; if (CurveRep->IsCurveOnSurface()) - { - NbPCurves++; - Handle(Geom2d_Curve) theCurve = CurveRep->PCurve(); - FirstPar = theCurve->FirstParameter(); - LastPar = theCurve->LastParameter(); + { + NbPCurves++; + Handle(Geom2d_Curve) theCurve = CurveRep->PCurve(); + FirstPar = theCurve->FirstParameter(); + LastPar = theCurve->LastParameter(); - if (theCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) && - (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset)) - { - Handle(Geom2d_Curve) NewPCurve; - if (ExtendPCurve(theCurve, anEf, anEl, a2Offset, NewPCurve)) - { - CurveRep->PCurve(NewPCurve); - FirstPar = NewPCurve->FirstParameter(); - LastPar = NewPCurve->LastParameter(); - if (CurveRep->IsCurveOnClosedSurface()) - { - Handle(Geom2d_Curve) PCurve2 = CurveRep->PCurve2(); - if (ExtendPCurve(PCurve2, anEf, anEl, a2Offset, NewPCurve)) - CurveRep->PCurve2(NewPCurve); - } - } - } - else if (theCurve->IsPeriodic()) - { - Standard_Real delta = (theCurve->Period() - (anEl - anEf))*0.5; - delta *= 0.95; - FirstPar = anEf - delta; - LastPar = anEl + delta; - } - else if (theCurve->IsClosed()) - LastPar -= 0.05*(LastPar - FirstPar); + if (theCurve->IsKind(STANDARD_TYPE(Geom2d_BoundedCurve)) && + (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset)) + { + Handle(Geom2d_Curve) NewPCurve; + if (ExtendPCurve(theCurve, anEf, anEl, a2Offset, NewPCurve)) + { + CurveRep->PCurve(NewPCurve); + FirstPar = NewPCurve->FirstParameter(); + LastPar = NewPCurve->LastParameter(); + if (CurveRep->IsCurveOnClosedSurface()) + { + Handle(Geom2d_Curve) PCurve2 = CurveRep->PCurve2(); + if (ExtendPCurve(PCurve2, anEf, anEl, a2Offset, NewPCurve)) + CurveRep->PCurve2(NewPCurve); + } + } + } + else if (theCurve->IsPeriodic()) + { + Standard_Real delta = (theCurve->Period() - (anEl - anEf))*0.5; + delta *= 0.95; + FirstPar = anEf - delta; + LastPar = anEl + delta; + } + else if (theCurve->IsClosed()) + LastPar -= 0.05*(LastPar - FirstPar); - //check FirstPar and LastPar: the pcurve should be in its surface - theCurve = CurveRep->PCurve(); - Handle(Geom_Surface) theSurf = CurveRep->Surface(); - Standard_Real Umin, Umax, Vmin, Vmax; - theSurf->Bounds(Umin, Umax, Vmin, Vmax); - TColGeom2d_SequenceOfCurve BoundLines; - if (!Precision::IsInfinite(Vmin)) - { - Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmin ), - gp_Dir2d( 1., 0. )); - BoundLines.Append(aLine); - } - if (!Precision::IsInfinite(Umin)) - { - Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umin, 0. ), - gp_Dir2d( 0., 1. )); - BoundLines.Append(aLine); - } - if (!Precision::IsInfinite(Vmax)) - { - Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmax ), - gp_Dir2d( 1., 0. )); - BoundLines.Append(aLine); - } - if (!Precision::IsInfinite(Umax)) - { - Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umax, 0. ), - gp_Dir2d( 0., 1. )); - BoundLines.Append(aLine); - } + //check FirstPar and LastPar: the pcurve should be in its surface + theCurve = CurveRep->PCurve(); + Handle(Geom_Surface) theSurf = CurveRep->Surface(); + Standard_Real Umin, Umax, Vmin, Vmax; + theSurf->Bounds(Umin, Umax, Vmin, Vmax); + TColGeom2d_SequenceOfCurve BoundLines; + if (!Precision::IsInfinite(Vmin)) + { + Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmin ), + gp_Dir2d( 1., 0. )); + BoundLines.Append(aLine); + } + if (!Precision::IsInfinite(Umin)) + { + Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umin, 0. ), + gp_Dir2d( 0., 1. )); + BoundLines.Append(aLine); + } + if (!Precision::IsInfinite(Vmax)) + { + Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( 0., Vmax ), + gp_Dir2d( 1., 0. )); + BoundLines.Append(aLine); + } + if (!Precision::IsInfinite(Umax)) + { + Handle(Geom2d_Line) aLine = new Geom2d_Line(gp_Pnt2d( Umax, 0. ), + gp_Dir2d( 0., 1. )); + BoundLines.Append(aLine); + } - TColStd_SequenceOfReal params; - Geom2dInt_GInter IntCC; - Geom2dAdaptor_Curve GAcurve(theCurve); - for (i = 1; i <= BoundLines.Length(); i++) - { - Geom2dAdaptor_Curve GAline( BoundLines(i) ); - IntCC.Perform( GAcurve, GAline, Precision::PConfusion(), Precision::PConfusion()); - if (IntCC.IsDone()) - { - for (j = 1; j <= IntCC.NbPoints(); j++) - { - const IntRes2d_IntersectionPoint& ip = IntCC.Point(j); - gp_Pnt2d aPoint = ip.Value(); - if (aPoint.X() >= Umin && aPoint.X() <= Umax && - aPoint.Y() >= Vmin && aPoint.Y() <= Vmax) - params.Append( ip.ParamOnFirst() ); - } - for (j = 1; j <= IntCC.NbSegments(); j++) - { - const IntRes2d_IntersectionSegment& is = IntCC.Segment(j); - if (is.HasFirstPoint()) - { - const IntRes2d_IntersectionPoint& ip = is.FirstPoint(); - gp_Pnt2d aPoint = ip.Value(); - if (aPoint.X() >= Umin && aPoint.X() <= Umax && - aPoint.Y() >= Vmin && aPoint.Y() <= Vmax) - params.Append( ip.ParamOnFirst() ); - } - if (is.HasLastPoint()) - { - const IntRes2d_IntersectionPoint& ip = is.LastPoint(); - gp_Pnt2d aPoint = ip.Value(); - if (aPoint.X() >= Umin && aPoint.X() <= Umax && - aPoint.Y() >= Vmin && aPoint.Y() <= Vmax) - params.Append( ip.ParamOnFirst() ); - } - } - } - } - if (!params.IsEmpty()) - { - if (params.Length() == 1) - { - gp_Pnt2d PntFirst = theCurve->Value(FirstPar); - if (PntFirst.X() >= Umin && PntFirst.X() <= Umax && - PntFirst.Y() >= Vmin && PntFirst.Y() <= Vmax) - { - if (LastPar > params(1)) - LastPar = params(1); - } - else if (FirstPar < params(1)) - FirstPar = params(1); - } - else - { - Standard_Real fpar = RealLast(), lpar = RealFirst(); - for (i = 1; i <= params.Length(); i++) - { - if (params(i) < fpar) - fpar = params(i); - if (params(i) > lpar) - lpar = params(i); - } - if (FirstPar < fpar) - FirstPar = fpar; - if (LastPar > lpar) - LastPar = lpar; - } - } - //// end of check //// - (Handle(BRep_GCurve)::DownCast(CurveRep))->SetRange( FirstPar, LastPar ); - //gp_Pnt2d Pfirst = theCurve->Value(FirstPar); - //gp_Pnt2d Plast = theCurve->Value(LastPar); - //(Handle(BRep_CurveOnSurface)::DownCast(CurveRep))->SetUVPoints( Pfirst, Plast ); + TColStd_SequenceOfReal params; + Geom2dInt_GInter IntCC; + Geom2dAdaptor_Curve GAcurve(theCurve); + for (i = 1; i <= BoundLines.Length(); i++) + { + Geom2dAdaptor_Curve GAline( BoundLines(i) ); + IntCC.Perform( GAcurve, GAline, Precision::PConfusion(), Precision::PConfusion()); + if (IntCC.IsDone()) + { + for (j = 1; j <= IntCC.NbPoints(); j++) + { + const IntRes2d_IntersectionPoint& ip = IntCC.Point(j); + gp_Pnt2d aPoint = ip.Value(); + if (aPoint.X() >= Umin && aPoint.X() <= Umax && + aPoint.Y() >= Vmin && aPoint.Y() <= Vmax) + params.Append( ip.ParamOnFirst() ); + } + for (j = 1; j <= IntCC.NbSegments(); j++) + { + const IntRes2d_IntersectionSegment& is = IntCC.Segment(j); + if (is.HasFirstPoint()) + { + const IntRes2d_IntersectionPoint& ip = is.FirstPoint(); + gp_Pnt2d aPoint = ip.Value(); + if (aPoint.X() >= Umin && aPoint.X() <= Umax && + aPoint.Y() >= Vmin && aPoint.Y() <= Vmax) + params.Append( ip.ParamOnFirst() ); + } + if (is.HasLastPoint()) + { + const IntRes2d_IntersectionPoint& ip = is.LastPoint(); + gp_Pnt2d aPoint = ip.Value(); + if (aPoint.X() >= Umin && aPoint.X() <= Umax && + aPoint.Y() >= Vmin && aPoint.Y() <= Vmax) + params.Append( ip.ParamOnFirst() ); + } + } + } + } + if (!params.IsEmpty()) + { + if (params.Length() == 1) + { + gp_Pnt2d PntFirst = theCurve->Value(FirstPar); + if (PntFirst.X() >= Umin && PntFirst.X() <= Umax && + PntFirst.Y() >= Vmin && PntFirst.Y() <= Vmax) + { + if (LastPar > params(1)) + LastPar = params(1); + } + else if (FirstPar < params(1)) + FirstPar = params(1); + } + else + { + Standard_Real fpar = RealLast(), lpar = RealFirst(); + for (i = 1; i <= params.Length(); i++) + { + if (params(i) < fpar) + fpar = params(i); + if (params(i) > lpar) + lpar = params(i); + } + if (FirstPar < fpar) + FirstPar = fpar; + if (LastPar > lpar) + LastPar = lpar; + } + } + //// end of check //// + (Handle(BRep_GCurve)::DownCast(CurveRep))->SetRange( FirstPar, LastPar ); + //gp_Pnt2d Pfirst = theCurve->Value(FirstPar); + //gp_Pnt2d Plast = theCurve->Value(LastPar); + //(Handle(BRep_CurveOnSurface)::DownCast(CurveRep))->SetUVPoints( Pfirst, Plast ); - //update FirstParOnPC and LastParOnPC - if (FirstPar > FirstParOnPC) - { - FirstParOnPC = FirstPar; - MinPC = theCurve; - MinSurf = theSurf; - MinLoc = CurveRep->Location(); - } - if (LastPar < LastParOnPC) - { - LastParOnPC = LastPar; - MinPC = theCurve; - MinSurf = theSurf; - MinLoc = CurveRep->Location(); - } - } + //update FirstParOnPC and LastParOnPC + if (FirstPar > FirstParOnPC) + { + FirstParOnPC = FirstPar; + MinPC = theCurve; + MinSurf = theSurf; + MinLoc = CurveRep->Location(); + } + if (LastPar < LastParOnPC) + { + LastParOnPC = LastPar; + MinPC = theCurve; + MinSurf = theSurf; + MinLoc = CurveRep->Location(); + } + } } Standard_Real f, l; @@ -1118,168 +1119,168 @@ static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real { MinLoc = E.Location() * MinLoc; if (!C3d.IsNull()) - { - if (MinPC->IsClosed()) - { - f = FirstParOnPC; - l = LastParOnPC; - } - else if (C3d->IsPeriodic()) - { - Standard_Real delta = (C3d->Period() - (l - f))*0.5; - delta *= 0.95; - f -= delta; - l += delta; - } - else if (C3d->IsClosed()) - l -= 0.05*(l - f); - else - { - f = FirstParOnPC; - l = LastParOnPC; - GeomAPI_ProjectPointOnCurve Projector; - if (!Precision::IsInfinite(FirstParOnPC)) - { - gp_Pnt2d P2d1 = MinPC->Value(FirstParOnPC); - gp_Pnt P1 = MinSurf->Value( P2d1.X(), P2d1.Y() ); - P1.Transform(MinLoc.Transformation()); - Projector.Init( P1, C3d ); - if (Projector.NbPoints() > 0) - f = Projector.LowerDistanceParameter(); + { + if (MinPC->IsClosed()) + { + f = FirstParOnPC; + l = LastParOnPC; + } + else if (C3d->IsPeriodic()) + { + Standard_Real delta = (C3d->Period() - (l - f))*0.5; + delta *= 0.95; + f -= delta; + l += delta; + } + else if (C3d->IsClosed()) + l -= 0.05*(l - f); + else + { + f = FirstParOnPC; + l = LastParOnPC; + GeomAPI_ProjectPointOnCurve Projector; + if (!Precision::IsInfinite(FirstParOnPC)) + { + gp_Pnt2d P2d1 = MinPC->Value(FirstParOnPC); + gp_Pnt P1 = MinSurf->Value( P2d1.X(), P2d1.Y() ); + P1.Transform(MinLoc.Transformation()); + Projector.Init( P1, C3d ); + if (Projector.NbPoints() > 0) + f = Projector.LowerDistanceParameter(); #ifdef OCCT_DEBUG - else - cout<<"ProjectPointOnCurve not done"<Value(LastParOnPC); - gp_Pnt P2 = MinSurf->Value( P2d2.X(), P2d2.Y() ); - P2.Transform(MinLoc.Transformation()); - Projector.Init( P2, C3d ); - if (Projector.NbPoints() > 0) - l = Projector.LowerDistanceParameter(); + } + if (!Precision::IsInfinite(LastParOnPC)) + { + gp_Pnt2d P2d2 = MinPC->Value(LastParOnPC); + gp_Pnt P2 = MinSurf->Value( P2d2.X(), P2d2.Y() ); + P2.Transform(MinLoc.Transformation()); + Projector.Init( P2, C3d ); + if (Projector.NbPoints() > 0) + l = Projector.LowerDistanceParameter(); #ifdef OCCT_DEBUG - else - cout<<"ProjectPointOnCurve not done"<Transformed(MinLoc.Transformation())); - Standard_Real max_deviation = 0.; - if (Precision::IsInfinite(FirstParOnPC) || Precision::IsInfinite(LastParOnPC)) - { - if (MinPC->IsInstance(STANDARD_TYPE(Geom2d_Line))) - { - Standard_Boolean IsLine = Standard_False; - if (MinSurf->IsInstance(STANDARD_TYPE(Geom_Plane))) - IsLine = Standard_True; - else if (MinSurf->IsInstance(STANDARD_TYPE(Geom_CylindricalSurface)) || - MinSurf->IsInstance(STANDARD_TYPE(Geom_ConicalSurface))) - { - Handle(Geom2d_Line) theLine = *((Handle(Geom2d_Line)*)&MinPC); - gp_Dir2d LineDir = theLine->Direction(); - if (LineDir.IsParallel( gp::DY2d(), Precision::Angular() )) - IsLine = Standard_True; - } - if (IsLine) - { - gp_Pnt2d P2d1 = MinPC->Value(0.), P2d2 = MinPC->Value(1.); - gp_Pnt P1 = MinSurf->Value(P2d1.X(), P2d1.Y()); - gp_Pnt P2 = MinSurf->Value(P2d2.X(), P2d2.Y()); - gp_Vec aVec(P1, P2); - C3d = new Geom_Line( P1, aVec ); - } - } - } - else - { - Geom2dAdaptor_Curve AC2d( MinPC, FirstParOnPC, LastParOnPC ); - GeomAdaptor_Surface GAsurf( MinSurf ); - Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d ); - Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf ); - Adaptor3d_CurveOnSurface ConS( HC2d, HSurf ); - Standard_Real /*max_deviation,*/ average_deviation; - GeomAbs_Shape Continuity = GeomAbs_C1; - Standard_Integer MaxDegree = 14; - Standard_Integer MaxSegment = evaluateMaxSegment(ConS); - GeomLib::BuildCurve3d(Precision::Confusion(), - ConS, FirstParOnPC, LastParOnPC, - C3d, max_deviation, average_deviation, - Continuity, MaxDegree, MaxSegment); - } - BB.UpdateEdge( NE, C3d, max_deviation ); - //BB.Range( NE, FirstParOnPC, LastParOnPC ); - Standard_Boolean ProjectionSuccess = Standard_True; - if (NbPCurves > 1) - //BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True ); - for (itr.Initialize((Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves()); - itr.More(); - itr.Next()) - { - Handle( BRep_CurveRepresentation ) CurveRep = itr.Value(); - Standard_Real FirstPar, LastPar; - if (CurveRep->IsCurveOnSurface()) - { - Handle(Geom2d_Curve) theCurve = CurveRep->PCurve(); - Handle(Geom_Surface) theSurf = CurveRep->Surface(); - TopLoc_Location theLoc = CurveRep->Location(); - if (theCurve == MinPC && theSurf == MinSurf && theLoc == MinLoc) - continue; - FirstPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->First(); - LastPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->Last(); - if (Abs(FirstPar - FirstParOnPC) > Precision::PConfusion() || - Abs(LastPar - LastParOnPC) > Precision::PConfusion()) - { - theLoc = E.Location() * theLoc; - theSurf = Handle(Geom_Surface)::DownCast - (theSurf->Transformed(theLoc.Transformation())); + { + MinSurf = Handle(Geom_Surface)::DownCast + (MinSurf->Transformed(MinLoc.Transformation())); + Standard_Real max_deviation = 0.; + if (Precision::IsInfinite(FirstParOnPC) || Precision::IsInfinite(LastParOnPC)) + { + if (MinPC->IsInstance(STANDARD_TYPE(Geom2d_Line))) + { + Standard_Boolean IsLine = Standard_False; + if (MinSurf->IsInstance(STANDARD_TYPE(Geom_Plane))) + IsLine = Standard_True; + else if (MinSurf->IsInstance(STANDARD_TYPE(Geom_CylindricalSurface)) || + MinSurf->IsInstance(STANDARD_TYPE(Geom_ConicalSurface))) + { + Handle(Geom2d_Line) theLine = *((Handle(Geom2d_Line)*)&MinPC); + gp_Dir2d LineDir = theLine->Direction(); + if (LineDir.IsParallel( gp::DY2d(), Precision::Angular() )) + IsLine = Standard_True; + } + if (IsLine) + { + gp_Pnt2d P2d1 = MinPC->Value(0.), P2d2 = MinPC->Value(1.); + gp_Pnt P1 = MinSurf->Value(P2d1.X(), P2d1.Y()); + gp_Pnt P2 = MinSurf->Value(P2d2.X(), P2d2.Y()); + gp_Vec aVec(P1, P2); + C3d = new Geom_Line( P1, aVec ); + } + } + } + else + { + Geom2dAdaptor_Curve AC2d( MinPC, FirstParOnPC, LastParOnPC ); + GeomAdaptor_Surface GAsurf( MinSurf ); + Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d ); + Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf ); + Adaptor3d_CurveOnSurface ConS( HC2d, HSurf ); + Standard_Real /*max_deviation,*/ average_deviation; + GeomAbs_Shape Continuity = GeomAbs_C1; + Standard_Integer MaxDegree = 14; + Standard_Integer MaxSegment = evaluateMaxSegment(ConS); + GeomLib::BuildCurve3d(Precision::Confusion(), + ConS, FirstParOnPC, LastParOnPC, + C3d, max_deviation, average_deviation, + Continuity, MaxDegree, MaxSegment); + } + BB.UpdateEdge( NE, C3d, max_deviation ); + //BB.Range( NE, FirstParOnPC, LastParOnPC ); + Standard_Boolean ProjectionSuccess = Standard_True; + if (NbPCurves > 1) + //BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True ); + for (itr.Initialize((Handle(BRep_TEdge)::DownCast(NE.TShape()))->ChangeCurves()); + itr.More(); + itr.Next()) + { + Handle( BRep_CurveRepresentation ) CurveRep = itr.Value(); + Standard_Real FirstPar, LastPar; + if (CurveRep->IsCurveOnSurface()) + { + Handle(Geom2d_Curve) theCurve = CurveRep->PCurve(); + Handle(Geom_Surface) theSurf = CurveRep->Surface(); + TopLoc_Location theLoc = CurveRep->Location(); + if (theCurve == MinPC && theSurf == MinSurf && theLoc == MinLoc) + continue; + FirstPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->First(); + LastPar = (Handle(BRep_GCurve)::DownCast(CurveRep))->Last(); + if (Abs(FirstPar - FirstParOnPC) > Precision::PConfusion() || + Abs(LastPar - LastParOnPC) > Precision::PConfusion()) + { + theLoc = E.Location() * theLoc; + theSurf = Handle(Geom_Surface)::DownCast + (theSurf->Transformed(theLoc.Transformation())); - if (theCurve->IsInstance(STANDARD_TYPE(Geom2d_Line)) && - theSurf->IsKind(STANDARD_TYPE(Geom_BoundedSurface))) - { - gp_Dir2d theDir = (*((Handle(Geom2d_Line)*)&theCurve))->Direction(); - if (theDir.IsParallel(gp::DX2d(), Precision::Angular()) || - theDir.IsParallel(gp::DY2d(), Precision::Angular())) - { - Standard_Real U1, U2, V1, V2; - theSurf->Bounds(U1, U2, V1, V2); - gp_Pnt2d Origin = (*((Handle(Geom2d_Line)*)&theCurve))->Location(); - if (Abs(Origin.X()-U1) <= Precision::Confusion() || - Abs(Origin.X()-U2) <= Precision::Confusion() || - Abs(Origin.Y()-V1) <= Precision::Confusion() || - Abs(Origin.Y()-V2) <= Precision::Confusion()) - { - BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True ); - break; - } - } - } + if (theCurve->IsInstance(STANDARD_TYPE(Geom2d_Line)) && + theSurf->IsKind(STANDARD_TYPE(Geom_BoundedSurface))) + { + gp_Dir2d theDir = (*((Handle(Geom2d_Line)*)&theCurve))->Direction(); + if (theDir.IsParallel(gp::DX2d(), Precision::Angular()) || + theDir.IsParallel(gp::DY2d(), Precision::Angular())) + { + Standard_Real U1, U2, V1, V2; + theSurf->Bounds(U1, U2, V1, V2); + gp_Pnt2d Origin = (*((Handle(Geom2d_Line)*)&theCurve))->Location(); + if (Abs(Origin.X()-U1) <= Precision::Confusion() || + Abs(Origin.X()-U2) <= Precision::Confusion() || + Abs(Origin.Y()-V1) <= Precision::Confusion() || + Abs(Origin.Y()-V2) <= Precision::Confusion()) + { + BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True ); + break; + } + } + } - Handle(Geom2d_Curve) ProjPCurve = - GeomProjLib::Curve2d( C3d, FirstParOnPC, LastParOnPC, theSurf ); - if (ProjPCurve.IsNull()) - ProjectionSuccess = Standard_False; - else - CurveRep->PCurve( ProjPCurve ); - } - } - } - if (ProjectionSuccess) - BB.Range( NE, FirstParOnPC, LastParOnPC ); - else - { - BB.Range( NE, FirstParOnPC, LastParOnPC, Standard_True ); - BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True ); - } - } + Handle(Geom2d_Curve) ProjPCurve = + GeomProjLib::Curve2d( C3d, FirstParOnPC, LastParOnPC, theSurf ); + if (ProjPCurve.IsNull()) + ProjectionSuccess = Standard_False; + else + CurveRep->PCurve( ProjPCurve ); + } + } + } + if (ProjectionSuccess) + BB.Range( NE, FirstParOnPC, LastParOnPC ); + else + { + BB.Range( NE, FirstParOnPC, LastParOnPC, Standard_True ); + BRepLib::SameParameter( NE, Precision::Confusion(), Standard_True ); + } + } } else //no pcurves { @@ -1287,58 +1288,58 @@ static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real Standard_Real LastPar = C3d->LastParameter(); if (C3d->IsKind(STANDARD_TYPE(Geom_BoundedCurve)) && - (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset)) - { - Handle(Geom_TrimmedCurve) aTrCurve = - new Geom_TrimmedCurve(C3d, FirstPar, LastPar); - - // The curve is not prolonged on begin or end. - // Trying to prolong it adding a segment to its bound. - gp_Pnt aPBnd; - gp_Vec aVBnd; - gp_Pnt aPBeg; - gp_Dir aDBnd; - Handle(Geom_Line) aLin; - Handle(Geom_TrimmedCurve) aSegment; - GeomConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1); - Standard_Real aTol = Precision::Confusion(); - Standard_Real aDelta = Max(a2Offset, 1.); - - if (FirstPar > anEf - a2Offset) { - C3d->D1(FirstPar, aPBnd, aVBnd); - aDBnd.SetXYZ(aVBnd.XYZ()); - aPBeg = aPBnd.Translated(gp_Vec(-aDelta*aDBnd.XYZ())); - aLin = new Geom_Line(aPBeg, aDBnd); - aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta); - - if (!aCompCurve.Add(aSegment, aTol)) - return; - } - - if (LastPar < anEl + a2Offset) { - C3d->D1(LastPar, aPBeg, aVBnd); - aDBnd.SetXYZ(aVBnd.XYZ()); - aLin = new Geom_Line(aPBeg, aDBnd); - aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta); - - if (!aCompCurve.Add(aSegment, aTol)) - return; - } - - C3d = aCompCurve.BSplineCurve(); - FirstPar = C3d->FirstParameter(); - LastPar = C3d->LastParameter(); - BB.UpdateEdge(NE, C3d, Precision::Confusion()); - } + (FirstPar > anEf - a2Offset || LastPar < anEl + a2Offset)) + { + Handle(Geom_TrimmedCurve) aTrCurve = + new Geom_TrimmedCurve(C3d, FirstPar, LastPar); + + // The curve is not prolonged on begin or end. + // Trying to prolong it adding a segment to its bound. + gp_Pnt aPBnd; + gp_Vec aVBnd; + gp_Pnt aPBeg; + gp_Dir aDBnd; + Handle(Geom_Line) aLin; + Handle(Geom_TrimmedCurve) aSegment; + GeomConvert_CompCurveToBSplineCurve aCompCurve(aTrCurve, Convert_RationalC1); + Standard_Real aTol = Precision::Confusion(); + Standard_Real aDelta = Max(a2Offset, 1.); + + if (FirstPar > anEf - a2Offset) { + C3d->D1(FirstPar, aPBnd, aVBnd); + aDBnd.SetXYZ(aVBnd.XYZ()); + aPBeg = aPBnd.Translated(gp_Vec(-aDelta*aDBnd.XYZ())); + aLin = new Geom_Line(aPBeg, aDBnd); + aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta); + + if (!aCompCurve.Add(aSegment, aTol)) + return; + } + + if (LastPar < anEl + a2Offset) { + C3d->D1(LastPar, aPBeg, aVBnd); + aDBnd.SetXYZ(aVBnd.XYZ()); + aLin = new Geom_Line(aPBeg, aDBnd); + aSegment = new Geom_TrimmedCurve(aLin, 0, aDelta); + + if (!aCompCurve.Add(aSegment, aTol)) + return; + } + + C3d = aCompCurve.BSplineCurve(); + FirstPar = C3d->FirstParameter(); + LastPar = C3d->LastParameter(); + BB.UpdateEdge(NE, C3d, Precision::Confusion()); + } else if (C3d->IsPeriodic()) - { - Standard_Real delta = (C3d->Period() - (anEl - anEf))*0.5; - delta *= 0.95; - FirstPar = anEf - delta; - LastPar = anEl + delta; - } + { + Standard_Real delta = (C3d->Period() - (anEl - anEf))*0.5; + delta *= 0.95; + FirstPar = anEf - delta; + LastPar = anEl + delta; + } else if (C3d->IsClosed()) - LastPar -= 0.05*(LastPar - FirstPar); + LastPar -= 0.05*(LastPar - FirstPar); BB.Range( NE, FirstPar, LastPar ); } @@ -1352,9 +1353,9 @@ static void ExtentEdge(const TopoDS_Edge& E,TopoDS_Edge& NE, const Standard_Real //======================================================================= static Standard_Boolean UpdateVertex(TopoDS_Vertex V, - TopoDS_Edge& OE, - TopoDS_Edge& NE, - Standard_Real TolConf) + TopoDS_Edge& OE, + TopoDS_Edge& NE, + Standard_Real TolConf) { BRepAdaptor_Curve OC(OE); BRepAdaptor_Curve NC(NE); @@ -1384,9 +1385,9 @@ static Standard_Boolean UpdateVertex(TopoDS_Vertex V, // TopoDS_Edge EE = TopoDS::Edge(NE.Oriented(TopAbs_FORWARD)); aLocalShape = V.Oriented(TopAbs_INTERNAL); B.UpdateVertex(TopoDS::Vertex(aLocalShape), - U,NE,BRep_Tool::Tolerance(NE)); + U,NE,BRep_Tool::Tolerance(NE)); // B.UpdateVertex(TopoDS::Vertex(V.Oriented(TopAbs_INTERNAL)), -// U,NE,BRep_Tool::Tolerance(NE)); +// U,NE,BRep_Tool::Tolerance(NE)); } return OK; } @@ -1397,9 +1398,9 @@ static Standard_Boolean UpdateVertex(TopoDS_Vertex V, //======================================================================= void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)& AsDes, - const TopoDS_Face& F, - const TopTools_IndexedMapOfShape& NewEdges, - const Standard_Real Tol) + const TopoDS_Face& F, + const TopTools_IndexedMapOfShape& NewEdges, + const Standard_Real Tol) { #ifdef DRAW NbF2d++; @@ -1416,8 +1417,8 @@ void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)& AsDes, // calculate intersections2d on faces touched by // intersection3d //--------------------------------------------------------- - TopTools_ListIteratorOfListOfShape it1LE ; - TopTools_ListIteratorOfListOfShape it2LE ; + TopTools_ListIteratorOfListOfShape it1LE ; + TopTools_ListIteratorOfListOfShape it2LE ; //----------------------------------------------- // Intersection of edges 2*2. @@ -1425,7 +1426,8 @@ void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)& AsDes, const TopTools_ListOfShape& LE = AsDes->Descendant(F); TopoDS_Vertex V1,V2; Standard_Integer j, i = 1; - + BRepAdaptor_Surface BAsurf(F); + // for ( it1LE.Initialize(LE) ; it1LE.More(); it1LE.Next()) { const TopoDS_Edge& E1 = TopoDS::Edge(it1LE.Value()); j = 1; @@ -1438,10 +1440,10 @@ void BRepOffset_Inter2d::Compute (const Handle(BRepAlgo_AsDes)& AsDes, // between them and with edges of restrictions //------------------------------------------------------ if ( (!EdgesOfFace.Contains(E1) || !EdgesOfFace.Contains(E2)) && - (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) { - TopoDS_Shape aLocalShape = F.Oriented(TopAbs_FORWARD); - EdgeInter(TopoDS::Face(aLocalShape),E1,E2,AsDes,Tol,Standard_True); -// EdgeInter(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),E1,E2,AsDes,Tol,Standard_True); + (NewEdges.Contains(E1) || NewEdges.Contains(E2)) ) { + TopoDS_Shape aLocalShape = F.Oriented(TopAbs_FORWARD); + EdgeInter(TopoDS::Face(aLocalShape),BAsurf,E1,E2,AsDes,Tol,Standard_True); + // EdgeInter(TopoDS::Face(F.Oriented(TopAbs_FORWARD)),E1,E2,AsDes,Tol,Standard_True); } it2LE.Next(); j++; @@ -1462,7 +1464,8 @@ void BRepOffset_Inter2d::ConnexIntByInt BRepOffset_Offset& OFI, TopTools_DataMapOfShapeShape& MES, const TopTools_DataMapOfShapeShape& Build, - const Handle(BRepAlgo_AsDes)& AsDes, + const Handle(BRepAlgo_AsDes)& AsDes, + const Handle(BRepAlgo_AsDes)& AsDes2d, const Standard_Real Offset, const Standard_Real Tol) // Modified by skv - Fri Dec 26 16:53:18 2003 OCC4455 End @@ -1486,24 +1489,34 @@ void BRepOffset_Inter2d::ConnexIntByInt } if (YaBuild) { for (itL.Initialize(L); itL.More(); itL.Next()) { - const TopoDS_Edge& EI = TopoDS::Edge(itL.Value()); - TopoDS_Shape aLocalShape = OFI.Generated(EI); - const TopoDS_Edge& OE = TopoDS::Edge(aLocalShape); -// const TopoDS_Edge& OE = TopoDS::Edge(OFI.Generated(EI)); - if (!MES.IsBound(OE) && !Build.IsBound(EI)) { + const TopoDS_Edge& EI = TopoDS::Edge(itL.Value()); + TopoDS_Shape aLocalShape = OFI.Generated(EI); + const TopoDS_Edge& OE = TopoDS::Edge(aLocalShape); +// const TopoDS_Edge& OE = TopoDS::Edge(OFI.Generated(EI)); + if (!MES.IsBound(OE) && !Build.IsBound(EI)) { // Modified by skv - Fri Dec 26 16:59:52 2003 OCC4455 Begin -// ExtentEdge(OE,NE); - ExtentEdge(OE,NE, Offset); +// ExtentEdge(OE,NE); + ExtentEdge(OE,NE, Offset); // Modified by skv - Fri Dec 26 16:59:54 2003 OCC4455 End - MES.Bind (OE,NE); - } + MES.Bind (OE,NE); + } } } } - + TopoDS_Face FIO = TopoDS::Face(OFI.Face()); if (MES.IsBound(FIO)) FIO = TopoDS::Face(MES(FIO)); - + // + TopTools_MapOfShape aME; + const TopTools_ListOfShape& aLE = AsDes->Descendant(FIO); + TopTools_ListIteratorOfListOfShape aItLE(aLE); + for (; aItLE.More(); aItLE.Next()) { + const TopoDS_Shape& aE = aItLE.Value(); + aME.Add(aE); + } + // + BRepAdaptor_Surface BAsurf(FIO); + TopExp_Explorer exp(FI.Oriented(TopAbs_FORWARD),TopAbs_WIRE); for (; exp.More(); exp.Next()) { const TopoDS_Wire& W = TopoDS::Wire(exp.Current()); @@ -1515,18 +1528,18 @@ void BRepOffset_Inter2d::ConnexIntByInt TopoDS_Shape aLocalFace = FI.Oriented(TopAbs_FORWARD); wexp.Init(TopoDS::Wire(aLocalWire),TopoDS::Face(aLocalFace)); // wexp.Init(TopoDS::Wire(W .Oriented(TopAbs_FORWARD)), -// TopoDS::Face(FI.Oriented(TopAbs_FORWARD))); +// TopoDS::Face(FI.Oriented(TopAbs_FORWARD))); CurE = FirstE = wexp.Current(); while (!end) { wexp.Next(); if (wexp.More()) { - NextE = wexp.Current(); + NextE = wexp.Current(); } else { - NextE = FirstE; end = Standard_True; + NextE = FirstE; end = Standard_True; } if (CurE.IsSame(NextE)) continue; - + //IFV------------ TopoDS_Vertex Vref = CommonVertex(CurE, NextE); gp_Pnt Pref = BRep_Tool::Pnt(Vref); @@ -1546,48 +1559,66 @@ void BRepOffset_Inter2d::ConnexIntByInt TopoDS_Shape NE1,NE2; if (Build.IsBound(CurE) && Build.IsBound(NextE)) { - NE1 = Build(CurE ); - NE2 = Build(NextE); + NE1 = Build(CurE ); + NE2 = Build(NextE); } else if (Build.IsBound(CurE) && MES.IsBound(NEO)) { - NE1 = Build(CurE); - NE2 = MES (NEO); + NE1 = Build(CurE); + NE2 = MES (NEO); } else if (Build.IsBound(NextE) && MES.IsBound(CEO)) { - NE1 = Build(NextE); - NE2 = MES(CEO); + NE1 = Build(NextE); + NE2 = MES(CEO); } else { - DoInter = 0; + DoInter = 0; } if (DoInter) { - //------------------------------------ - // NE1,NE2 can be a compound of Edges. - //------------------------------------ - TopExp_Explorer Exp1,Exp2; - for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) { - for (Exp2.Init(NE2,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) { - RefEdgeInter(FIO,TopoDS::Edge(Exp1.Current()),TopoDS::Edge(Exp2.Current()), - AsDes,Tol,Standard_True/*Standard_False*/, Pref); - } - } + //------------------------------------ + // NE1,NE2 can be a compound of Edges. + //------------------------------------ + TopExp_Explorer Exp1,Exp2; + for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) { + for (Exp2.Init(NE2,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) { + RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),TopoDS::Edge(Exp2.Current()), + AsDes2d,Tol,Standard_True/*Standard_False*/, Pref); + } + } + // + if (Build.IsBound(Vref)) { + TopoDS_Shape NE3 = Build(Vref); + // + for (Exp2.Init(NE3,TopAbs_EDGE) ; Exp2.More(); Exp2.Next()) { + const TopoDS_Edge& aE3 = *(TopoDS_Edge*)&Exp2.Current(); + if (!aME.Contains(aE3)) { + continue; + } + // + for (Exp1.Init(NE1,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) { + RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),aE3, + AsDes2d,Tol,Standard_True/*Standard_False*/, Pref); + } + // + for (Exp1.Init(NE2,TopAbs_EDGE) ; Exp1.More(); Exp1.Next()) { + RefEdgeInter(FIO,BAsurf,TopoDS::Edge(Exp1.Current()),aE3, + AsDes2d,Tol,Standard_True/*Standard_False*/, Pref); + } + } + } } else { - if (MES.IsBound(CEO)) { - TopoDS_Vertex V = CommonVertex(CEO,NEO); - UpdateVertex (V,CEO,TopoDS::Edge(MES(CEO)),Tol); - AsDes->Add (MES(CEO),V); - } - else if (MES.IsBound(NEO)) { - TopoDS_Vertex V = CommonVertex(CEO,NEO); - UpdateVertex (V,NEO,TopoDS::Edge(MES(NEO)),Tol); - AsDes->Add (MES(NEO),V); - } + if (MES.IsBound(CEO)) { + TopoDS_Vertex V = CommonVertex(CEO,NEO); + UpdateVertex (V,CEO,TopoDS::Edge(MES(CEO)),Tol); + AsDes2d->Add (MES(CEO),V); + } + else if (MES.IsBound(NEO)) { + TopoDS_Vertex V = CommonVertex(CEO,NEO); + UpdateVertex (V,NEO,TopoDS::Edge(MES(NEO)),Tol); + AsDes2d->Add (MES(NEO),V); + } } CurE = NextE; } } } - - - diff --git a/src/BRepOffset/BRepOffset_Inter3d.cxx b/src/BRepOffset/BRepOffset_Inter3d.cxx index 334d800ccc..342747fd94 100644 --- a/src/BRepOffset/BRepOffset_Inter3d.cxx +++ b/src/BRepOffset/BRepOffset_Inter3d.cxx @@ -40,6 +40,7 @@ #include #include #include +#include @@ -49,8 +50,8 @@ //======================================================================= BRepOffset_Inter3d::BRepOffset_Inter3d(const Handle(BRepAlgo_AsDes)& AsDes, - const TopAbs_State Side , - const Standard_Real Tol) + const TopAbs_State Side , + const Standard_Real Tol) :myAsDes(AsDes), mySide(Side), myTol(Tol) @@ -64,8 +65,8 @@ myTol(Tol) //======================================================================= static void ExtentEdge(const TopoDS_Face& /*F*/, - const TopoDS_Edge& E, - TopoDS_Edge& NE) + const TopoDS_Edge& E, + TopoDS_Edge& NE) { TopoDS_Shape aLocalShape = E.EmptyCopied(); NE = TopoDS::Edge(aLocalShape); @@ -97,117 +98,60 @@ static void ExtentEdge(const TopoDS_Face& /*F*/, //function : SelectEdge //purpose : //======================================================================= - -static void SelectEdge (const TopoDS_Face& /*F*/, - const TopoDS_Face& /*EF*/, - const TopoDS_Edge& E, - TopTools_ListOfShape& LInt) +static void SelectEdge (const TopoDS_Shape& theS, + TopTools_ListOfShape& theLE) { - //------------------------------------------------------------ - // Proofing on the intersections on periodical faces - //------------------------------------------------------------ - TopTools_ListIteratorOfListOfShape it(LInt); -// Modified by Sergey KHROMOV - Wed Jun 5 11:43:04 2002 Begin -// Standard_Real dU = 1.0e100; - Standard_Real dU = RealLast(); -// Modified by Sergey KHROMOV - Wed Jun 5 11:43:05 2002 End - TopoDS_Edge GE; - - Standard_Real Fst, Lst, tmp; - BRep_Tool::Range(E, Fst, Lst); - BRepAdaptor_Curve Ad1(E); - - gp_Pnt PFirst = Ad1.Value( Fst ); - gp_Pnt PLast = Ad1.Value( Lst ); - -// Modified by Sergey KHROMOV - Wed Jun 5 11:23:10 2002 Begin - Extrema_ExtPC anExt; -// Modified by Sergey KHROMOV - Wed Jun 5 11:23:11 2002 End - //---------------------------------------------------------------------- - // Selection of edge that coversmost of the domain of the initial edge. - //---------------------------------------------------------------------- - for (; it.More(); it.Next()) { - const TopoDS_Edge& EI = TopoDS::Edge(it.Value()); - - BRep_Tool::Range(EI, Fst, Lst); - BRepAdaptor_Curve Ad2(EI); - -// Modified by Sergey KHROMOV - Wed Jun 5 11:25:03 2002 Begin - Standard_Integer i; - Standard_Real aTol = BRep_Tool::Tolerance(EI); - Standard_Boolean isMinFound = Standard_False; - Standard_Real aSqrDist1 = Precision::Infinite(); - Standard_Real aSqrDist2 = Precision::Infinite(); - - anExt.Initialize(Ad2, Fst, Lst, aTol); - -// Seek for the min distance for PFirst: - anExt.Perform(PFirst); - if (anExt.IsDone()) { - for (i = 1; i <= anExt.NbExt(); i++) { - if (anExt.IsMin(i)) { - const gp_Pnt &aPMin = anExt.Point(i).Value(); - - aSqrDist1 = PFirst.SquareDistance(aPMin); - isMinFound = Standard_True; - - break; - } + Standard_Real aT1, aT2, aDist, aDistMin; + TopExp_Explorer aExp; + TopTools_ListIteratorOfListOfShape aIt; + GeomAPI_ProjectPointOnCurve aProjPC; + gp_Pnt aPE1, aPE2; + TopoDS_Edge aRE; + // + aDistMin = RealLast(); + // + aIt.Initialize(theLE); + for (; aIt.More(); aIt.Next()) { + const TopoDS_Edge& aE = *(TopoDS_Edge*)&aIt.Value(); + // + const Handle(Geom_Curve)& aC = BRep_Tool::Curve(aE, aT1, aT2); + // + aProjPC.Init(aC, aT1, aT2); + aPE1 = aC->Value(aT1); + aPE2 = aC->Value(aT2); + // + aDist = 0.; + aExp.Init(theS, TopAbs_VERTEX); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aExp.Current(); + const gp_Pnt aP = BRep_Tool::Pnt(aV); + // + aProjPC.Perform(aP); + if (aProjPC.NbPoints()) { + aDist += aProjPC.LowerDistance(); + } + else { + aDist += Min(aP.Distance(aPE1), aP.Distance(aPE2)); } } - if (!isMinFound) { - gp_Pnt aP1 = Ad2.Value(Fst); - gp_Pnt aP2 = Ad2.Value(Lst); - - aSqrDist1 = Min(aP1.SquareDistance(PFirst), aP2.SquareDistance(PFirst)); + // + if (aDist < aDistMin) { + aDistMin = aDist; + aRE = aE; } - -// Seek for the min distance for PLast: - isMinFound = Standard_False; - anExt.Perform(PLast); - if (anExt.IsDone()) { - for (i = 1; i <= anExt.NbExt(); i++) { - if (anExt.IsMin(i)) { - const gp_Pnt &aPMin = anExt.Point(i).Value(); - - aSqrDist2 = PLast.SquareDistance(aPMin); - isMinFound = Standard_True; - - break; - } - } - } - if (!isMinFound) { - gp_Pnt aP1 = Ad2.Value(Fst); - gp_Pnt aP2 = Ad2.Value(Lst); - - aSqrDist2 = Min(aP1.SquareDistance(PLast), aP2.SquareDistance(PLast)); - } - - tmp = aSqrDist1 + aSqrDist2; -// gp_Pnt P1 = Ad2.Value(Fst); -// gp_Pnt P2 = Ad2.Value(Lst); - -// tmp = P1.Distance(PFirst) + P2.Distance(PLast); - if( tmp <= dU ) { - dU = tmp; - GE = EI; - } -// Modified by Sergey KHROMOV - Wed Jun 5 11:24:54 2002 End - } - LInt.Clear(); - LInt.Append(GE); + // + theLE.Clear(); + theLE.Append(aRE); } - //======================================================================= //function : CompletInt //purpose : //======================================================================= void BRepOffset_Inter3d::CompletInt(const TopTools_ListOfShape& SetOfFaces, - const BRepAlgo_Image& InitOffsetFace) + const BRepAlgo_Image& InitOffsetFace) { //--------------------------------------------------------------- // Calculate the intersections of offset faces @@ -250,8 +194,8 @@ void BRepOffset_Inter3d::CompletInt(const TopTools_ListOfShape& SetOfFaces, //======================================================================= void BRepOffset_Inter3d::FaceInter(const TopoDS_Face& F1, - const TopoDS_Face& F2, - const BRepAlgo_Image& InitOffsetFace) + const TopoDS_Face& F2, + const BRepAlgo_Image& InitOffsetFace) { TopTools_ListOfShape LInt1, LInt2; TopoDS_Edge NullEdge; @@ -261,9 +205,9 @@ void BRepOffset_Inter3d::FaceInter(const TopoDS_Face& F1, const TopoDS_Shape& InitF1 = InitOffsetFace.ImageFrom(F1); const TopoDS_Shape& InitF2 = InitOffsetFace.ImageFrom(F2); Standard_Boolean InterPipes = (InitF2.ShapeType() == TopAbs_EDGE && - InitF1.ShapeType() == TopAbs_EDGE ); + InitF1.ShapeType() == TopAbs_EDGE ); Standard_Boolean InterFaces = (InitF1.ShapeType() == TopAbs_FACE && - InitF2.ShapeType() == TopAbs_FACE); + InitF2.ShapeType() == TopAbs_FACE); TopTools_ListOfShape LE,LV; LInt1.Clear(); LInt2.Clear(); if (BRepOffset_Tool::HasCommonShapes(F1,F2,LE,LV) || @@ -273,38 +217,44 @@ void BRepOffset_Inter3d::FaceInter(const TopoDS_Face& F1, //------------------------------------------------- if ( LE.IsEmpty() && !LV.IsEmpty()) { if (InterPipes) { - //---------------------- - // tubes share a vertex. - //---------------------- - const TopoDS_Edge& EE1 = TopoDS::Edge(InitF1); - const TopoDS_Edge& EE2 = TopoDS::Edge(InitF2); - TopoDS_Vertex VE1[2],VE2[2]; - TopExp::Vertices(EE1,VE1[0],VE1[1]); - TopExp::Vertices(EE2,VE2[0],VE2[1]); - TopoDS_Vertex V; - for (Standard_Integer i = 0 ; i < 2; i++) { - for (Standard_Integer j = 0 ; j < 2; j++) { - if (VE1[i].IsSame(VE2[j])) { - V = VE1[i]; - } - } - } - if (!InitOffsetFace.HasImage(V)) { //no sphere - BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide); - } + //---------------------- + // tubes share a vertex. + //---------------------- + const TopoDS_Edge& EE1 = TopoDS::Edge(InitF1); + const TopoDS_Edge& EE2 = TopoDS::Edge(InitF2); + TopoDS_Vertex VE1[2],VE2[2]; + TopExp::Vertices(EE1,VE1[0],VE1[1]); + TopExp::Vertices(EE2,VE2[0],VE2[1]); + TopoDS_Vertex V; + for (Standard_Integer i = 0 ; i < 2; i++) { + for (Standard_Integer j = 0 ; j < 2; j++) { + if (VE1[i].IsSame(VE2[j])) { + V = VE1[i]; + } + } + } + if (!InitOffsetFace.HasImage(V)) { //no sphere + BRepOffset_Tool::PipeInter(F1,F2,LInt1,LInt2,mySide); + } } else { - //-------------------------------------------------------- - // Intersection having only common vertices - // and supports having common edges. - // UNSUFFICIENT, but a larger criterion shakes too - // many sections. - //-------------------------------------------------------- - if (InterFaces && - BRepOffset_Tool::HasCommonShapes(TopoDS::Face(InitF1), - TopoDS::Face(InitF2),LE,LV)) - if (!LE.IsEmpty()) - BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge); + //-------------------------------------------------------- + // Intersection having only common vertices + // and supports having common edges. + // UNSUFFICIENT, but a larger criterion shakes too + // many sections. + //-------------------------------------------------------- + if (InterFaces) { + if (BRepOffset_Tool::HasCommonShapes(TopoDS::Face(InitF1), + TopoDS::Face(InitF2),LE,LV)) { + if (!LE.IsEmpty()) { + BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge); + } + } + else { + BRepOffset_Tool::Inter3D(F1,F2,LInt1,LInt2,mySide,NullEdge); + } + } } } } @@ -350,13 +300,13 @@ void BRepOffset_Inter3d::ConnexIntByArc(const TopTools_ListOfShape& /*SetOfFaces //----------------------------------------------------------- const TopTools_ListOfShape& Anc = Analyse.Ancestors(E); if (Anc.Extent() == 2) { - F1 = TopoDS::Face(InitOffsetFace.Image(Anc.First()).First()); - F2 = TopoDS::Face(InitOffsetFace.Image(Anc.Last ()).First()); - if (!IsDone(F1,F2)) { - BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,E,Standard_True); - Store (F1,F2,LInt1,LInt2); - } - } + F1 = TopoDS::Face(InitOffsetFace.Image(Anc.First()).First()); + F2 = TopoDS::Face(InitOffsetFace.Image(Anc.Last ()).First()); + if (!IsDone(F1,F2)) { + BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,E,Standard_True); + Store (F1,F2,LInt1,LInt2); + } + } } } //--------------------------------------------------------------------- @@ -378,84 +328,84 @@ void BRepOffset_Inter3d::ConnexIntByArc(const TopTools_ListOfShape& /*SetOfFaces const TopTools_ListOfShape& AncE1 = Analyse.Ancestors(E1); for (Standard_Integer i = 0; i < 2; i++) { - if (!InitOffsetFace.HasImage(V[i])) { - //----------------------------- - // the vertex has no sphere. - //----------------------------- - const TopTools_ListOfShape& Anc = Analyse.Ancestors(V[i]); - TopTools_ListOfShape TangOnV; - Analyse.TangentEdges(E1,V[i],TangOnV); - TopTools_MapOfShape MTEV; - for (it.Initialize(TangOnV); it.More(); it.Next()) { - MTEV.Add(it.Value()); - } - for (it.Initialize(Anc); it.More(); it.Next()) { - const TopoDS_Edge& E2 = TopoDS::Edge(it.Value()); + if (!InitOffsetFace.HasImage(V[i])) { + //----------------------------- + // the vertex has no sphere. + //----------------------------- + const TopTools_ListOfShape& Anc = Analyse.Ancestors(V[i]); + TopTools_ListOfShape TangOnV; + Analyse.TangentEdges(E1,V[i],TangOnV); + TopTools_MapOfShape MTEV; + for (it.Initialize(TangOnV); it.More(); it.Next()) { + MTEV.Add(it.Value()); + } + for (it.Initialize(Anc); it.More(); it.Next()) { + const TopoDS_Edge& E2 = TopoDS::Edge(it.Value()); // Modified by skv - Fri Jan 16 16:27:54 2004 OCC4455 Begin -// if (E1.IsSame(E2) || MTEV.Contains(E2)) continue; - Standard_Boolean isToSkip = Standard_False; +// if (E1.IsSame(E2) || MTEV.Contains(E2)) continue; + Standard_Boolean isToSkip = Standard_False; - if (!E1.IsSame(E2)) { - const BRepOffset_ListOfInterval& aL = Analyse.Type(E2); + if (!E1.IsSame(E2)) { + const BRepOffset_ListOfInterval& aL = Analyse.Type(E2); - isToSkip = (MTEV.Contains(E2) && - (aL.IsEmpty() || - (!aL.IsEmpty() && aL.First().Type() != OT))); - } + isToSkip = (MTEV.Contains(E2) && + (aL.IsEmpty() || + (!aL.IsEmpty() && aL.First().Type() != OT))); + } - if (E1.IsSame(E2) || isToSkip) - continue; + if (E1.IsSame(E2) || isToSkip) + continue; // Modified by skv - Fri Jan 16 16:27:54 2004 OCC4455 End - if (InitOffsetFace.HasImage(E2)) { - //----------------------------- - // E2 generated a tube. - //----------------------------- - F2 = TopoDS::Face(InitOffsetFace.Image(E2).First()); - if (!IsDone(F1,F2)) { - //--------------------------------------------------------------------- - // Intersection tube/tube if the edges are not tangent (AFINIR). - //---------------------------------------------------------------------- - BRepOffset_Tool::PipeInter (F1,F2,LInt1,LInt2,mySide); - Store (F1,F2,LInt1,LInt2); - } - } - else { - //------------------------------------------------------- - // Intersection of the tube of E1 with faces // - // to face containing E2 if they are not tangent - // to the tube or if E2 is not a tangent edge. - //------------------------------------------------------- - const BRepOffset_ListOfInterval& L = Analyse.Type(E2); - if (!L.IsEmpty() && L.First().Type() == BRepOffset_Tangent) { - continue; - } - const TopTools_ListOfShape& AncE2 = Analyse.Ancestors(E2); - Standard_Boolean TangentFaces = Standard_False; - if (AncE2.Extent() == 2) { - TopoDS_Face InitF2 = TopoDS::Face(AncE2.First ()); - TangentFaces = (InitF2.IsSame(AncE1.First()) || - InitF2.IsSame(AncE1.Last())); - if (!TangentFaces) { - F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First()); - if (!IsDone(F1,F2)) { - BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge); - Store (F1,F2,LInt1,LInt2); - } - } - InitF2 = TopoDS::Face(AncE2.Last ()); - TangentFaces = (InitF2.IsSame(AncE1.First()) || - InitF2.IsSame(AncE1.Last())); - if (!TangentFaces) { - F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First()); - if (!IsDone(F1,F2)) { - BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge); - Store (F1,F2,LInt1,LInt2); - } - } - } - } - } - } + if (InitOffsetFace.HasImage(E2)) { + //----------------------------- + // E2 generated a tube. + //----------------------------- + F2 = TopoDS::Face(InitOffsetFace.Image(E2).First()); + if (!IsDone(F1,F2)) { + //--------------------------------------------------------------------- + // Intersection tube/tube if the edges are not tangent (AFINIR). + //---------------------------------------------------------------------- + BRepOffset_Tool::PipeInter (F1,F2,LInt1,LInt2,mySide); + Store (F1,F2,LInt1,LInt2); + } + } + else { + //------------------------------------------------------- + // Intersection of the tube of E1 with faces // + // to face containing E2 if they are not tangent + // to the tube or if E2 is not a tangent edge. + //------------------------------------------------------- + const BRepOffset_ListOfInterval& L = Analyse.Type(E2); + if (!L.IsEmpty() && L.First().Type() == BRepOffset_Tangent) { + continue; + } + const TopTools_ListOfShape& AncE2 = Analyse.Ancestors(E2); + Standard_Boolean TangentFaces = Standard_False; + if (AncE2.Extent() == 2) { + TopoDS_Face InitF2 = TopoDS::Face(AncE2.First ()); + TangentFaces = (InitF2.IsSame(AncE1.First()) || + InitF2.IsSame(AncE1.Last())); + if (!TangentFaces) { + F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First()); + if (!IsDone(F1,F2)) { + BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge); + Store (F1,F2,LInt1,LInt2); + } + } + InitF2 = TopoDS::Face(AncE2.Last ()); + TangentFaces = (InitF2.IsSame(AncE1.First()) || + InitF2.IsSame(AncE1.Last())); + if (!TangentFaces) { + F2 = TopoDS::Face(InitOffsetFace.Image(InitF2).First()); + if (!IsDone(F1,F2)) { + BRepOffset_Tool::Inter3D (F1,F2,LInt1,LInt2,mySide,NullEdge); + Store (F1,F2,LInt1,LInt2); + } + } + } + } + } + } } } } @@ -476,103 +426,213 @@ void BRepOffset_Inter3d::ConnexIntByInt TopTools_ListOfShape& Failed) { //TopExp_Explorer Exp(SI,TopAbs_EDGE); - TopTools_IndexedMapOfShape Emap; - TopExp::MapShapes( SI, TopAbs_EDGE, Emap ); + TopTools_IndexedMapOfShape VEmap; + TopTools_IndexedDataMapOfShapeListOfShape aMVF; TopoDS_Face F1,F2,OF1,OF2,NF1,NF2; TopAbs_State CurSide = mySide; BRep_Builder B; - TopTools_ListIteratorOfListOfShape it; - - //for (; Exp.More(); Exp.Next()) { - for (Standard_Integer i = 1; i <= Emap.Extent(); i++) { - //const TopoDS_Edge& E = TopoDS::Edge(Exp.Current()); - const TopoDS_Edge& E = TopoDS::Edge(Emap(i)); - const BRepOffset_ListOfInterval& L = Analyse.Type(E); - if (!L.IsEmpty()) { + Standard_Boolean bEdge; + Standard_Integer i, aNb; + TopTools_ListIteratorOfListOfShape it, it1, itF1, itF2; + // + TopExp::MapShapes(SI, TopAbs_EDGE , VEmap); + TopExp::MapShapes(SI, TopAbs_VERTEX, VEmap); + TopExp::MapShapesAndAncestors(SI, TopAbs_VERTEX, TopAbs_FACE, aMVF); + // + aNb = VEmap.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopoDS_Shape& aS = VEmap(i); + // + TopoDS_Edge E; + TopTools_ListOfShape aLF1, aLF2; + // + bEdge = (aS.ShapeType() == TopAbs_EDGE); + if (bEdge) { + // faces connected by the edge + E = *(TopoDS_Edge*)&aS; + // + const BRepOffset_ListOfInterval& L = Analyse.Type(E); + if (L.IsEmpty()) { + continue; + } + // BRepOffset_Type OT = L.First().Type(); - if (OT == BRepOffset_Convex || OT == BRepOffset_Concave) { - if (OT == BRepOffset_Concave) CurSide = TopAbs_IN; - else CurSide = TopAbs_OUT; - //----------------------------------------------------------- - // edge is of the proper type, return adjacent faces. - //----------------------------------------------------------- - const TopTools_ListOfShape& Anc = Analyse.Ancestors(E); - if (Anc.Extent() != 2) continue; - F1 = TopoDS::Face(Anc.First()); - F2 = TopoDS::Face(Anc.Last ()); - OF1 = TopoDS::Face(MapSF(F1).Face()); OF2 = TopoDS::Face(MapSF(F2).Face()); - if (!MES.IsBound(OF1)) { - Standard_Boolean enlargeU = Standard_True; - Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True; - BRepOffset_Tool::CheckBounds( F1, Analyse, enlargeU, enlargeVfirst, enlargeVlast ); - BRepOffset_Tool::EnLargeFace(OF1,NF1,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast); - MES.Bind(OF1,NF1); - } - else { - NF1 = TopoDS::Face(MES(OF1)); - } - if (!MES.IsBound(OF2)) { - Standard_Boolean enlargeU = Standard_True; - Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True; - BRepOffset_Tool::CheckBounds( F2, Analyse, enlargeU, enlargeVfirst, enlargeVlast ); - BRepOffset_Tool::EnLargeFace(OF2,NF2,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast); - MES.Bind(OF2,NF2); - } - else { - NF2 = TopoDS::Face(MES(OF2)); - } - if (!IsDone(NF1,NF2)) { - TopTools_ListOfShape LInt1,LInt2; - BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,Standard_True); - if (LInt1.Extent() > 1) - { - // intersection is in seceral edges (free sewing) - SelectEdge( NF1, NF2, E, LInt1 ); - SelectEdge( NF1, NF2, E, LInt2 ); - } - SetDone(NF1,NF2); - if (!LInt1.IsEmpty()) { - Store (NF1,NF2,LInt1,LInt2); - TopoDS_Compound C; - B.MakeCompound(C); - for (it.Initialize(LInt1) ; it.More(); it.Next()) { - B.Add(C,it.Value()); - } - Build.Bind(E,C); - } - else { - Failed.Append(E); - } - } else { // IsDone(NF1,NF2) - // Modified by skv - Fri Dec 26 12:20:13 2003 OCC4455 Begin - const TopTools_ListOfShape &aLInt1 = myAsDes->Descendant(NF1); - const TopTools_ListOfShape &aLInt2 = myAsDes->Descendant(NF2); - - if (!aLInt1.IsEmpty()) { - TopoDS_Compound C; - TopTools_ListIteratorOfListOfShape anIt2; - - B.MakeCompound(C); - - for (it.Initialize(aLInt1) ; it.More(); it.Next()) { - const TopoDS_Shape &anE1 = it.Value(); - - for (anIt2.Initialize(aLInt2) ; anIt2.More(); anIt2.Next()) { - const TopoDS_Shape &anE2 = anIt2.Value(); - - if (anE1.IsSame(anE2)) - B.Add(C, anE1); - } - } - Build.Bind(E,C); - } - else { - Failed.Append(E); - } - } - // Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End - } + if (OT != BRepOffset_Convex && OT != BRepOffset_Concave) { + continue; + } + // + if (OT == BRepOffset_Concave) CurSide = TopAbs_IN; + else CurSide = TopAbs_OUT; + //----------------------------------------------------------- + // edge is of the proper type, return adjacent faces. + //----------------------------------------------------------- + const TopTools_ListOfShape& Anc = Analyse.Ancestors(E); + if (Anc.Extent() != 2) { + continue; + } + // + F1 = TopoDS::Face(Anc.First()); + F2 = TopoDS::Face(Anc.Last ()); + // + aLF1.Append(F1); + aLF2.Append(F2); } + else { + // faces connected by the vertex + const TopTools_ListOfShape& aLF = aMVF.FindFromKey(aS); + if (aLF.Extent() < 2) { + continue; + } + // + Standard_Boolean bVertexOnly = Standard_False; + TopTools_MapOfShape aMFence; + // + it.Initialize(aLF); + for (; it.More(); it.Next()) { + const TopoDS_Face& aFV1 = *(TopoDS_Face*)&it.Value(); + if (!aMFence.Add(aFV1)) { + continue; + } + // + TopTools_MapOfShape aME; + TopExp_Explorer aExp(aFV1, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + aME.Add(aExp.Current()); + } + // + it1.Initialize(aLF); + for (it1.Next(); it1.More(); it1.Next()) { + const TopoDS_Face& aFV2 = *(TopoDS_Face*)&it1.Value(); + if (aMFence.Contains(aFV2)) { + continue; + } + // + bVertexOnly = Standard_True; + aExp.Init(aFV2, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aEV2 = aExp.Current(); + if (aME.Contains(aEV2)) { + bVertexOnly = Standard_False; + break; + } + } + // + if (bVertexOnly) { + aLF1.Append(aFV1); + aLF2.Append(aFV2); + aMFence.Add(aFV2); + } + } + } + // + if (aLF1.IsEmpty()) { + continue; + } + // + CurSide = mySide; + } + // + itF1.Initialize(aLF1); + itF2.Initialize(aLF2); + for (; itF1.More() && itF2.More(); itF1.Next(), itF2.Next()) { + F1 = TopoDS::Face(itF1.Value()); + F2 = TopoDS::Face(itF2.Value()); + // + OF1 = TopoDS::Face(MapSF(F1).Face()); + OF2 = TopoDS::Face(MapSF(F2).Face()); + if (!MES.IsBound(OF1)) { + Standard_Boolean enlargeU = Standard_True; + Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True; + BRepOffset_Tool::CheckBounds( F1, Analyse, enlargeU, enlargeVfirst, enlargeVlast ); + BRepOffset_Tool::EnLargeFace(OF1,NF1,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast); + MES.Bind(OF1,NF1); + } + else { + NF1 = TopoDS::Face(MES(OF1)); + } + // + if (!MES.IsBound(OF2)) { + Standard_Boolean enlargeU = Standard_True; + Standard_Boolean enlargeVfirst = Standard_True, enlargeVlast = Standard_True; + BRepOffset_Tool::CheckBounds( F2, Analyse, enlargeU, enlargeVfirst, enlargeVlast ); + BRepOffset_Tool::EnLargeFace(OF2,NF2,Standard_True,Standard_True,enlargeU,enlargeVfirst,enlargeVlast); + MES.Bind(OF2,NF2); + } + else { + NF2 = TopoDS::Face(MES(OF2)); + } + // + if (!IsDone(NF1,NF2)) { + TopTools_ListOfShape LInt1,LInt2; + BRepOffset_Tool::Inter3D (NF1,NF2,LInt1,LInt2,CurSide,E,bEdge); + if (LInt1.Extent() > 1) { + // intersection is in seceral edges (free sewing) + SelectEdge(aS, LInt1); + SelectEdge(aS, LInt2); + } + SetDone(NF1,NF2); + if (!LInt1.IsEmpty()) { + Store (NF1,NF2,LInt1,LInt2); + // + TopoDS_Compound C; + B.MakeCompound(C); + // + if (Build.IsBound(aS)) { + const TopoDS_Shape& aSE = Build(aS); + TopExp_Explorer aExp(aSE, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aNE = aExp.Current(); + B.Add(C, aNE); + } + } + // + it.Initialize(LInt1); + for (; it.More(); it.Next()) { + const TopoDS_Shape& aNE = it.Value(); + B.Add(C, aNE); + } + // + Build.Bind(aS,C); + } + else { + Failed.Append(aS); + } + } else { // IsDone(NF1,NF2) + // Modified by skv - Fri Dec 26 12:20:13 2003 OCC4455 Begin + const TopTools_ListOfShape &aLInt1 = myAsDes->Descendant(NF1); + const TopTools_ListOfShape &aLInt2 = myAsDes->Descendant(NF2); + + if (!aLInt1.IsEmpty()) { + TopoDS_Compound C; + B.MakeCompound(C); + // + if (Build.IsBound(aS)) { + const TopoDS_Shape& aSE = Build(aS); + TopExp_Explorer aExp(aSE, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aNE = aExp.Current(); + B.Add(C, aNE); + } + } + // + for (it.Initialize(aLInt1) ; it.More(); it.Next()) { + const TopoDS_Shape &anE1 = it.Value(); + // + for (it1.Initialize(aLInt2) ; it1.More(); it1.Next()) { + const TopoDS_Shape &anE2 = it1.Value(); + + if (anE1.IsSame(anE2)) + B.Add(C, anE1); + } + } + Build.Bind(aS,C); + } + else { + Failed.Append(aS); + } + } + } + // Modified by skv - Fri Dec 26 12:20:14 2003 OCC4455 End } } @@ -597,10 +657,12 @@ void BRepOffset_Inter3d::ContextIntByInt TopoDS_Edge OE; TopoDS_Compound C; BRep_Builder B; - TopTools_ListIteratorOfListOfShape it; - Standard_Integer i; - - for (i = 1; i <= ContextFaces.Extent(); i++) { + TopTools_ListIteratorOfListOfShape it, itF; + Standard_Integer i, j, aNb, aNbVE; + Standard_Boolean bEdge; + + aNb = ContextFaces.Extent(); + for (i = 1; i <= aNb; i++) { const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i)); myTouched.Add(CF); if (ExtentContext) { @@ -610,90 +672,154 @@ void BRepOffset_Inter3d::ContextIntByInt } TopAbs_State Side = TopAbs_OUT; - for (i = 1; i <= ContextFaces.Extent(); i++) { + for (i = 1; i <= aNb; i++) { const TopoDS_Face& CF = TopoDS::Face(ContextFaces(i)); if (ExtentContext) WCF = TopoDS::Face(MES(CF)); else WCF = CF; - for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); - exp.More(); exp.Next()) { - const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); - if (!Analyse.HasAncestor(E)) { - //---------------------------------------------------------------- - // the edges of faces of context that are not in the initial shape - // can appear in the result. - //---------------------------------------------------------------- - if (!ExtentContext) { - myAsDes->Add(CF,E); - myNewEdges.Add(E); - } - else { - if (!MES.IsBound(E)) { - TopoDS_Edge NE; - Standard_Real f,l,Tol; - BRep_Tool::Range(E,f,l); - Tol = BRep_Tool::Tolerance(E); - ExtentEdge(CF,E,NE); - TopoDS_Vertex V1,V2; - TopExp::Vertices(E,V1,V2); - NE.Orientation(TopAbs_FORWARD); - myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED)); - myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD)); - TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL); - B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol); - aLocalShape = V2.Oriented(TopAbs_INTERNAL); - B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol); -// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol); -// B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol); - NE.Orientation(E.Orientation()); - myAsDes->Add(CF,NE); - myNewEdges.Add(NE); - MES.Bind(E,NE); - } - else { - TopoDS_Shape NE = MES(E); - TopoDS_Shape aLocalShape = NE.Oriented(E.Orientation()); - myAsDes->Add(CF,aLocalShape); -// myAsDes->Add(CF,NE.Oriented(E.Orientation())); - } - } - continue; - } - const TopTools_ListOfShape& Anc = Analyse.Ancestors(E); - const TopoDS_Face& F = TopoDS::Face(Anc.First()); - OF = TopoDS::Face(MapSF(F).Face()); - TopoDS_Shape aLocalShape = MapSF(F).Generated(E); - OE = TopoDS::Edge(aLocalShape); -// OE = TopoDS::Edge(MapSF(F).Generated(E)); - if (!MES.IsBound(OF)) { - BRepOffset_Tool::EnLargeFace(OF,NF,1,1); - MES.Bind(OF,NF); + TopTools_IndexedMapOfShape VEmap; + TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_EDGE , VEmap); + TopExp::MapShapes(CF.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap); + // + aNbVE = VEmap.Extent(); + for (j = 1; j <= aNbVE; ++j) { + const TopoDS_Shape& aS = VEmap(j); + // + bEdge = (aS.ShapeType() == TopAbs_EDGE); + // + TopoDS_Edge E; + TopTools_ListOfShape Anc; + // + if (bEdge) { + // faces connected by the edge + // + E = *(TopoDS_Edge*)&aS; + if (!Analyse.HasAncestor(E)) { + //---------------------------------------------------------------- + // the edges of faces of context that are not in the initial shape + // can appear in the result. + //---------------------------------------------------------------- + if (!ExtentContext) { + myAsDes->Add(CF,E); + myNewEdges.Add(E); + } + else { + if (!MES.IsBound(E)) { + TopoDS_Edge NE; + Standard_Real f,l,Tol; + BRep_Tool::Range(E,f,l); + Tol = BRep_Tool::Tolerance(E); + ExtentEdge(CF,E,NE); + TopoDS_Vertex V1,V2; + TopExp::Vertices(E,V1,V2); + NE.Orientation(TopAbs_FORWARD); + myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED)); + myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD)); + TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL); + B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol); + aLocalShape = V2.Oriented(TopAbs_INTERNAL); + B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol); +// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol); +// B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol); + NE.Orientation(E.Orientation()); + myAsDes->Add(CF,NE); + myNewEdges.Add(NE); + MES.Bind(E,NE); + } + else { + TopoDS_Shape NE = MES(E); + TopoDS_Shape aLocalShape = NE.Oriented(E.Orientation()); + myAsDes->Add(CF,aLocalShape); +// myAsDes->Add(CF,NE.Oriented(E.Orientation())); + } + } + continue; + } + Anc = Analyse.Ancestors(E); } else { - NF = TopoDS::Face(MES(OF)); + // faces connected by the vertex + // + if (!Analyse.HasAncestor(aS)) { + continue; + } + // + const TopTools_ListOfShape& aLE = Analyse.Ancestors(aS); + it.Initialize(aLE); + for (; it.More(); it.Next()) { + const TopoDS_Edge& aE = *(TopoDS_Edge*)&it.Value(); + // + if (BRep_Tool::Degenerated(aE)) { + continue; + } + // + if (VEmap.Contains(aE)) { + continue; + } + // + const TopTools_ListOfShape& aLF = Analyse.Ancestors(aE); + itF.Initialize(aLF); + for (; itF.More(); itF.Next()) { + const TopoDS_Shape& aF = itF.Value(); + Standard_Boolean bAdd = Standard_True; + exp.Init(aF, TopAbs_EDGE); + for (; exp.More() && bAdd; exp.Next()) { + const TopoDS_Shape& aEF = exp.Current(); + bAdd = !VEmap.Contains(aEF); + } + if (bAdd) { + Anc.Append(aF); + } + } + } } - if (!IsDone(NF,CF)) { - TopTools_ListOfShape LInt1,LInt2; - TopTools_ListOfShape LOE; - LOE.Append(OE); - BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,Standard_True); - SetDone(NF,CF); - if (!LInt1.IsEmpty()) { - Store (CF,NF,LInt1,LInt2); - if (LInt1.Extent() == 1) { - Build.Bind(E,LInt1.First()); - } - else { - B.MakeCompound(C); - for (it.Initialize(LInt1) ; it.More(); it.Next()) { - B.Add(C,it.Value()); - } - Build.Bind(E,C); - } - } - else { - Failed.Append(E); - } + // + itF.Initialize(Anc); + for (; itF.More(); itF.Next()) { + const TopoDS_Face& F = TopoDS::Face(itF.Value()); + OF = TopoDS::Face(MapSF(F).Face()); + TopoDS_Shape aLocalShape = MapSF(F).Generated(E); + OE = TopoDS::Edge(aLocalShape); +// OE = TopoDS::Edge(MapSF(F).Generated(E)); + if (!MES.IsBound(OF)) { + BRepOffset_Tool::EnLargeFace(OF,NF,1,1); + MES.Bind(OF,NF); + } + else { + NF = TopoDS::Face(MES(OF)); + } + if (!IsDone(NF,CF)) { + TopTools_ListOfShape LInt1,LInt2; + TopTools_ListOfShape LOE; + LOE.Append(OE); + BRepOffset_Tool::Inter3D (WCF,NF,LInt1,LInt2,Side,E,bEdge); + SetDone(NF,CF); + if (!LInt1.IsEmpty()) { + Store (CF,NF,LInt1,LInt2); + if ((LInt1.Extent() == 1) && !Build.IsBound(aS)) { + Build.Bind(aS,LInt1.First()); + } + else { + B.MakeCompound(C); + if (Build.IsBound(aS)) { + const TopoDS_Shape& aSE = Build(aS); + exp.Init(aSE, TopAbs_EDGE); + for (; exp.More(); exp.Next()) { + const TopoDS_Shape& aNE = exp.Current(); + B.Add(C, aNE); + } + } + // + for (it.Initialize(LInt1) ; it.More(); it.Next()) { + B.Add(C,it.Value()); + } + Build.Bind(aS,C); + } + } + else { + Failed.Append(aS); + } + } } } } @@ -705,10 +831,10 @@ void BRepOffset_Inter3d::ContextIntByInt //======================================================================= void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& ContextFaces, - const Standard_Boolean InSide, - const BRepOffset_Analyse& Analyse, - const BRepAlgo_Image& InitOffsetFace, - BRepAlgo_Image& InitOffsetEdge) + const Standard_Boolean InSide, + const BRepOffset_Analyse& Analyse, + const BRepAlgo_Image& InitOffsetFace, + BRepAlgo_Image& InitOffsetEdge) { TopTools_ListOfShape LInt1,LInt2; @@ -728,39 +854,39 @@ void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& Conte for (j = 1; j <= ContextFaces.Extent(); j++) { const TopoDS_Face& CF = TopoDS::Face(ContextFaces(j)); for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); - exp.More(); exp.Next()) { + exp.More(); exp.Next()) { const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); if (!Analyse.HasAncestor(E)) { - if (InSide) - myAsDes->Add(CF,E); - else { - TopoDS_Edge NE; - if (!InitOffsetEdge.HasImage(E)) { - Standard_Real f,l,Tol; - BRep_Tool::Range(E,f,l); - Tol = BRep_Tool::Tolerance(E); - ExtentEdge(CF,E,NE); - TopoDS_Vertex V1,V2; - TopExp::Vertices(E,V1,V2); - NE.Orientation(TopAbs_FORWARD); - myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED)); - myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD)); - TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL); - B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol); - aLocalShape = V2.Oriented(TopAbs_INTERNAL); - B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol); -// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol); -// B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol); - NE.Orientation(E.Orientation()); - myAsDes->Add(CF,NE); - InitOffsetEdge.Bind(E,NE); - } - else { - NE = TopoDS::Edge(InitOffsetEdge.Image(E).First()); - myAsDes->Add(CF,NE.Oriented(E.Orientation())); - } - } - continue; + if (InSide) + myAsDes->Add(CF,E); + else { + TopoDS_Edge NE; + if (!InitOffsetEdge.HasImage(E)) { + Standard_Real f,l,Tol; + BRep_Tool::Range(E,f,l); + Tol = BRep_Tool::Tolerance(E); + ExtentEdge(CF,E,NE); + TopoDS_Vertex V1,V2; + TopExp::Vertices(E,V1,V2); + NE.Orientation(TopAbs_FORWARD); + myAsDes->Add(NE,V1.Oriented(TopAbs_REVERSED)); + myAsDes->Add(NE,V2.Oriented(TopAbs_FORWARD)); + TopoDS_Shape aLocalShape = V1.Oriented(TopAbs_INTERNAL); + B.UpdateVertex(TopoDS::Vertex(aLocalShape),f,NE,Tol); + aLocalShape = V2.Oriented(TopAbs_INTERNAL); + B.UpdateVertex(TopoDS::Vertex(aLocalShape),l,NE,Tol); +// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)),f,NE,Tol); +// B.UpdateVertex(TopoDS::Vertex(V2.Oriented(TopAbs_INTERNAL)),l,NE,Tol); + NE.Orientation(E.Orientation()); + myAsDes->Add(CF,NE); + InitOffsetEdge.Bind(E,NE); + } + else { + NE = TopoDS::Edge(InitOffsetEdge.Image(E).First()); + myAsDes->Add(CF,NE.Oriented(E.Orientation())); + } + } + continue; } OE.Nullify(); //--------------------------------------------------- @@ -787,11 +913,11 @@ void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& Conte //-------------------------------------------------- // MAJ of OE on cap CF. //-------------------------------------------------- -// TopTools_ListOfShape LOE; LOE.Append(OE); +// TopTools_ListOfShape LOE; LOE.Append(OE); // BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide); // LInt2.Clear(); // StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes, -// LInt1,LInt2); +// LInt1,LInt2); LInt1.Clear(); LInt1.Append(OE); LInt2.Clear(); TopAbs_Orientation O1,O2; @@ -807,18 +933,18 @@ void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& Conte TopoDS_Vertex V[2]; TopExp::Vertices (E,V[0],V[1]); for (Standard_Integer i = 0; i < 2; i++) { - if (!MV.Add(V[i])) continue; - OF1.Nullify(); - const TopTools_ListOfShape& LE = Analyse.Ancestors(V[i]); - TopTools_ListIteratorOfListOfShape itLE(LE); - for ( ; itLE.More(); itLE.Next()) { - const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value()); - if (InitOffsetFace.HasImage(EV)) { - //------------------------------------------------- - // OF1 parallel face generated by an ancester edge of V[i]. - //------------------------------------------------- - OF1 = TopoDS::Face(InitOffsetFace.Image(EV).First()); - OE = TopoDS::Edge(InitOffsetEdge.Image(V[i]).First()); + if (!MV.Add(V[i])) continue; + OF1.Nullify(); + const TopTools_ListOfShape& LE = Analyse.Ancestors(V[i]); + TopTools_ListIteratorOfListOfShape itLE(LE); + for ( ; itLE.More(); itLE.Next()) { + const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value()); + if (InitOffsetFace.HasImage(EV)) { + //------------------------------------------------- + // OF1 parallel face generated by an ancester edge of V[i]. + //------------------------------------------------- + OF1 = TopoDS::Face(InitOffsetFace.Image(EV).First()); + OE = TopoDS::Edge(InitOffsetEdge.Image(V[i]).First()); { //Check if OE has pcurve in CF and OF1 @@ -834,64 +960,64 @@ void BRepOffset_Inter3d::ContextIntByArc(const TopTools_IndexedMapOfShape& Conte } } - //-------------------------------------------------- - // MAj of OE on cap CF. - //-------------------------------------------------- - // LOE.Clear(); LOE.Append(OE); - // BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide); - // LInt2.Clear(); - // StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes, - // LInt1,LInt2); - LInt1.Clear(); LInt1.Append(OE); - LInt2.Clear(); - TopAbs_Orientation O1,O2; - BRepOffset_Tool::OrientSection(OE,CF,OF1,O1,O2); -// if (mySide == TopAbs_OUT); - O1 = TopAbs::Reverse(O1); - LInt1.First().Orientation(O1); - Store(CF,OF1,LInt1,LInt2); - } - } + //-------------------------------------------------- + // MAj of OE on cap CF. + //-------------------------------------------------- + // LOE.Clear(); LOE.Append(OE); + // BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide); + // LInt2.Clear(); + // StoreInter3d(CF,OF1,myTouched,NewEdges,InterDone,myAsDes, + // LInt1,LInt2); + LInt1.Clear(); LInt1.Append(OE); + LInt2.Clear(); + TopAbs_Orientation O1,O2; + BRepOffset_Tool::OrientSection(OE,CF,OF1,O1,O2); +// if (mySide == TopAbs_OUT); + O1 = TopAbs::Reverse(O1); + LInt1.First().Orientation(O1); + Store(CF,OF1,LInt1,LInt2); + } + } } } for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); - exp.More(); exp.Next()) { + exp.More(); exp.Next()) { const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current()); if (!Analyse.HasAncestor(V)) { - continue; + continue; } const TopTools_ListOfShape& LE = Analyse.Ancestors(V); TopTools_ListIteratorOfListOfShape itLE(LE); for (; itLE.More(); itLE.Next()) { - const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value()); - const TopTools_ListOfShape& LF = Analyse.Ancestors(EV); - TopTools_ListIteratorOfListOfShape itLF(LF); - for ( ; itLF.More(); itLF.Next()) { - const TopoDS_Face& FEV = TopoDS::Face(itLF.Value()); - //------------------------------------------------- - // OF1 parallel face generated by uneFace ancestor of V[i]. - //------------------------------------------------- - OF1 = TopoDS::Face(InitOffsetFace.Image(FEV).First()); - if (!IsDone(OF1,CF)) { - //------------------------------------------------------- - // Find if one of edges of OF1 has no trace in CF. - //------------------------------------------------------- - TopTools_ListOfShape LOE; - TopExp_Explorer exp2(OF1.Oriented(TopAbs_FORWARD),TopAbs_EDGE); - for ( ;exp2.More(); exp2.Next()) { - LOE.Append(exp2.Current()); - } - BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide,myTol); - //------------------------------------------------------- - // If no trace try intersection. - //------------------------------------------------------- - if (LInt1.IsEmpty()) { - BRepOffset_Tool::Inter3D (CF,OF1,LInt1,LInt2,mySide,NullEdge); - } - Store (CF,OF1,LInt1,LInt2); - } - } + const TopoDS_Edge& EV = TopoDS::Edge(itLE.Value()); + const TopTools_ListOfShape& LF = Analyse.Ancestors(EV); + TopTools_ListIteratorOfListOfShape itLF(LF); + for ( ; itLF.More(); itLF.Next()) { + const TopoDS_Face& FEV = TopoDS::Face(itLF.Value()); + //------------------------------------------------- + // OF1 parallel face generated by uneFace ancestor of V[i]. + //------------------------------------------------- + OF1 = TopoDS::Face(InitOffsetFace.Image(FEV).First()); + if (!IsDone(OF1,CF)) { + //------------------------------------------------------- + // Find if one of edges of OF1 has no trace in CF. + //------------------------------------------------------- + TopTools_ListOfShape LOE; + TopExp_Explorer exp2(OF1.Oriented(TopAbs_FORWARD),TopAbs_EDGE); + for ( ;exp2.More(); exp2.Next()) { + LOE.Append(exp2.Current()); + } + BRepOffset_Tool::TryProject(CF,OF1,LOE,LInt1,LInt2,mySide,myTol); + //------------------------------------------------------- + // If no trace try intersection. + //------------------------------------------------------- + if (LInt1.IsEmpty()) { + BRepOffset_Tool::Inter3D (CF,OF1,LInt1,LInt2,mySide,NullEdge); + } + Store (CF,OF1,LInt1,LInt2); + } + } } } } @@ -913,7 +1039,7 @@ void BRepOffset_Inter3d::AddCommonEdges(const TopTools_ListOfShape&) //======================================================================= void BRepOffset_Inter3d::SetDone(const TopoDS_Face& F1, - const TopoDS_Face& F2) + const TopoDS_Face& F2) { if (!myDone.IsBound(F1)) { TopTools_ListOfShape empty; @@ -934,7 +1060,7 @@ void BRepOffset_Inter3d::SetDone(const TopoDS_Face& F1, //======================================================================= Standard_Boolean BRepOffset_Inter3d::IsDone(const TopoDS_Face& F1, - const TopoDS_Face& F2) + const TopoDS_Face& F2) const { if (myDone.IsBound(F1)) { @@ -987,9 +1113,9 @@ TopTools_IndexedMapOfShape& BRepOffset_Inter3d::NewEdges() //======================================================================= void BRepOffset_Inter3d::Store(const TopoDS_Face& F1, - const TopoDS_Face& F2, - const TopTools_ListOfShape& LInt1, - const TopTools_ListOfShape& LInt2) + const TopoDS_Face& F2, + const TopTools_ListOfShape& LInt1, + const TopTools_ListOfShape& LInt2) { if (!LInt1.IsEmpty()) { myTouched.Add(F1); diff --git a/src/BRepOffset/BRepOffset_MakeOffset.cdl b/src/BRepOffset/BRepOffset_MakeOffset.cdl index 1b4fbb847e..c071d6157d 100644 --- a/src/BRepOffset/BRepOffset_MakeOffset.cdl +++ b/src/BRepOffset/BRepOffset_MakeOffset.cdl @@ -19,7 +19,7 @@ class MakeOffset from BRepOffset - ---Purpose: + ---Purpose: uses Image from BRepAlgo, @@ -36,47 +36,53 @@ uses Edge from TopoDS, MapOfShape from TopTools, IndexedMapOfShape from TopTools, - ListOfShape from TopTools, + ListOfShape from TopTools, + DataMapOfShapeShape from TopTools, + IndexedDataMapOfShapeListOfShape from TopTools, MakeLoops from BRepOffset is Create; - Create ( S : Shape from TopoDS; - Offset : Real from Standard; - Tol : Real from Standard; - Mode : Mode from BRepOffset = BRepOffset_Skin; - Intersection : Boolean from Standard = Standard_False; - SelfInter : Boolean from Standard = Standard_False; - Join : JoinType from GeomAbs = GeomAbs_Arc; - Thickening : Boolean from Standard = Standard_False) - returns MakeOffset from BRepOffset; - + Create ( S : Shape from TopoDS; + Offset : Real from Standard; + Tol : Real from Standard; + Mode : Mode from BRepOffset = BRepOffset_Skin; + Intersection : Boolean from Standard = Standard_False; + SelfInter : Boolean from Standard = Standard_False; + Join : JoinType from GeomAbs = GeomAbs_Arc; + RemoveIntEdges : Boolean from Standard = Standard_False; + Thickening : Boolean from Standard = Standard_False; + RemoveInvalidFaces: Boolean from Standard = Standard_False) + returns MakeOffset from BRepOffset; + ---Category: Initialization. Initialize (me : in out; - S : Shape from TopoDS; - Offset : Real from Standard; - Tol : Real from Standard; - Mode : Mode from BRepOffset = BRepOffset_Skin; - Intersection : Boolean from Standard = Standard_False; - SelfInter : Boolean from Standard = Standard_False; - Join : JoinType from GeomAbs = GeomAbs_Arc; - Thickening : Boolean from Standard = Standard_False) + S : Shape from TopoDS; + Offset : Real from Standard; + Tol : Real from Standard; + Mode : Mode from BRepOffset = BRepOffset_Skin; + Intersection : Boolean from Standard = Standard_False; + SelfInter : Boolean from Standard = Standard_False; + Join : JoinType from GeomAbs = GeomAbs_Arc; + RemoveIntEdges : Boolean from Standard = Standard_False; + Thickening : Boolean from Standard = Standard_False; + RemoveInvalidFaces: Boolean from Standard = Standard_False) is static; Clear (me : in out) is static; AddFace (me : in out; F : Face from TopoDS) is static; - ---Purpose: Add Closing Faces, has to be in the initial - -- shape S. + ---Purpose: Add Closing Faces, has to be in the initial + -- shape S. SetOffsetOnFace (me : in out; - F : Face from TopoDS; - Off : Real from Standard) is static; - ---Purpose: set the offset on the Face + F : Face from TopoDS; + Off : Real from Standard) is static; + ---Purpose: set the offset on the Face ---Category: Computation. @@ -88,7 +94,7 @@ is ---Category: Querying. GetAnalyse(me) - ---C++: return const & + ---C++: return const & returns Analyse from BRepOffset is static; @@ -96,18 +102,18 @@ is is static; Shape (me) - ---C++: return const & + ---C++: return const & returns Shape from TopoDS is static; Error (me) returns Error from BRepOffset; - ---Purpose: returns information if IsDone() = FALSE. - + ---Purpose: returns information if IsDone() = FALSE. + OffsetFacesFromShapes (me) - ---Purpose: Returns containing links between initials - -- shapes and offset faces. - ---C++: return const & + ---Purpose: Returns containing links between initials + -- shapes and offset faces. + ---C++: return const & returns Image from BRepAlgo is static; @@ -115,24 +121,24 @@ is -- Query offset join type. GetJoinType(me) - ---Purpose: Returns myJoin. + ---Purpose: Returns myJoin. returns JoinType from GeomAbs is static; -- Add methods for supporting history. OffsetEdgesFromShapes (me) - ---Purpose: Returns containing links between initials - -- shapes and offset edges. - ---C++: return const & + ---Purpose: Returns containing links between initials + -- shapes and offset edges. + ---C++: return const & returns Image from BRepAlgo is static; -- Modified by skv - Tue Mar 15 16:17:37 2005 End ClosingFaces (me) - ---Purpose: Returns the list of closing faces stores by AddFace - ---C++: return const & + ---Purpose: Returns the list of closing faces stores by AddFace + ---C++: return const & returns IndexedMapOfShape from TopTools is static; @@ -156,18 +162,30 @@ is BuildOffsetByInter ( me : in out ) is static private; - + + BuildSplitsOfFaces (me:in out; + theLF : ListOfShape from TopTools; + theAsDes : AsDes from BRepAlgo; + theOrMap : out IndexedDataMapOfShapeListOfShape from TopTools; + theImage : out Image from BRepAlgo; + theLFail : out ListOfShape from TopTools; + bLimited : Boolean from Standard) + is static private; + ---Purpose: + -- Building splits of the offset faces by the section curves + -- between the neighboring faces. + SelfInter (me : in out ; - Modif : in out MapOfShape from TopTools) - is static private; + Modif : in out MapOfShape from TopTools) + is static private; Intersection3D (me : in out; - Inter : in out Inter3d from BRepOffset) - is static private; - + Inter : in out Inter3d from BRepOffset) + is static private; + Intersection2D ( me : in out ; Modif : IndexedMapOfShape from TopTools; - NewEdges : IndexedMapOfShape from TopTools) + NewEdges : IndexedMapOfShape from TopTools) is static private; MakeLoops ( me : in out ; @@ -187,7 +205,7 @@ is SelectShells (me : in out) is static private; - + EncodeRegularity( me : in out) is static private; @@ -195,20 +213,24 @@ is is static private; ToContext (me : in out; - MapSF : in out DataMapOfShapeOffset from BRepOffset) - is static private; + MapSF : in out DataMapOfShapeOffset from BRepOffset) + is static private; UpdateFaceOffset (me: in out) - ---Purpose: Private method use to update the map face<->offset + ---Purpose: Private method use to update the map face<->offset is static private; CorrectConicalFaces (me: in out) - ---Purpose: Private method used to correct degenerated edges on conical faces + ---Purpose: Private method used to correct degenerated edges on conical faces is static private; MakeMissingWalls (me: in out) - ---Purpose: Private method used to build walls for thickening the shell - is static private; + ---Purpose: Private method used to build walls for thickening the shell + is static private; + + RemoveInternalEdges (me: in out) + ---Purpose: Removes INTERNAL edges from the faces + is static private; fields @@ -218,13 +240,15 @@ fields myMode : Mode from BRepOffset; myInter : Boolean from Standard; mySelfInter : Boolean from Standard; - myJoin : JoinType from GeomAbs; + myJoin : JoinType from GeomAbs; + myRemoveIntEdges : Boolean from Standard; myThickening : Boolean from Standard; + myRemoveInvalidFaces : Boolean from Standard; myFaceOffset : DataMapOfShapeReal from TopTools; myFaces : IndexedMapOfShape from TopTools; - myAnalyse : Analyse from BRepOffset; + myAnalyse : Analyse from BRepOffset; myOffsetShape : Shape from TopoDS; -- Result myInitOffsetFace : Image from BRepAlgo; @@ -240,5 +264,4 @@ fields myBadShape : Shape from TopoDS; myIsPerformSewing: Boolean from Standard; -- Handle bad walls in thicksolid mode. - end MakeOffset; diff --git a/src/BRepOffset/BRepOffset_MakeOffset.cxx b/src/BRepOffset/BRepOffset_MakeOffset.cxx index 71f7615e52..b29ebed6c9 100644 --- a/src/BRepOffset/BRepOffset_MakeOffset.cxx +++ b/src/BRepOffset/BRepOffset_MakeOffset.cxx @@ -34,8 +34,7 @@ #include -#include -#include + #include #include #include @@ -45,6 +44,10 @@ #include #include +#include +#include +#include + #include #include #include @@ -62,6 +65,8 @@ #include #include #include +#include +#include #include #include @@ -90,7 +95,6 @@ #include #include -#include #include #include #include @@ -112,15 +116,32 @@ #include #include #include -#include -#include -#include -#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + + // POP for NT #include #include #include #include +#include +#include #ifdef DRAW @@ -149,7 +170,7 @@ //======================================================================= static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges, - Handle(BRepAlgo_AsDes) AsDes) + Handle(BRepAlgo_AsDes) AsDes) { TopTools_ListOfShape LVP; TopTools_ListIteratorOfListOfShape it1LE ; @@ -160,34 +181,34 @@ static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges, const TopoDS_Edge& NE = TopoDS::Edge(NewEdges(i)); if (AsDes->HasDescendant(NE)) { for (it1LE.Initialize(AsDes->Descendant(NE)); it1LE.More(); it1LE.Next()) { - if (AsDes->Ascendant(it1LE.Value()).Extent() < 3) { - LVP.Append(it1LE.Value()); - cout <<"Vertex on at least 3 edges."<Ascendant(it1LE.Value()).Extent() < 3) { + LVP.Append(it1LE.Value()); + cout <<"Vertex on at least 3 edges."<Ascendant(it1LE.Value()).Extent() > 3) { - cout <<"Vertex on more than 3 edges."<Ascendant(it1LE.Value()).Extent() > 3) { + cout <<"Vertex on more than 3 edges."< i) { - TopoDS_Shape V2 = it2.Value(); - gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(V2)); - if (!V1.IsSame(V2)) { - Standard_Real dist = P1.Distance(P2); - if (dist < distmin) distmin = dist; - if (dist < TolConf) { - Standard_Real UV2; - TopoDS_Edge EWE2; - const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2); - TopTools_ListIteratorOfListOfShape itAsDes; - for (itAsDes.Initialize(EdgeWithV2); itAsDes.More(); itAsDes.Next()) { - EWE2 = TopoDS::Edge(itAsDes.Value()); - TopoDS_Shape aLocalShape = V2.Oriented(TopAbs_INTERNAL); - UV2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2); - aLocalShape = V1.Oriented(TopAbs_INTERNAL) ; - B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol); -// UV2 = -// BRep_Tool::Parameter(TopoDS::Vertex(),EWE2); -// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)), -// UV2,EWE2,Tol); - } - AsDes->Replace(V2,V1); - } - } + TopoDS_Shape V2 = it2.Value(); + gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(V2)); + if (!V1.IsSame(V2)) { + Standard_Real dist = P1.Distance(P2); + if (dist < distmin) distmin = dist; + if (dist < TolConf) { + Standard_Real UV2; + TopoDS_Edge EWE2; + const TopTools_ListOfShape& EdgeWithV2 = AsDes->Ascendant(V2); + TopTools_ListIteratorOfListOfShape itAsDes; + for (itAsDes.Initialize(EdgeWithV2); itAsDes.More(); itAsDes.Next()) { + EWE2 = TopoDS::Edge(itAsDes.Value()); + TopoDS_Shape aLocalShape = V2.Oriented(TopAbs_INTERNAL); + UV2 = BRep_Tool::Parameter(TopoDS::Vertex(aLocalShape),EWE2); + aLocalShape = V1.Oriented(TopAbs_INTERNAL) ; + B.UpdateVertex(TopoDS::Vertex(aLocalShape),UV2,EWE2,Tol); +// UV2 = +// BRep_Tool::Parameter(TopoDS::Vertex(),EWE2); +// B.UpdateVertex(TopoDS::Vertex(V1.Oriented(TopAbs_INTERNAL)), +// UV2,EWE2,Tol); + } + AsDes->Replace(V2,V1); + } + } } j++; } @@ -243,307 +264,186 @@ static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges, } #endif -//--------------------------------------------------------------------- -static void UpdateTolerance ( TopoDS_Shape& myShape, - const TopTools_IndexedMapOfShape& myFaces); - -static void CorrectSolid(TopoDS_Solid& theSol, TopTools_ListOfShape& theSolList); -//--------------------------------------------------------------------- -// -static Standard_Boolean FindParameter(const TopoDS_Vertex& V, - const TopoDS_Edge& E, - Standard_Real& U) -{ - // Search the vertex in the edge - - Standard_Boolean rev = Standard_False; - TopoDS_Shape VF; - TopAbs_Orientation orient = TopAbs_INTERNAL; - - TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD)); - - // if the edge has no vertices - // and is degenerated use the vertex orientation - // RLE, june 94 - - if (!itv.More() && BRep_Tool::Degenerated(E)) { - orient = V.Orientation(); - } - - while (itv.More()) { - const TopoDS_Shape& Vcur = itv.Value(); - if (V.IsSame(Vcur)) { - if (VF.IsNull()) { - VF = Vcur; - } - else { - rev = E.Orientation() == TopAbs_REVERSED; - if (Vcur.Orientation() == V.Orientation()) { - VF = Vcur; - } - } - } - itv.Next(); - } - - if (!VF.IsNull()) orient = VF.Orientation(); - - Standard_Real f,l; - - if (orient == TopAbs_FORWARD) { - BRep_Tool::Range(E,f,l); - //return (rev) ? l : f; - U = (rev) ? l : f; - return Standard_True; - } - - else if (orient == TopAbs_REVERSED) { - BRep_Tool::Range(E,f,l); - //return (rev) ? f : l; - U = (rev) ? f : l; - return Standard_True; - } - - else { - TopLoc_Location L; - const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L,f,l); - L = L.Predivided(V.Location()); - if (!C.IsNull() || BRep_Tool::Degenerated(E)) { - BRep_ListIteratorOfListOfPointRepresentation itpr - ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points()); - - while (itpr.More()) { - const Handle(BRep_PointRepresentation)& pr = itpr.Value(); - if (pr->IsPointOnCurve(C,L)) { - Standard_Real p = pr->Parameter(); - Standard_Real res = p;// SVV 4 nov 99 - to avoid warnings on Linux - if (!C.IsNull()) { - // Closed curves RLE 16 june 94 - if (Precision::IsNegativeInfinite(f)) - { - //return pr->Parameter();//p; - U = pr->Parameter(); - return Standard_True; - } - if (Precision::IsPositiveInfinite(l)) - { - //return pr->Parameter();//p; - U = pr->Parameter(); - return Standard_True; - } - gp_Pnt Pf = C->Value(f).Transformed(L.Transformation()); - gp_Pnt Pl = C->Value(l).Transformed(L.Transformation()); - Standard_Real tol = BRep_Tool::Tolerance(V); - if (Pf.Distance(Pl) < tol) { - if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) { - if (V.Orientation() == TopAbs_FORWARD) res = f;//p = f; - else res = l;//p = l; - } - } - } - //return res;//p; - U = res; - return Standard_True; - } - itpr.Next(); - } - } - else { - // no 3d curve !! - // let us try with the first pcurve - Handle(Geom2d_Curve) PC; - Handle(Geom_Surface) S; - BRep_Tool::CurveOnSurface(E,PC,S,L,f,l); - L = L.Predivided(V.Location()); - BRep_ListIteratorOfListOfPointRepresentation itpr - ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points()); - - while (itpr.More()) { - const Handle(BRep_PointRepresentation)& pr = itpr.Value(); - if (pr->IsPointOnCurveOnSurface(PC,S,L)) { - Standard_Real p = pr->Parameter(); - // Closed curves RLE 16 june 94 - if (PC->IsClosed()) { - if ((p == PC->FirstParameter()) || - (p == PC->LastParameter())) { - if (V.Orientation() == TopAbs_FORWARD) p = PC->FirstParameter(); - else p = PC->LastParameter(); - } - } - //return p; - U = p; - return Standard_True; - } - itpr.Next(); - } - } - } - - //Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge"); - return Standard_False; -} //======================================================================= -//function : GetEdgePoints -//purpose : gets the first, last and middle points of the edge +// static methods //======================================================================= -static void GetEdgePoints(const TopoDS_Edge& anEdge, - const TopoDS_Face& aFace, - gp_Pnt& fPnt, gp_Pnt& mPnt, - gp_Pnt& lPnt) -{ - Standard_Real f, l; - Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( anEdge, aFace, f, l ); - gp_Pnt2d fPnt2d = theCurve->Value(f); - gp_Pnt2d lPnt2d = theCurve->Value(l); - gp_Pnt2d mPnt2d = theCurve->Value(0.5*(f + l)); - Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); - fPnt = aSurf->Value(fPnt2d.X(),fPnt2d.Y()); - lPnt = aSurf->Value(lPnt2d.X(),lPnt2d.Y()); - mPnt = aSurf->Value(mPnt2d.X(), mPnt2d.Y()); -} +static + void UpdateTolerance(TopoDS_Shape& myShape, + const TopTools_IndexedMapOfShape& myFaces); + +static + Standard_Boolean FindParameter(const TopoDS_Vertex& V, + const TopoDS_Edge& E, + Standard_Real& U); + +static + void GetEdgePoints(const TopoDS_Edge& anEdge, + const TopoDS_Face& aFace, + gp_Pnt& fPnt, gp_Pnt& mPnt, + gp_Pnt& lPnt); + +static + void FillContours(const TopoDS_Shape& aShape, + const BRepOffset_Analyse& Analyser, + TopTools_DataMapOfShapeListOfShape& Contours, + TopTools_DataMapOfShapeShape& MapEF); + +static + void RemoveCorks(TopoDS_Shape& S, + TopTools_IndexedMapOfShape& Faces); + +static + Standard_Boolean IsConnectedShell(const TopoDS_Shape& S); + +static + void MakeList(TopTools_ListOfShape& OffsetFaces, + const BRepAlgo_Image& myInitOffsetFace, + const TopTools_IndexedMapOfShape& myFaces); + +static + void EvalMax(const TopoDS_Shape& S, + Standard_Real& Tol); + +static + void TrimEdge(TopoDS_Edge& NE, + const Handle(BRepAlgo_AsDes)& AsDes2d, + Handle(BRepAlgo_AsDes)& AsDes); + +static + void CorrectSolid(TopoDS_Solid& theSol, + TopTools_ListOfShape& theSolList); + +static + void SortFaces(const TopTools_ListOfShape& theLIm, + TopTools_ListOfShape& theLFImages, + const Standard_Boolean bKeepFirst); + +static + Standard_Boolean FindShape(const TopoDS_Shape& theSWhat, + const TopoDS_Shape& theSWhere, + TopoDS_Shape& theRes); + +static + void UpdateOrigins(TopTools_IndexedDataMapOfShapeListOfShape& theOrigins, + BOPAlgo_Builder& theGF); + +static + Standard_Boolean IsMicroEdge(const TopoDS_Edge& theEdge, + const Handle(IntTools_Context)& theCtx); + +static + Standard_Boolean ComputeBiNormal(const TopoDS_Face& theF, + const TopoDS_Edge& theE, + gp_Dir& theDB); +static + Standard_Boolean CheckBiNormals(const TopoDS_Face& aFIm, + const TopoDS_Face& aFOr, + const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins, + const TopTools_MapOfShape& theMFence, + Standard_Boolean& bKeep, + Standard_Boolean& bRem, + const Standard_Boolean RemoveInvalidFaces); + +static + void CheckBiNormals(TopTools_ListOfShape& theLFImages, + const TopoDS_Face& theF, + const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins, + TopTools_ListOfShape& theLFKeep, + const Standard_Boolean RemoveInvalidFaces); + +static + Standard_Boolean CheckNormals(const TopoDS_Face& theFIm, + const TopoDS_Face& theFOr); + +static + void UpdateInitOffset(BRepAlgo_Image& myInitOffset, + BRepAlgo_Image& myImageOffset, + const TopoDS_Shape& myOffsetShape, + const TopAbs_ShapeEnum &theShapeType); + +static + void RemoveShapes(TopoDS_Shape& theS, + const TopTools_ListOfShape& theLS); //======================================================================= -//function : FillContours -//purpose : fills free boundary contours and faces connected (MapEF) -//======================================================================= -static void FillContours(const TopoDS_Shape& aShape, - const BRepOffset_Analyse& Analyser, - TopTools_DataMapOfShapeListOfShape& Contours, - TopTools_DataMapOfShapeShape& MapEF) -{ - TopTools_ListOfShape Edges; - - TopExp_Explorer Explo(aShape, TopAbs_FACE); - BRepTools_WireExplorer Wexp; - - for (; Explo.More(); Explo.Next()) - { - TopoDS_Face aFace = TopoDS::Face(Explo.Current()); - TopoDS_Iterator itf(aFace); - for (; itf.More(); itf.Next()) - { - TopoDS_Wire aWire = TopoDS::Wire(itf.Value()); - for (Wexp.Init(aWire, aFace); Wexp.More(); Wexp.Next()) - { - TopoDS_Edge anEdge = Wexp.Current(); - if (BRep_Tool::Degenerated(anEdge)) - continue; - const BRepOffset_ListOfInterval& Lint = Analyser.Type(anEdge); - if (!Lint.IsEmpty() && Lint.First().Type() == BRepOffset_FreeBoundary) - { - MapEF.Bind(anEdge, aFace); - Edges.Append(anEdge); - } - } - } - } - - TopTools_ListIteratorOfListOfShape itl; - while (!Edges.IsEmpty()) - { - TopoDS_Edge StartEdge = TopoDS::Edge(Edges.First()); - Edges.RemoveFirst(); - TopoDS_Vertex StartVertex, CurVertex; - TopExp::Vertices(StartEdge, StartVertex, CurVertex, Standard_True); - TopTools_ListOfShape aContour; - aContour.Append(StartEdge); - while (!CurVertex.IsSame(StartVertex)) - for (itl.Initialize(Edges); itl.More(); itl.Next()) - { - TopoDS_Edge anEdge = TopoDS::Edge(itl.Value()); - TopoDS_Vertex V1, V2; - TopExp::Vertices(anEdge, V1, V2); - if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex)) - { - aContour.Append(anEdge); - CurVertex = (V1.IsSame(CurVertex))? V2 : V1; - Edges.Remove(itl); - break; - } - } - Contours.Bind(StartVertex, aContour); - } -} -// -//----------------------------------------------------------------------- -// //======================================================================= //function : BRepOffset_MakeOffset //purpose : //======================================================================= - BRepOffset_MakeOffset::BRepOffset_MakeOffset() { myAsDes = new BRepAlgo_AsDes(); } - //======================================================================= //function : BRepOffset_MakeOffset //purpose : //======================================================================= - BRepOffset_MakeOffset::BRepOffset_MakeOffset(const TopoDS_Shape& S, - const Standard_Real Offset, - const Standard_Real Tol, - const BRepOffset_Mode Mode, - const Standard_Boolean Inter, - const Standard_Boolean SelfInter, - const GeomAbs_JoinType Join, - const Standard_Boolean Thickening) + const Standard_Real Offset, + const Standard_Real Tol, + const BRepOffset_Mode Mode, + const Standard_Boolean Inter, + const Standard_Boolean SelfInter, + const GeomAbs_JoinType Join, + const Standard_Boolean RemoveIntEdges, + const Standard_Boolean Thickening, + const Standard_Boolean RemInvFaces) : -myOffset (Offset), -myTol (Tol), -myShape (S), -myMode (Mode), -myInter (Inter), -mySelfInter (SelfInter), -myJoin (Join), -myThickening (Thickening), -myDone (Standard_False) +myOffset (Offset), +myTol (Tol), +myShape (S), +myMode (Mode), +myInter (Inter), +mySelfInter (SelfInter), +myJoin (Join), +myRemoveIntEdges(RemoveIntEdges), +myThickening (Thickening), +myRemoveInvalidFaces(RemInvFaces), +myDone (Standard_False) { myAsDes = new BRepAlgo_AsDes(); MakeOffsetShape(); } - //======================================================================= //function : Initialize //purpose : //======================================================================= - void BRepOffset_MakeOffset::Initialize(const TopoDS_Shape& S, - const Standard_Real Offset, - const Standard_Real Tol, - const BRepOffset_Mode Mode, - const Standard_Boolean Inter, - const Standard_Boolean SelfInter, - const GeomAbs_JoinType Join, - const Standard_Boolean Thickening) + const Standard_Real Offset, + const Standard_Real Tol, + const BRepOffset_Mode Mode, + const Standard_Boolean Inter, + const Standard_Boolean SelfInter, + const GeomAbs_JoinType Join, + const Standard_Boolean RemoveIntEdges, + const Standard_Boolean Thickening, + const Standard_Boolean RemInvFaces) { - myOffset = Offset; - myShape = S; - myTol = Tol; - myMode = Mode; - myInter = Inter; - mySelfInter = SelfInter; - myJoin = Join; - myThickening = Thickening; - myDone = Standard_False; + myOffset = Offset; + myShape = S; + myTol = Tol; + myMode = Mode; + myInter = Inter; + mySelfInter = SelfInter; + myJoin = Join; + myRemoveIntEdges = RemoveIntEdges; + myThickening = Thickening; + myRemoveInvalidFaces = RemInvFaces; + myDone = Standard_False; myIsPerformSewing = Standard_False; Clear(); } - //======================================================================= //function : Clear //purpose : //======================================================================= - void BRepOffset_MakeOffset::Clear() { myOffsetShape.Nullify(); @@ -560,7 +460,6 @@ void BRepOffset_MakeOffset::Clear() //function : AddFace //purpose : //======================================================================= - void BRepOffset_MakeOffset::AddFace(const TopoDS_Face& F) { myFaces.Add(F); //------------- @@ -575,124 +474,33 @@ void BRepOffset_MakeOffset::AddFace(const TopoDS_Face& F) { //function : SetOffsetOnFace //purpose : //======================================================================= - void BRepOffset_MakeOffset::SetOffsetOnFace(const TopoDS_Face& F, - const Standard_Real Off) + const Standard_Real Off) { if ( myFaceOffset.IsBound(F)) myFaceOffset.UnBind(F); myFaceOffset.Bind(F,Off); } -//======================================================================= -//function : RemoveCorks -//purpose : -//======================================================================= - -static void RemoveCorks (TopoDS_Shape& S, - TopTools_IndexedMapOfShape& Faces) -{ - TopoDS_Compound SS; - BRep_Builder B; - B.MakeCompound (SS); - //----------------------------------------------------- - // Construction of a shape without caps. - // and Orientation of caps as in shape S. - //----------------------------------------------------- - TopExp_Explorer exp(S,TopAbs_FACE); - for (; exp.More(); exp.Next()) { - const TopoDS_Shape& Cork = exp.Current(); - if (!Faces.Contains(Cork)) { - B.Add(SS,Cork); - } - else { - //Faces.Remove (Cork); - //begin instead of Remove// - TopoDS_Shape LastShape = Faces(Faces.Extent()); - Faces.RemoveLast(); - if (Faces.FindIndex(Cork) != 0) - Faces.Substitute(Faces.FindIndex(Cork), LastShape); - //end instead of Remove // - Faces.Add(Cork); // to reset it with proper orientation. - } - } - S = SS; -#ifdef DRAW - if ( AffichOffC) - DBRep::Set("myInit", SS); -#endif - -} - -static Standard_Boolean IsConnectedShell( const TopoDS_Shape& S ) -{ - BRepTools_Quilt Glue; - Glue.Add( S ); - - TopoDS_Shape SS = Glue.Shells(); - TopExp_Explorer Explo( SS, TopAbs_SHELL ); - Explo.Next(); - if (Explo.More()) - return Standard_False; - - return Standard_True; -} - - -//======================================================================= -//function : MakeList -//purpose : -//======================================================================= - -static void MakeList (TopTools_ListOfShape& OffsetFaces, - const BRepAlgo_Image& myInitOffsetFace, - const TopTools_IndexedMapOfShape& myFaces) -{ - TopTools_ListIteratorOfListOfShape itLOF(myInitOffsetFace.Roots()); - for ( ; itLOF.More(); itLOF.Next()) { - const TopoDS_Shape& Root = itLOF.Value(); - if (!myFaces.Contains(Root)) - OffsetFaces.Append(myInitOffsetFace.Image(Root).First()); - } -} - -//======================================================================= -//function : EvalMax -//purpose : -//======================================================================= - -static void EvalMax(const TopoDS_Shape& S, Standard_Real& Tol) -{ - TopExp_Explorer exp; - for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) { - const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current()); - Standard_Real TolV = BRep_Tool::Tolerance(V); - if (TolV > Tol) Tol = TolV; - } -} - - //======================================================================= //function : MakeOffsetShape //purpose : //======================================================================= - void BRepOffset_MakeOffset::MakeOffsetShape() { - myDone = Standard_False; + myDone = Standard_False; //------------------------------------------ // Construction of myShape without caps. //------------------------------------------ - if(!myFaces.IsEmpty()) - { + if(!myFaces.IsEmpty()) { RemoveCorks (myShape,myFaces); } - + if (!CheckInputData()) { // There is error in input data. // Check Error() method. - return; - } + return; + } TopAbs_State Side = TopAbs_IN; if (myOffset < 0.) Side = TopAbs_OUT; @@ -731,7 +539,7 @@ void BRepOffset_MakeOffset::MakeOffsetShape() //----------------- TopTools_IndexedMapOfShape& Modif = Inter.TouchedFaces(); TopTools_IndexedMapOfShape& NewEdges = Inter.NewEdges(); - + if (!Modif.IsEmpty()) Intersection2D (Modif,NewEdges); //------------------------------------------------------- // Unwinding 2D and reconstruction of modified faces @@ -742,7 +550,7 @@ void BRepOffset_MakeOffset::MakeOffsetShape() // reconstructed edges //------------------------------------------------------ if (!Modif.IsEmpty()) MakeFaces (Modif); - + // if (myThickening) MakeMissingWalls(); @@ -755,6 +563,12 @@ void BRepOffset_MakeOffset::MakeOffsetShape() //-------------- SelectShells (); //---------------------------------- + // Remove INTERNAL edges if necessary + //---------------------------------- + if (myRemoveIntEdges) { + RemoveInternalEdges(); + } + //---------------------------------- // Coding of regularities. //---------------------------------- EncodeRegularity(); @@ -784,13 +598,10 @@ void BRepOffset_MakeOffset::MakeOffsetShape() myDone = Standard_True; } - - //======================================================================= //function : MakeThickSolid //purpose : //======================================================================= - void BRepOffset_MakeOffset::MakeThickSolid() { //-------------------------------------------------------------- @@ -872,7 +683,6 @@ void BRepOffset_MakeOffset::MakeThickSolid() //function : IsDone //purpose : //======================================================================= - Standard_Boolean BRepOffset_MakeOffset::IsDone() const { return myDone; @@ -882,7 +692,6 @@ Standard_Boolean BRepOffset_MakeOffset::IsDone() const //function : Error //purpose : //======================================================================= - BRepOffset_Error BRepOffset_MakeOffset::Error() const { return myError; @@ -892,78 +701,11 @@ BRepOffset_Error BRepOffset_MakeOffset::Error() const //function : Shape //purpose : //======================================================================= - const TopoDS_Shape& BRepOffset_MakeOffset::Shape() const { return myOffsetShape; } -//======================================================================= -//function : TrimEdge -//purpose : Trim the edge of the largest of descendants in AsDes2d. -// Order in AsDes two vertices that have trimmed the edge. -//======================================================================= - -static void TrimEdge (TopoDS_Edge& NE, - const Handle(BRepAlgo_AsDes)& AsDes2d, - Handle(BRepAlgo_AsDes)& AsDes) -{ - Standard_Real aSameParTol = Precision::Confusion(); - - TopoDS_Vertex V1,V2; - Standard_Real U = 0.; - Standard_Real UMin = Precision::Infinite(); - Standard_Real UMax = -UMin; - - const TopTools_ListOfShape& LE = AsDes2d->Descendant(NE); - - if (LE.Extent() > 1) { - TopTools_ListIteratorOfListOfShape it (LE); - for (; it.More(); it.Next()) { - TopoDS_Vertex V = TopoDS::Vertex(it.Value()); - if (NE.Orientation() == TopAbs_REVERSED) - V.Reverse(); - //V.Orientation(TopAbs_INTERNAL); - if (!FindParameter(V, NE, U)) - { - Standard_Real f, l; - Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l); - gp_Pnt thePoint = BRep_Tool::Pnt(V); - GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve); - if (Projector.NbPoints() == 0) - Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge no projection"); - U = Projector.LowerDistanceParameter(); - } - if (U < UMin) { - UMin = U; V1 = V; - } - if (U > UMax) { - UMax = U; V2 = V; - } - } - if (V1.IsNull() || V2.IsNull()) { - Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge"); - } - if (!V1.IsSame(V2)) { - NE.Free( Standard_True ); - BRep_Builder B; - TopAbs_Orientation Or = NE.Orientation(); - NE.Orientation(TopAbs_FORWARD); - TopoDS_Vertex VF,VL; - TopExp::Vertices (NE,VF,VL); - B.Remove(NE,VF); - B.Remove(NE,VL); - B.Add (NE,V1.Oriented(TopAbs_FORWARD)); - B.Add (NE,V2.Oriented(TopAbs_REVERSED)); - B.Range(NE,UMin,UMax); - NE.Orientation(Or); - AsDes->Add(NE,V1.Oriented(TopAbs_FORWARD)); - AsDes->Add(NE,V2.Oriented(TopAbs_REVERSED)); - BRepLib::SameParameter(NE, aSameParTol, Standard_True); - } - } -} - //======================================================================= //function : BuildOffsetByInter //purpose : @@ -1003,27 +745,27 @@ void BRepOffset_MakeOffset::BuildOffsetByInter() for ( ; itl.More(); itl.Next()) { const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value()); if ( !ShapeTgt.IsBound(Cur)) { - TopoDS_Shape aLocalShape = OF.Generated(Cur); - const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape); -// const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur)); - ShapeTgt.Bind(Cur,OF.Generated(Cur)); - TopoDS_Vertex V1,V2,OV1,OV2; - TopExp::Vertices (Cur,V1,V2); - TopExp::Vertices (OTE,OV1,OV2); - TopTools_ListOfShape LE; - if (!ShapeTgt.IsBound(V1)) { - myAnalyse.Edges(V1,BRepOffset_Tangent,LE); - const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1); - if (LE.Extent() == LA.Extent()) - ShapeTgt.Bind(V1,OV1); - } - if (!ShapeTgt.IsBound(V2)) { - LE.Clear(); - myAnalyse.Edges(V2,BRepOffset_Tangent,LE); - const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2); - if (LE.Extent() == LA.Extent()) - ShapeTgt.Bind(V2,OV2); - } + TopoDS_Shape aLocalShape = OF.Generated(Cur); + const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape); +// const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur)); + ShapeTgt.Bind(Cur,OF.Generated(Cur)); + TopoDS_Vertex V1,V2,OV1,OV2; + TopExp::Vertices (Cur,V1,V2); + TopExp::Vertices (OTE,OV1,OV2); + TopTools_ListOfShape LE; + if (!ShapeTgt.IsBound(V1)) { + myAnalyse.Edges(V1,BRepOffset_Tangent,LE); + const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1); + if (LE.Extent() == LA.Extent()) + ShapeTgt.Bind(V1,OV1); + } + if (!ShapeTgt.IsBound(V2)) { + LE.Clear(); + myAnalyse.Edges(V2,BRepOffset_Tangent,LE); + const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2); + if (LE.Extent() == LA.Extent()) + ShapeTgt.Bind(V2,OV2); + } } } MapSF.Bind(F,OF); @@ -1056,12 +798,11 @@ void BRepOffset_MakeOffset::BuildOffsetByInter() // Extension of neighbor edges of new edges and intersection between neighbors. //-------------------------------------------------------------------------------- Handle(BRepAlgo_AsDes) AsDes2d = new BRepAlgo_AsDes(); - for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) - { + for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) { const TopoDS_Face& FI = TopoDS::Face(Exp.Current()); Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(FI); BRepOffset_Inter2d::ConnexIntByInt (FI, MapSF(FI), MES, Build, - AsDes2d, myOffset, aCurrFaceTol); + AsDes, AsDes2d, myOffset, aCurrFaceTol); } //----------------------------------------------------------- // Great restriction of new edges and update of AsDes. @@ -1071,53 +812,100 @@ void BRepOffset_MakeOffset::BuildOffsetByInter() TopoDS_Shape NE; TopoDS_Edge TNE; TopoDS_Face NF; + TopTools_IndexedDataMapOfShapeListOfShape anOrigins; for (Exp.Init(myShape,TopAbs_FACE) ; Exp.More(); Exp.Next()) { const TopoDS_Face& FI = TopoDS::Face(Exp.Current()); NF = MapSF(FI).Face(); - if (MES.IsBound(NF)) {NF = TopoDS::Face(MES(NF));} + if (MES.IsBound(NF)) { + NF = TopoDS::Face(MES(NF)); + } + // TopTools_MapOfShape View; - for (Exp2.Init(FI.Oriented(TopAbs_FORWARD),TopAbs_EDGE); Exp2.More(); Exp2.Next()) { - const TopoDS_Edge& EI = TopoDS::Edge(Exp2.Current()); - if (View.Add(EI)) { - if (Build.IsBound(EI)) { - NE = Build(EI); - if (NE.ShapeType() == TopAbs_EDGE) { - if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);} - } - else { - //------------------------------------------------------------ - // The Intersections are on several edges. - // The pieces without intersections with neighbors - // are removed from AsDes. - //------------------------------------------------------------ - for (ExpC.Init(NE,TopAbs_EDGE); ExpC.More(); ExpC.Next()) { - if (NewEdges.Add(ExpC.Current())) { - TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current()); - NEC.Free(Standard_True); - if (!AsDes2d->Descendant(NEC).IsEmpty()) { - TrimEdge (NEC,AsDes2d,AsDes); - } - else { - AsDes->Remove(NEC); - } - } - } - } - } - else { - NE = MapSF(FI).Generated(EI); - //// modified by jgv, 19.12.03 for OCC4455 //// - NE.Orientation( EI.Orientation() ); - /////////////////////////////////////////////// - if (MES.IsBound(NE)) { - NE = MES(NE); - NE.Orientation(EI.Orientation()); - if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);} - } - AsDes->Add(NF,NE); - } + TopTools_IndexedMapOfShape VEmap; + Standard_Integer i, aNb; + // + TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_EDGE , VEmap); + TopExp::MapShapes(FI.Oriented(TopAbs_FORWARD), TopAbs_VERTEX, VEmap); + // + aNb = VEmap.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopoDS_Shape& aS = VEmap(i); + if (!View.Add(aS)) { + continue; } + // + if (Build.IsBound(aS)) { + NE = Build(aS); + if (NE.ShapeType() == TopAbs_EDGE) { + if (anOrigins.Contains(NE)) { + anOrigins.ChangeFromKey(NE).Append(aS); + } + else { + TopTools_ListOfShape aLSx; + aLSx.Append(aS); + anOrigins.Add(NE, aLSx); + } + // + if (NewEdges.Add(NE)) { + TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes); + } + } + else { + //------------------------------------------------------------ + // The Intersections are on several edges. + // The pieces without intersections with neighbors + // are removed from AsDes. + //------------------------------------------------------------ + for (ExpC.Init(NE,TopAbs_EDGE); ExpC.More(); ExpC.Next()) { + TopoDS_Edge NEC = TopoDS::Edge(ExpC.Current()); + if (NewEdges.Add(NEC)) { + NEC.Free(Standard_True); + if (anOrigins.Contains(NEC)) { + anOrigins.ChangeFromKey(NEC).Append(aS); + } + else { + TopTools_ListOfShape aLSx; + aLSx.Append(aS); + anOrigins.Add(NEC, aLSx); + } + // + if (!AsDes2d->Descendant(NEC).IsEmpty()) { + TrimEdge (NEC,AsDes2d,AsDes); + } + else { + if (AsDes->HasAscendant(NEC)) { + AsDes->Remove(NEC); + } + } + } + } + } + } + else { + if (aS.ShapeType() != TopAbs_EDGE) { + continue; + } + // + NE = MapSF(FI).Generated(aS); + //// modified by jgv, 19.12.03 for OCC4455 //// + NE.Orientation(aS.Orientation()); + if (anOrigins.Contains(NE)) { + anOrigins.ChangeFromKey(NE).Append(aS); + } + else { + TopTools_ListOfShape aLSx; + aLSx.Append(aS); + anOrigins.Add(NE, aLSx); + } + // + if (MES.IsBound(NE)) { + NE = MES(NE); + NE.Orientation(aS.Orientation()); + if (NewEdges.Add(NE)) {TrimEdge (TopoDS::Edge(NE),AsDes2d,AsDes);} + } + AsDes->Add(NF,NE); + } } } @@ -1133,12 +921,20 @@ void BRepOffset_MakeOffset::BuildOffsetByInter() const TopoDS_Face& NF = TopoDS::Face(MES(OFI)); LFE.Append(NF); IMOE.SetRoot(NF); + // + if (anOrigins.Contains(NF)) { + anOrigins.ChangeFromKey(NF).Append(FI); + } + else { + TopTools_ListOfShape aLSx; + aLSx.Append(FI); + anOrigins.Add(NF, aLSx); + } } } TopTools_ListIteratorOfListOfShape itLFE(LFE); - for (; itLFE.More(); itLFE.Next()) - { + for (; itLFE.More(); itLFE.Next()) { const TopoDS_Face& NEF = TopoDS::Face(itLFE.Value()); Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(NEF); BRepOffset_Inter2d::Compute(AsDes, NEF, NewEdges, aCurrFaceTol); @@ -1147,8 +943,7 @@ void BRepOffset_MakeOffset::BuildOffsetByInter() // Intersections 2d on caps. //---------------------------------------------- Standard_Integer i; - for (i = 1; i <= myFaces.Extent(); i++) - { + for (i = 1; i <= myFaces.Extent(); i++) { const TopoDS_Face& Cork = TopoDS::Face(myFaces(i)); Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(Cork); BRepOffset_Inter2d::Compute(AsDes, Cork, NewEdges, aCurrFaceTol); @@ -1157,8 +952,18 @@ void BRepOffset_MakeOffset::BuildOffsetByInter() //------------------------------- // Unwinding of extended Faces. //------------------------------- - myMakeLoops.Build(LFE ,AsDes,IMOE); - + // + if ((myJoin == GeomAbs_Intersection) && myInter) { + TopTools_ListOfShape aLFailed; + BuildSplitsOfFaces(LFE, AsDes, anOrigins, IMOE, aLFailed, Standard_False); + if (aLFailed.Extent()) { + myMakeLoops.Build(aLFailed, AsDes, IMOE); + } + } + else { + myMakeLoops.Build(LFE, AsDes, IMOE); + } + // #ifdef OCCT_DEBUG TopTools_IndexedMapOfShape COES; #endif @@ -1172,91 +977,91 @@ void BRepOffset_MakeOffset::BuildOffsetByInter() if (MES.IsBound(OF)) { OF = TopoDS::Face(MES(OF)); if (IMOE.HasImage(OF)) { - const TopTools_ListOfShape& LOFE = IMOE.Image(OF); - myInitOffsetFace.Bind(FI,LOFE); - for (itLF.Initialize(LOFE); itLF.More(); itLF.Next()) { - const TopoDS_Shape& OFE = itLF.Value(); - myImageOffset.SetRoot(OFE); + const TopTools_ListOfShape& LOFE = IMOE.Image(OF); + myInitOffsetFace.Bind(FI,LOFE); + for (itLF.Initialize(LOFE); itLF.More(); itLF.Next()) { + const TopoDS_Shape& OFE = itLF.Value(); + myImageOffset.SetRoot(OFE); #ifdef DRAW - if (AffichInt2d) { - sprintf(name,"AF_%d",NbAF++); - DBRep::Set(name,OFE); - } + if (AffichInt2d) { + sprintf(name,"AF_%d",NbAF++); + DBRep::Set(name,OFE); + } #endif - TopTools_MapOfShape View; - for (Exp2.Init(OFE.Oriented(TopAbs_FORWARD),TopAbs_EDGE); - Exp2.More(); Exp2.Next()) { - const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current()); - - myAsDes->Add (OFE,COE); + TopTools_MapOfShape View; + for (Exp2.Init(OFE.Oriented(TopAbs_FORWARD),TopAbs_EDGE); + Exp2.More(); Exp2.Next()) { + const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current()); + + myAsDes->Add (OFE,COE); #ifdef DRAW - if (AffichInt2d) { - sprintf(name,"AE_%d",NbAE++); - DBRep::Set(name,COE); - COES.Add(COE); - } + if (AffichInt2d) { + sprintf(name,"AE_%d",NbAE++); + DBRep::Set(name,COE); + COES.Add(COE); + } #endif - if (View.Add(COE)){ - if (!myAsDes->HasDescendant(COE)) { - TopoDS_Vertex CV1,CV2; - TopExp::Vertices(COE,CV1,CV2); - if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD)); - if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED)); - } - } - } - } + if (View.Add(COE)){ + if (!myAsDes->HasDescendant(COE)) { + TopoDS_Vertex CV1,CV2; + TopExp::Vertices(COE,CV1,CV2); + if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD)); + if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED)); + } + } + } + } } else { - myInitOffsetFace.Bind(FI,OF); - myImageOffset.SetRoot(OF); + /*myInitOffsetFace.Bind(FI,OF); + myImageOffset.SetRoot(OF); #ifdef DRAW - if (AffichInt2d) { - sprintf(name,"AF_%d",NbAF++); - DBRep::Set(name,OF); - } + if (AffichInt2d) { + sprintf(name,"AF_%d",NbAF++); + DBRep::Set(name,OF); + } #endif - const TopTools_ListOfShape& LE = AsDes->Descendant(OF); - for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) { - const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value()); - if (IMOE.HasImage(OE)) { - const TopTools_ListOfShape& LOE = IMOE.Image(OE); - TopTools_ListIteratorOfListOfShape itLOE(LOE); - for (; itLOE.More(); itLOE.Next()) { - TopoDS_Shape aLocalShape = itLOE.Value().Oriented(OE.Orientation()); - const TopoDS_Edge& COE = TopoDS::Edge(aLocalShape); -// const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value().Oriented(OE.Orientation())); - myAsDes->Add(OF,COE); + const TopTools_ListOfShape& LE = AsDes->Descendant(OF); + for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) { + const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value()); + if (IMOE.HasImage(OE)) { + const TopTools_ListOfShape& LOE = IMOE.Image(OE); + TopTools_ListIteratorOfListOfShape itLOE(LOE); + for (; itLOE.More(); itLOE.Next()) { + TopoDS_Shape aLocalShape = itLOE.Value().Oriented(OE.Orientation()); + const TopoDS_Edge& COE = TopoDS::Edge(aLocalShape); +// const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value().Oriented(OE.Orientation())); + myAsDes->Add(OF,COE); #ifdef DRAW - if (AffichInt2d) { - sprintf(name,"AE_%d",NbAE++); - DBRep::Set(name,COE); - COES.Add(COE); - } + if (AffichInt2d) { + sprintf(name,"AE_%d",NbAE++); + DBRep::Set(name,COE); + COES.Add(COE); + } #endif - - if (!myAsDes->HasDescendant(COE)) { - TopoDS_Vertex CV1,CV2; - TopExp::Vertices(COE,CV1,CV2); - if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD)); - if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED)); - } - } - } - else { - myAsDes->Add(OF,OE); + + if (!myAsDes->HasDescendant(COE)) { + TopoDS_Vertex CV1,CV2; + TopExp::Vertices(COE,CV1,CV2); + if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD)); + if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED)); + } + } + } + else { + myAsDes->Add(OF,OE); #ifdef DRAW - if (AffichInt2d) { - sprintf(name,"AE_%d",NbAE++); - DBRep::Set(name,OE); - COES.Add(OE); - } + if (AffichInt2d) { + sprintf(name,"AE_%d",NbAE++); + DBRep::Set(name,OE); + COES.Add(OE); + } #endif - const TopTools_ListOfShape& LV = AsDes->Descendant(OE); - myAsDes->Add(OE,LV); - } - } + const TopTools_ListOfShape& LV = AsDes->Descendant(OE); + myAsDes->Add(OE,LV); + } + }*/ } } else { @@ -1264,26 +1069,26 @@ void BRepOffset_MakeOffset::BuildOffsetByInter() myImageOffset.SetRoot(OF); TopTools_MapOfShape View; for (Exp2.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); - Exp2.More(); Exp2.Next()) { + Exp2.More(); Exp2.Next()) { - const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current()); - myAsDes->Add (OF,COE); + const TopoDS_Edge& COE = TopoDS::Edge(Exp2.Current()); + myAsDes->Add (OF,COE); #ifdef DRAW - if (AffichInt2d) { - sprintf(name,"AE_%d",NbAE++); - DBRep::Set(name,COE); - COES.Add(COE); - } + if (AffichInt2d) { + sprintf(name,"AE_%d",NbAE++); + DBRep::Set(name,COE); + COES.Add(COE); + } #endif - - if (View.Add(Exp2.Current())) { - if (!myAsDes->HasDescendant(COE)) { - TopoDS_Vertex CV1,CV2; - TopExp::Vertices(COE,CV1,CV2); - if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD)); - if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED)); - } - } + + if (View.Add(Exp2.Current())) { + if (!myAsDes->HasDescendant(COE)) { + TopoDS_Vertex CV1,CV2; + TopExp::Vertices(COE,CV1,CV2); + if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD)); + if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED)); + } + } } } } @@ -1300,49 +1105,49 @@ void BRepOffset_MakeOffset::BuildOffsetByInter() const TopoDS_Shape& anEdgeRef = Exp2.Current(); if (aMapEdges.Add(anEdgeRef)) { - myInitOffsetEdge.SetRoot(anEdgeRef); - if (Build.IsBound(anEdgeRef)) { - TopoDS_Shape aNewShape = Build(anEdgeRef); - - if (aNewShape.ShapeType() == TopAbs_EDGE) { - if (IMOE.HasImage(aNewShape)) { - const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewShape); - - myInitOffsetEdge.Bind (anEdgeRef, aListNewE); - } else - myInitOffsetEdge.Bind (anEdgeRef, aNewShape); - } else { // aNewShape != TopAbs_EDGE - TopTools_ListOfShape aListNewEdge; - - for (ExpC.Init(aNewShape, TopAbs_EDGE); ExpC.More(); ExpC.Next()) { - const TopoDS_Shape &aResEdge = ExpC.Current(); - - if (IMOE.HasImage(aResEdge)) { - const TopTools_ListOfShape& aListNewE = IMOE.Image(aResEdge); - TopTools_ListIteratorOfListOfShape aNewEIter(aListNewE); - - for (; aNewEIter.More(); aNewEIter.Next()) - aListNewEdge.Append(aNewEIter.Value()); - } else - aListNewEdge.Append(aResEdge); - } - - myInitOffsetEdge.Bind (anEdgeRef, aListNewEdge); - } - } - else { // Free boundary. - TopoDS_Shape aNewEdge = MapSF(aFaceRef).Generated(anEdgeRef); + myInitOffsetEdge.SetRoot(anEdgeRef); + if (Build.IsBound(anEdgeRef)) { + TopoDS_Shape aNewShape = Build(anEdgeRef); + + if (aNewShape.ShapeType() == TopAbs_EDGE) { + if (IMOE.HasImage(aNewShape)) { + const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewShape); + + myInitOffsetEdge.Bind (anEdgeRef, aListNewE); + } else + myInitOffsetEdge.Bind (anEdgeRef, aNewShape); + } else { // aNewShape != TopAbs_EDGE + TopTools_ListOfShape aListNewEdge; + + for (ExpC.Init(aNewShape, TopAbs_EDGE); ExpC.More(); ExpC.Next()) { + const TopoDS_Shape &aResEdge = ExpC.Current(); + + if (IMOE.HasImage(aResEdge)) { + const TopTools_ListOfShape& aListNewE = IMOE.Image(aResEdge); + TopTools_ListIteratorOfListOfShape aNewEIter(aListNewE); + + for (; aNewEIter.More(); aNewEIter.Next()) + aListNewEdge.Append(aNewEIter.Value()); + } else + aListNewEdge.Append(aResEdge); + } + + myInitOffsetEdge.Bind (anEdgeRef, aListNewEdge); + } + } + else { // Free boundary. + TopoDS_Shape aNewEdge = MapSF(aFaceRef).Generated(anEdgeRef); - if (MES.IsBound(aNewEdge)) - aNewEdge = MES(aNewEdge); + if (MES.IsBound(aNewEdge)) + aNewEdge = MES(aNewEdge); - if (IMOE.HasImage(aNewEdge)) { - const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewEdge); + if (IMOE.HasImage(aNewEdge)) { + const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewEdge); - myInitOffsetEdge.Bind (anEdgeRef, aListNewE); - } else - myInitOffsetEdge.Bind (anEdgeRef, aNewEdge); - } + myInitOffsetEdge.Bind (anEdgeRef, aListNewE); + } else + myInitOffsetEdge.Bind (anEdgeRef, aNewEdge); + } } } } @@ -1358,38 +1163,38 @@ void BRepOffset_MakeOffset::BuildOffsetByInter() for (itLF.Initialize(LE) ; itLF.More(); itLF.Next()) { const TopoDS_Edge& OE = TopoDS::Edge(itLF.Value()); if (IMOE.HasImage(OE)) { - const TopTools_ListOfShape& LOE = IMOE.Image(OE); - TopTools_ListIteratorOfListOfShape itLOE(LOE); - for (; itLOE.More(); itLOE.Next()) { - const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value()); - myAsDes->Add(Cork,COE.Oriented(OE.Orientation())) ; + const TopTools_ListOfShape& LOE = IMOE.Image(OE); + TopTools_ListIteratorOfListOfShape itLOE(LOE); + for (; itLOE.More(); itLOE.Next()) { + const TopoDS_Edge& COE = TopoDS::Edge(itLOE.Value()); + myAsDes->Add(Cork,COE.Oriented(OE.Orientation())) ; #ifdef DRAW - if (AffichInt2d) { - sprintf(name,"AE_%d",NbAE++); - DBRep::Set(name,COE); - COES.Add(COE); - } + if (AffichInt2d) { + sprintf(name,"AE_%d",NbAE++); + DBRep::Set(name,COE); + COES.Add(COE); + } #endif - - if (!myAsDes->HasDescendant(COE)) { - TopoDS_Vertex CV1,CV2; - TopExp::Vertices(COE,CV1,CV2); - if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD)); - if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED)); - } - } + + if (!myAsDes->HasDescendant(COE)) { + TopoDS_Vertex CV1,CV2; + TopExp::Vertices(COE,CV1,CV2); + if (!CV1.IsNull()) myAsDes->Add(COE,CV1.Oriented(TopAbs_FORWARD)); + if (!CV2.IsNull()) myAsDes->Add(COE,CV2.Oriented(TopAbs_REVERSED)); + } + } } else { - myAsDes->Add(Cork,OE); - if (AsDes->HasDescendant(OE)) { - myAsDes->Add(OE,AsDes->Descendant(OE)); - } + myAsDes->Add(Cork,OE); + if (AsDes->HasDescendant(OE)) { + myAsDes->Add(OE,AsDes->Descendant(OE)); + } #ifdef DRAW - if (AffichInt2d) { - sprintf(name,"AE_%d",NbAE++); - DBRep::Set(name,OE); - COES.Add(OE); - } + if (AffichInt2d) { + sprintf(name,"AE_%d",NbAE++); + DBRep::Set(name,OE); + COES.Add(OE); + } #endif } } @@ -1401,6 +1206,322 @@ void BRepOffset_MakeOffset::BuildOffsetByInter() #endif } +//======================================================================= +//function : BuildSplitsOfFaces +//purpose : +//======================================================================= +void BRepOffset_MakeOffset::BuildSplitsOfFaces + (const TopTools_ListOfShape& theLF, + const Handle(BRepAlgo_AsDes)& theAsDes, + TopTools_IndexedDataMapOfShapeListOfShape& theOrigins, + BRepAlgo_Image& theImage, + TopTools_ListOfShape& theLFailed, + const Standard_Boolean bLimited) +{ + BOPCol_ListOfShape aLS; + BOPCol_ListIteratorOfListOfShape aIt; + TopTools_ListIteratorOfListOfShape aItLF, aItLE, aItLE1; + TopTools_DataMapOfShapeListOfShape anEImages; + BRep_Builder aBB; + TopoDS_Compound aFaces; + // + aBB.MakeCompound(aFaces); + // + // firstly it is necessary to fuse all the edges + Handle(IntTools_Context) aCtx = new IntTools_Context(); + // + aItLF.Initialize(theLF); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Shape& aF = aItLF.Value(); + // + const TopTools_ListOfShape& aLE = theAsDes->Descendant(aF); + aItLE.Initialize(aLE); + for (; aItLE.More(); aItLE.Next()) { + const TopoDS_Edge& aE = *(TopoDS_Edge*)&aItLE.Value(); + if (BRep_Tool::Degenerated(aE)) { + continue; + } + // + if (IsMicroEdge(aE, aCtx)) { + continue; + } + // + aLS.Append(aE); + } + } + // + if (aLS.Extent() > 1) { + BOPAlgo_Builder aGFE; + // + aGFE.SetArguments(aLS); + aGFE.Perform(); + if (aGFE.ErrorStatus() == 0) { + // fill map with edges images + aIt.Initialize(aLS); + for (; aIt.More(); aIt.Next()) { + const TopoDS_Shape& aE = aIt.Value(); + // + const TopTools_ListOfShape& aLEIm = aGFE.Modified(aE); + if (aLEIm.Extent()) { + anEImages.Bind(aE, aLEIm); + } + } + // + UpdateOrigins(theOrigins, aGFE); + } + } + // + // now we can split the faces + aItLF.Initialize(theLF); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Face& aF = *(TopoDS_Face*)&aItLF.Value(); + // + // the offset face + aLS.Clear(); + aLS.Append(aF.Oriented(TopAbs_FORWARD)); + // + Standard_Integer iCountE = 0; + TopTools_MapOfShape aMFE; + TopExp_Explorer aExp(aF, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aE = aExp.Current(); + if (anEImages.IsBound(aE)) { + const TopTools_ListOfShape& aLEIm = anEImages.Find(aE); + aItLE.Initialize(aLEIm); + for (; aItLE.More(); aItLE.Next()) { + const TopoDS_Shape& aEIm = aItLE.Value(); + aMFE.Add(aEIm); + } + } + else { + aMFE.Add(aE); + } + } + // + // the edges by which the offset face should be split + const TopTools_ListOfShape& aLE = theAsDes->Descendant(aF); + aItLE.Initialize(aLE); + for (; aItLE.More(); aItLE.Next()) { + const TopoDS_Edge& aE = *(TopoDS_Edge*)&aItLE.Value(); + if (BRep_Tool::Degenerated(aE)) { + continue; + } + // + if (anEImages.IsBound(aE)) { + const TopTools_ListOfShape& aLEIm = anEImages.Find(aE); + aItLE1.Initialize(aLEIm); + for (; aItLE1.More(); aItLE1.Next()) { + const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aItLE1.Value(); + // check for micro edge + if (IsMicroEdge(aEIm, aCtx)) { + continue; + } + // + aLS.Append(aEIm); + if (!aMFE.Contains(aEIm)) { + ++iCountE; + } + } + } + else { + if (IsMicroEdge(aE, aCtx)) { + continue; + } + aLS.Append(aE); + if (!aMFE.Contains(aE)) { + ++iCountE; + } + } + } + // + TopTools_ListOfShape aLFImages; + // + // split the face by the edges + if (!iCountE) { + if (bLimited) { + aLFImages.Append(aF); + theImage.Bind(aF, aLFImages); + aBB.Add(aFaces, aF); + } + continue; + } + // + BOPAlgo_Builder aGF; + // + aGF.SetArguments(aLS); + aGF.Perform(); + if (aGF.ErrorStatus()) { + theLFailed.Append(aF); + continue; + } + // + // splits of the offset shape + aLFImages = aGF.Modified(aF); + if (aLFImages.IsEmpty()) { + theLFailed.Append(aF); + continue; + } + // + TopTools_MapOfShape aME; + // collect images of Edges + aItLE.Initialize(aLE); + for (; aItLE.More(); aItLE.Next()) { + const TopoDS_Shape& aE = aItLE.Value(); + if (anEImages.IsBound(aE)) { + TopTools_MapOfShape aMFence; + TopTools_ListOfShape aLEImNew; + Standard_Boolean bModif = Standard_False; + // + TopTools_ListOfShape& aLEIm = anEImages.ChangeFind(aE); + aItLE1.Initialize(aLEIm); + for (; aItLE1.More(); aItLE1.Next()) { + const TopoDS_Shape& aEIm = aItLE1.Value(); + const TopTools_ListOfShape& aLEImIm = aGF.Modified(aEIm); + if (aLEImIm.Extent()) { + bModif = Standard_True; + TopTools_ListIteratorOfListOfShape aItLEIm(aLEImIm); + for (; aItLEIm.More(); aItLEIm.Next()) { + const TopoDS_Shape& aEImIm = aItLEIm.Value(); + if (aMFence.Add(aEImIm)) { + aLEImNew.Append(aEImIm); + aME.Add(aEImIm); + } + } + } + else { + aLEImNew.Append(aEIm); + aME.Add(aEIm); + } + } + // + if (bModif) { + aLEIm.Assign(aLEImNew); + } + } + else { + const TopTools_ListOfShape& aLEIm = aGF.Modified(aE); + if (aLEIm.Extent()) { + anEImages.Bind(aE, aLEIm); + TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm); + for (; aItLEIm.More(); aItLEIm.Next()) { + const TopoDS_Shape& aEIm = aItLEIm.Value(); + aME.Add(aEIm); + } + } + else { + aME.Add(aE); + } + } + } + // + if (!bLimited) { + // + // to overcome the often errors in trimming edges it is + // better to remove first the faces containing the boundaries + // of the extended surfaces; + Standard_Boolean bKeep; + aItLE.Initialize(aLFImages); + for (; aItLE.More();) { + const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLE.Value(); + // + aExp.Init(aFIm, TopAbs_EDGE); + for (bKeep = Standard_True; aExp.More() && bKeep; aExp.Next()) { + const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current(); + // + if (BRep_Tool::Degenerated(aE)) { + continue; + } + // + bKeep = aME.Contains(aE); + } + // + if (bKeep) { + aItLE.Next(); + } + else { + aLFImages.Remove(aItLE); + } + } + // + UpdateOrigins(theOrigins, aGF); + // + if (aLFImages.Extent() >= 1) { + TopTools_ListOfShape aLFKeep; + // + // check offset faces on the coincidence of the + // bi-normal directions with the original faces + CheckBiNormals(aLFImages, aF, theOrigins, aLFKeep, myRemoveInvalidFaces); + // + // limit the face + if (aLFImages.Extent() > 1) { + TopTools_ListOfShape aLFTmp = aLFImages; + aLFImages.Clear(); + // + SortFaces(aLFTmp, aLFImages, Standard_True); + } + // + if (aLFKeep.Extent()) { + TopTools_MapOfShape aMFence; + aItLE.Initialize(aLFImages); + for (; aItLE.More(); aItLE.Next()) { + const TopoDS_Shape& aFIm = aItLE.Value(); + aMFence.Add(aFIm); + } + // + aItLE.Initialize(aLFKeep); + for (; aItLE.More(); aItLE.Next()) { + const TopoDS_Shape& aFIm = aItLE.Value(); + if (aMFence.Add(aFIm)) { + aLFImages.Append(aFIm); + } + } + } + } + } + // + // Fill history for faces + if (aLFImages.Extent()) { + theImage.Bind(aF, aLFImages); + } + else { + BRepAdaptor_Surface aBAS(aF, Standard_False); + if (aBAS.GetType() != GeomAbs_Plane) { + theLFailed.Append(aF); + } + } + // + aItLE.Initialize(aLFImages); + for (; aItLE.More(); aItLE.Next()) { + const TopoDS_Shape& aFIm = aItLE.Value(); + aBB.Add(aFaces, aFIm); + } + } + // + // fill history for edges + TopTools_IndexedMapOfShape aMFE; + TopExp::MapShapes(aFaces, TopAbs_EDGE, aMFE); + // + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItEIm(anEImages); + for (; aItEIm.More(); aItEIm.Next()) { + const TopoDS_Shape& aE = aItEIm.Key(); + const TopTools_ListOfShape& aLEIm = aItEIm.Value(); + // + Standard_Boolean bHasImage = theImage.HasImage(aE); + aItLE.Initialize(aLEIm); + for (; aItLE.More(); aItLE.Next()) { + const TopoDS_Shape& aEIm = aItLE.Value(); + if (aMFE.Contains(aEIm)) { + if (bHasImage) { + theImage.Add(aE, aEIm); + } + else { + theImage.Bind(aE, aEIm); + bHasImage = Standard_True; + } + } + } + } +} //======================================================================= //function : BuildOffsetByArc @@ -1441,27 +1562,27 @@ void BRepOffset_MakeOffset::BuildOffsetByArc() for ( ; itl.More(); itl.Next()) { const TopoDS_Edge& Cur = TopoDS::Edge(itl.Value()); if ( !EdgeTgt.IsBound(Cur)) { - TopoDS_Shape aLocalShape = OF.Generated(Cur); - const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape); -// const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur)); - EdgeTgt.Bind(Cur,OF.Generated(Cur)); - TopoDS_Vertex V1,V2,OV1,OV2; - TopExp::Vertices (Cur,V1,V2); - TopExp::Vertices (OTE,OV1,OV2); - TopTools_ListOfShape LE; - if (!EdgeTgt.IsBound(V1)) { - myAnalyse.Edges(V1,BRepOffset_Tangent,LE); - const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1); - if (LE.Extent() == LA.Extent()) - EdgeTgt.Bind(V1,OV1); - } - if (!EdgeTgt.IsBound(V2)) { - LE.Clear(); - myAnalyse.Edges(V2,BRepOffset_Tangent,LE); - const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2); - if (LE.Extent() == LA.Extent()) - EdgeTgt.Bind(V2,OV2); - } + TopoDS_Shape aLocalShape = OF.Generated(Cur); + const TopoDS_Edge& OTE = TopoDS::Edge(aLocalShape); +// const TopoDS_Edge& OTE = TopoDS::Edge(OF.Generated(Cur)); + EdgeTgt.Bind(Cur,OF.Generated(Cur)); + TopoDS_Vertex V1,V2,OV1,OV2; + TopExp::Vertices (Cur,V1,V2); + TopExp::Vertices (OTE,OV1,OV2); + TopTools_ListOfShape LE; + if (!EdgeTgt.IsBound(V1)) { + myAnalyse.Edges(V1,BRepOffset_Tangent,LE); + const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V1); + if (LE.Extent() == LA.Extent()) + EdgeTgt.Bind(V1,OV1); + } + if (!EdgeTgt.IsBound(V2)) { + LE.Clear(); + myAnalyse.Edges(V2,BRepOffset_Tangent,LE); + const TopTools_ListOfShape& LA =myAnalyse.Ancestors(V2); + if (LE.Extent() == LA.Extent()) + EdgeTgt.Bind(V2,OV2); + } } } MapSF.Bind(F,OF); @@ -1477,60 +1598,60 @@ void BRepOffset_MakeOffset::BuildOffsetByArc() if (Done.Add(E)) { const TopTools_ListOfShape& Anc = myAnalyse.Ancestors(E); if (Anc.Extent() == 2) { - const BRepOffset_ListOfInterval& L = myAnalyse.Type(E); - if (!L.IsEmpty() && L.First().Type() == OT) { - Standard_Real CurOffset = myOffset; - if ( myFaceOffset.IsBound(Anc.First())) - CurOffset = myFaceOffset(Anc.First()); - TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E); - TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape); - aLocalShape = MapSF(Anc.Last()).Generated(E); - TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape); -// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E)); -// TopoDS_Edge EOn2 = TopoDS::Edge(MapSF(Anc.Last()) .Generated(E)); - // find if exits tangent edges in the original shape - TopoDS_Edge E1f, E1l; - TopoDS_Vertex V1f, V1l; - TopExp::Vertices(E,V1f,V1l); - TopTools_ListOfShape TangE; - myAnalyse.TangentEdges(E,V1f,TangE); - // find if the pipe on the tangent edges are soon created. - TopTools_ListIteratorOfListOfShape itl(TangE); - Standard_Boolean Find = Standard_False; - for ( ; itl.More() && !Find; itl.Next()) { - if ( MapSF.IsBound(itl.Value())) { - TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1f); - E1f = TopoDS::Edge(aLocalShape); -// E1f = TopoDS::Edge(MapSF(itl.Value()).Generated(V1f)); - Find = Standard_True; - } - } - TangE.Clear(); - myAnalyse.TangentEdges(E,V1l,TangE); - // find if the pipe on the tangent edges are soon created. - itl.Initialize(TangE); - Find = Standard_False; - for ( ; itl.More() && !Find; itl.Next()) { - if ( MapSF.IsBound(itl.Value())) { - TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1l); - E1l = TopoDS::Edge(aLocalShape); -// E1l = TopoDS::Edge(MapSF(itl.Value()).Generated(V1l)); - Find = Standard_True; - } - } - BRepOffset_Offset OF (E,EOn1,EOn2,CurOffset,E1f, E1l); - MapSF.Bind(E,OF); - } + const BRepOffset_ListOfInterval& L = myAnalyse.Type(E); + if (!L.IsEmpty() && L.First().Type() == OT) { + Standard_Real CurOffset = myOffset; + if ( myFaceOffset.IsBound(Anc.First())) + CurOffset = myFaceOffset(Anc.First()); + TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E); + TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape); + aLocalShape = MapSF(Anc.Last()).Generated(E); + TopoDS_Edge EOn2 = TopoDS::Edge(aLocalShape); +// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E)); +// TopoDS_Edge EOn2 = TopoDS::Edge(MapSF(Anc.Last()) .Generated(E)); + // find if exits tangent edges in the original shape + TopoDS_Edge E1f, E1l; + TopoDS_Vertex V1f, V1l; + TopExp::Vertices(E,V1f,V1l); + TopTools_ListOfShape TangE; + myAnalyse.TangentEdges(E,V1f,TangE); + // find if the pipe on the tangent edges are soon created. + TopTools_ListIteratorOfListOfShape itl(TangE); + Standard_Boolean Find = Standard_False; + for ( ; itl.More() && !Find; itl.Next()) { + if ( MapSF.IsBound(itl.Value())) { + TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1f); + E1f = TopoDS::Edge(aLocalShape); +// E1f = TopoDS::Edge(MapSF(itl.Value()).Generated(V1f)); + Find = Standard_True; + } + } + TangE.Clear(); + myAnalyse.TangentEdges(E,V1l,TangE); + // find if the pipe on the tangent edges are soon created. + itl.Initialize(TangE); + Find = Standard_False; + for ( ; itl.More() && !Find; itl.Next()) { + if ( MapSF.IsBound(itl.Value())) { + TopoDS_Shape aLocalShape = MapSF(itl.Value()).Generated(V1l); + E1l = TopoDS::Edge(aLocalShape); +// E1l = TopoDS::Edge(MapSF(itl.Value()).Generated(V1l)); + Find = Standard_True; + } + } + BRepOffset_Offset OF (E,EOn1,EOn2,CurOffset,E1f, E1l); + MapSF.Bind(E,OF); + } } else { - // ---------------------- - // free border. - // ---------------------- - TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E); - TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape); -/// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E)); + // ---------------------- + // free border. + // ---------------------- + TopoDS_Shape aLocalShape = MapSF(Anc.First()).Generated(E); + TopoDS_Edge EOn1 = TopoDS::Edge(aLocalShape); +/// TopoDS_Edge EOn1 = TopoDS::Edge(MapSF(Anc.First()).Generated(E)); myInitOffsetEdge.SetRoot(E); // skv: supporting history. - myInitOffsetEdge.Bind (E,EOn1); + myInitOffsetEdge.Bind (E,EOn1); } } } @@ -1549,42 +1670,42 @@ void BRepOffset_MakeOffset::BuildOffsetByArc() myAnalyse.Edges(V,OT,LE); if (LE.Extent() >= 3 && LE.Extent() == LA.Extent()) { - TopTools_ListOfShape LOE; - //-------------------------------------------------------- - // Return connected edges on tubes. - //-------------------------------------------------------- - for (it.Initialize(LE) ; it.More(); it.Next()) { - LOE.Append(MapSF(it.Value()).Generated(V).Reversed()); - } - //---------------------- - // construction sphere. - //----------------------- - const TopTools_ListOfShape& LLA = myAnalyse.Ancestors(LA.First()); - const TopoDS_Shape& FF = LLA.First(); - Standard_Real CurOffset = myOffset; - if ( myFaceOffset.IsBound(FF)) - CurOffset = myFaceOffset(FF); - - BRepOffset_Offset OF(V,LOE,CurOffset); - MapSF.Bind(V,OF); + TopTools_ListOfShape LOE; + //-------------------------------------------------------- + // Return connected edges on tubes. + //-------------------------------------------------------- + for (it.Initialize(LE) ; it.More(); it.Next()) { + LOE.Append(MapSF(it.Value()).Generated(V).Reversed()); + } + //---------------------- + // construction sphere. + //----------------------- + const TopTools_ListOfShape& LLA = myAnalyse.Ancestors(LA.First()); + const TopoDS_Shape& FF = LLA.First(); + Standard_Real CurOffset = myOffset; + if ( myFaceOffset.IsBound(FF)) + CurOffset = myFaceOffset(FF); + + BRepOffset_Offset OF(V,LOE,CurOffset); + MapSF.Bind(V,OF); } //-------------------------------------------------------------- // Particular processing if V is at least a free border. //------------------------------------------------------------- TopTools_ListOfShape LBF; myAnalyse.Edges(V,BRepOffset_FreeBoundary,LBF); - if (!LBF.IsEmpty()) { - Standard_Boolean First = Standard_True; - for (it.Initialize(LE) ; it.More(); it.Next()) { - if (First) { - myInitOffsetEdge.SetRoot(V); // skv: supporting history. - myInitOffsetEdge.Bind(V,MapSF(it.Value()).Generated(V)); - First = Standard_False; - } - else { - myInitOffsetEdge.Add(V,MapSF(it.Value()).Generated(V)); - } - } + if (!LBF.IsEmpty()) { + Standard_Boolean First = Standard_True; + for (it.Initialize(LE) ; it.More(); it.Next()) { + if (First) { + myInitOffsetEdge.SetRoot(V); // skv: supporting history. + myInitOffsetEdge.Bind(V,MapSF(it.Value()).Generated(V)); + First = Standard_False; + } + else { + myInitOffsetEdge.Add(V,MapSF(it.Value()).Generated(V)); + } + } } } } @@ -1605,12 +1726,12 @@ void BRepOffset_MakeOffset::BuildOffsetByArc() const TopoDS_Shape& SI = It.Key(); const BRepOffset_Offset& SF = It.Value(); if (SF.Status() == BRepOffset_Reversed || - SF.Status() == BRepOffset_Degenerated ) { + SF.Status() == BRepOffset_Degenerated ) { //------------------------------------------------ // Degenerated or returned faces are not stored. //------------------------------------------------ continue; - } + } const TopoDS_Face& OF = It.Value().Face(); myInitOffsetFace.Bind (SI,OF); @@ -1619,27 +1740,27 @@ void BRepOffset_MakeOffset::BuildOffsetByArc() if (SI.ShapeType() == TopAbs_FACE) { for (Exp.Init(SI.Oriented(TopAbs_FORWARD),TopAbs_EDGE); - Exp.More(); Exp.Next()) { - //-------------------------------------------------------------------- - // To each face are associatedthe edges that restrict that - // The edges that do not generate tubes or are not tangent - // to two faces are removed. - //-------------------------------------------------------------------- - const TopoDS_Edge& E = TopoDS::Edge(Exp.Current()); - const BRepOffset_ListOfInterval& L = myAnalyse.Type(E); - if (!L.IsEmpty() && L.First().Type() != RT) { - TopAbs_Orientation OO = E.Orientation(); - TopoDS_Shape aLocalShape = It.Value().Generated(E); - TopoDS_Edge OE = TopoDS::Edge(aLocalShape); -// TopoDS_Edge OE = TopoDS::Edge(It.Value().Generated(E)); - myAsDes->Add (OF,OE.Oriented(OO)); - } + Exp.More(); Exp.Next()) { + //-------------------------------------------------------------------- + // To each face are associatedthe edges that restrict that + // The edges that do not generate tubes or are not tangent + // to two faces are removed. + //-------------------------------------------------------------------- + const TopoDS_Edge& E = TopoDS::Edge(Exp.Current()); + const BRepOffset_ListOfInterval& L = myAnalyse.Type(E); + if (!L.IsEmpty() && L.First().Type() != RT) { + TopAbs_Orientation OO = E.Orientation(); + TopoDS_Shape aLocalShape = It.Value().Generated(E); + TopoDS_Edge OE = TopoDS::Edge(aLocalShape); +// TopoDS_Edge OE = TopoDS::Edge(It.Value().Generated(E)); + myAsDes->Add (OF,OE.Oriented(OO)); + } } } else { for (Exp.Init(OF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); - Exp.More(); Exp.Next()) { - myAsDes->Add (OF,Exp.Current()); + Exp.More(); Exp.Next()) { + myAsDes->Add (OF,Exp.Current()); } } } @@ -1649,13 +1770,10 @@ void BRepOffset_MakeOffset::BuildOffsetByArc() #endif } - - //======================================================================= //function : SelfInter //purpose : //======================================================================= - void BRepOffset_MakeOffset::SelfInter(TopTools_MapOfShape& /*Modif*/) { #ifdef OCCT_DEBUG @@ -1673,12 +1791,10 @@ void BRepOffset_MakeOffset::SelfInter(TopTools_MapOfShape& /*Modif*/) #endif } - //======================================================================= //function : ToContext //purpose : //======================================================================= - void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF) { TopTools_DataMapOfShapeShape Created; @@ -1697,14 +1813,14 @@ void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF) for (i = 1; i <= myFaces.Extent(); i++) { const TopoDS_Face& CF = TopoDS::Face(myFaces(i)); for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); - exp.More(); exp.Next()) { + exp.More(); exp.Next()) { const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); if (!myAnalyse.HasAncestor(E)) { - //---------------------------------------------------------------- - // The edges of context faces that are not in the initial shape - // can appear in the result. - //---------------------------------------------------------------- - //myAsDes->Add(CF,E); + //---------------------------------------------------------------- + // The edges of context faces that are not in the initial shape + // can appear in the result. + //---------------------------------------------------------------- + //myAsDes->Add(CF,E); } } } @@ -1718,28 +1834,28 @@ void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF) for (j = 1; j <= myFaces.Extent(); j++) { const TopoDS_Face& CF = TopoDS::Face(myFaces(j)); for (exp.Init(CF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); - exp.More(); exp.Next()) { + exp.More(); exp.Next()) { const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); if (myAnalyse.HasAncestor(E)) { - const TopTools_ListOfShape& LEA = myAnalyse.Ancestors(E); - for (itl.Initialize(LEA); itl.More(); itl.Next()) { - const BRepOffset_Offset& OF = MapSF(itl.Value()); - FacesToBuild.Add(itl.Value()); - MEF.Bind(OF.Generated(E),CF); - } - TopoDS_Vertex V[2]; - TopExp::Vertices(E,V[0],V[1]); - for (Standard_Integer i = 0; i < 2; i++) { - const TopTools_ListOfShape& LVA = myAnalyse.Ancestors(V[i]); - for ( itl.Initialize(LVA); itl.More(); itl.Next()) { - const TopoDS_Edge& EV = TopoDS::Edge(itl.Value()); - if (MapSF.IsBound(EV)) { - const BRepOffset_Offset& OF = MapSF(EV); - FacesToBuild.Add(EV); - MEF.Bind(OF.Generated(V[i]),CF); - } - } - } + const TopTools_ListOfShape& LEA = myAnalyse.Ancestors(E); + for (itl.Initialize(LEA); itl.More(); itl.Next()) { + const BRepOffset_Offset& OF = MapSF(itl.Value()); + FacesToBuild.Add(itl.Value()); + MEF.Bind(OF.Generated(E),CF); + } + TopoDS_Vertex V[2]; + TopExp::Vertices(E,V[0],V[1]); + for (Standard_Integer i = 0; i < 2; i++) { + const TopTools_ListOfShape& LVA = myAnalyse.Ancestors(V[i]); + for ( itl.Initialize(LVA); itl.More(); itl.Next()) { + const TopoDS_Edge& EV = TopoDS::Edge(itl.Value()); + if (MapSF.IsBound(EV)) { + const BRepOffset_Offset& OF = MapSF(EV); + FacesToBuild.Add(EV); + MEF.Bind(OF.Generated(V[i]),CF); + } + } + } } } } @@ -1768,26 +1884,26 @@ void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF) if (S.ShapeType() == TopAbs_FACE) { for (exp.Init(S.Oriented(TopAbs_FORWARD),TopAbs_EDGE); - exp.More(); exp.Next()) { - - const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); - const BRepOffset_ListOfInterval& L = myAnalyse.Type(E); - OE = BOF.Generated(E); - Or = E.Orientation(); - OE.Orientation(Or); - if (!L.IsEmpty() && L.First().Type() != RT) { - if (Created.IsBound(OE)) { - NE = Created(OE); - if (NE.Orientation() == TopAbs_REVERSED) - NE.Orientation(TopAbs::Reverse(Or)); - else - NE.Orientation(Or); - myAsDes->Add(NF,NE); - } - else { - myAsDes->Add(NF,OE); - } - } + exp.More(); exp.Next()) { + + const TopoDS_Edge& E = TopoDS::Edge(exp.Current()); + const BRepOffset_ListOfInterval& L = myAnalyse.Type(E); + OE = BOF.Generated(E); + Or = E.Orientation(); + OE.Orientation(Or); + if (!L.IsEmpty() && L.First().Type() != RT) { + if (Created.IsBound(OE)) { + NE = Created(OE); + if (NE.Orientation() == TopAbs_REVERSED) + NE.Orientation(TopAbs::Reverse(Or)); + else + NE.Orientation(Or); + myAsDes->Add(NF,NE); + } + else { + myAsDes->Add(NF,OE); + } + } } } else { @@ -1795,8 +1911,8 @@ void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF) // Tube //--------------------- for (exp.Init(NF.Oriented(TopAbs_FORWARD),TopAbs_EDGE); - exp.More(); exp.Next()) { - myAsDes->Add (NF,exp.Current()); + exp.More(); exp.Next()) { + myAsDes->Add (NF,exp.Current()); } } MapSF.UnBind(S); @@ -1813,21 +1929,19 @@ void BRepOffset_MakeOffset::ToContext (BRepOffset_DataMapOfShapeOffset& MapSF) TopoDS_Shape E = myInitOffsetEdge.ImageFrom (OE); Or = myInitOffsetEdge.Image(E).First().Orientation(); if (NE.Orientation() == TopAbs_REVERSED) - NE.Orientation(TopAbs::Reverse(Or)); + NE.Orientation(TopAbs::Reverse(Or)); else - NE.Orientation(Or); + NE.Orientation(Or); myInitOffsetEdge.Remove(OE); myInitOffsetEdge.Bind(E,NE); } } } - //======================================================================= //function : UpdateFaceOffset //purpose : //======================================================================= - void BRepOffset_MakeOffset::UpdateFaceOffset() { TopTools_MapOfShape M; @@ -1857,7 +1971,7 @@ void BRepOffset_MakeOffset::UpdateFaceOffset() const TopoDS_Face& FF = TopoDS::Face(exp.Current()); if ( !M.Add(FF)) continue; if ( myFaceOffset.IsBound(FF)) - myFaceOffset.UnBind(FF); + myFaceOffset.UnBind(FF); myFaceOffset.Bind(FF,CurOffset); } } @@ -1867,7 +1981,6 @@ void BRepOffset_MakeOffset::UpdateFaceOffset() //function : CorrectConicalFaces //purpose : //======================================================================= - void BRepOffset_MakeOffset::CorrectConicalFaces() { if(myOffsetShape.IsNull()) @@ -2017,7 +2130,7 @@ void BRepOffset_MakeOffset::CorrectConicalFaces() Ul = 2.*M_PI; Handle(Geom_Curve) aCurv = aSphSurf->VIso(Vf); /* - if (!isFirstFace) + if (!isFirstFace) { gp_Circ aCircle = (Handle(Geom_Circle)::DownCast(aCurv))->Circ(); if (Abs(Uf - f) > Precision::Confusion()) @@ -2294,12 +2407,10 @@ void BRepOffset_MakeOffset::CorrectConicalFaces() } } - //======================================================================= //function : Intersection3D //purpose : //======================================================================= - void BRepOffset_MakeOffset::Intersection3D(BRepOffset_Inter3d& Inter) { #ifdef OCCT_DEBUG @@ -2310,7 +2421,7 @@ void BRepOffset_MakeOffset::Intersection3D(BRepOffset_Inter3d& Inter) } #endif TopTools_ListOfShape OffsetFaces; // list of faces // created. - MakeList (OffsetFaces,myInitOffsetFace,myFaces); + MakeList (OffsetFaces, myInitOffsetFace, myFaces); if (!myFaces.IsEmpty()) { Standard_Boolean InSide = (myOffset < 0.); // Temporary @@ -2347,7 +2458,7 @@ void BRepOffset_MakeOffset::Intersection3D(BRepOffset_Inter3d& Inter) //======================================================================= void BRepOffset_MakeOffset::Intersection2D(const TopTools_IndexedMapOfShape& Modif, - const TopTools_IndexedMapOfShape& NewEdges) + const TopTools_IndexedMapOfShape& NewEdges) { #ifdef OCCT_DEBUG if (ChronBuild) { @@ -2367,7 +2478,8 @@ void BRepOffset_MakeOffset::Intersection2D(const TopTools_IndexedMapOfShape& Mod Standard_Integer i; for (i = 1; i <= Modif.Extent(); i++) { const TopoDS_Face& F = TopoDS::Face(Modif(i)); - BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,myTol); + Standard_Real aCurrFaceTol = BRep_Tool::Tolerance(F); + BRepOffset_Inter2d::Compute(myAsDes,F,NewEdges,aCurrFaceTol); } #ifdef OCCT_DEBUG @@ -2378,12 +2490,10 @@ void BRepOffset_MakeOffset::Intersection2D(const TopTools_IndexedMapOfShape& Mod #endif } - //======================================================================= //function : MakeLoops //purpose : //======================================================================= - void BRepOffset_MakeOffset::MakeLoops(TopTools_IndexedMapOfShape& Modif) { #ifdef OCCT_DEBUG @@ -2403,8 +2513,18 @@ void BRepOffset_MakeOffset::MakeLoops(TopTools_IndexedMapOfShape& Modif) if (!myFaces.Contains(Modif(i))) LF.Append(Modif(i)); } - myMakeLoops.Build(LF,myAsDes,myImageOffset); - + // + if ((myJoin == GeomAbs_Intersection) && myInter) { + TopTools_ListOfShape aLFailed; + TopTools_IndexedDataMapOfShapeListOfShape anOr; + BuildSplitsOfFaces(LF, myAsDes, anOr, myImageOffset, aLFailed, Standard_True); + if (aLFailed.Extent()) { + myMakeLoops.Build(aLFailed, myAsDes, myImageOffset); + } + } + else { + myMakeLoops.Build(LF,myAsDes,myImageOffset); + } //----------------------------------------- // unwinding of caps. //----------------------------------------- @@ -2425,7 +2545,6 @@ void BRepOffset_MakeOffset::MakeLoops(TopTools_IndexedMapOfShape& Modif) //purpose : Reconstruction of topologically unchanged faces that // share edges that were reconstructed. //======================================================================= - void BRepOffset_MakeOffset::MakeFaces(TopTools_IndexedMapOfShape& /*Modif*/) { #ifdef OCCT_DEBUG @@ -2438,58 +2557,34 @@ void BRepOffset_MakeOffset::MakeFaces(TopTools_IndexedMapOfShape& /*Modif*/) TopTools_ListIteratorOfListOfShape itr; const TopTools_ListOfShape& Roots = myInitOffsetFace.Roots(); TopTools_ListOfShape LOF; + TopTools_MapOfShape aMFence; //---------------------------------- // Loop on all faces //. //---------------------------------- for (itr.Initialize(Roots); itr.More(); itr.Next()) { TopoDS_Face F = TopoDS::Face(myInitOffsetFace.Image(itr.Value()).First()); - LOF.Append(F); + if (!myImageOffset.HasImage(F) && aMFence.Add(F)) { + LOF.Append(F); + } } - myMakeLoops.BuildFaces(LOF,myAsDes,myImageOffset); - + // + if ((myJoin == GeomAbs_Intersection) && myInter) { + TopTools_ListOfShape aLFailed; + TopTools_IndexedDataMapOfShapeListOfShape anOr; + BuildSplitsOfFaces(LOF, myAsDes, anOr, myImageOffset, aLFailed, Standard_True); + if (aLFailed.Extent()) { + myMakeLoops.Build(aLFailed, myAsDes, myImageOffset); + } + } + else { + myMakeLoops.BuildFaces(LOF,myAsDes,myImageOffset); + } + // #ifdef OCCT_DEBUG if ( ChronBuild) Clock.Show(); #endif } -//======================================================================= -//function : UpdateInitOffset -//purpose : Update and cleaning of myInitOffset -//======================================================================= - -static void UpdateInitOffset (BRepAlgo_Image& myInitOffset, - BRepAlgo_Image& myImageOffset, - const TopoDS_Shape& myOffsetShape, - const TopAbs_ShapeEnum &theShapeType) // skv -{ - BRepAlgo_Image NIOF; - const TopTools_ListOfShape& Roots = myInitOffset.Roots(); - TopTools_ListIteratorOfListOfShape it(Roots); - for (; it.More(); it.Next()) { - NIOF.SetRoot (it.Value()); - } - for (it.Initialize(Roots); it.More(); it.Next()) { - const TopoDS_Shape& SI = it.Value(); - TopTools_ListOfShape LI; - TopTools_ListOfShape L1; - myInitOffset.LastImage(SI,L1); - TopTools_ListIteratorOfListOfShape itL1(L1); - for (; itL1.More(); itL1.Next()) { - const TopoDS_Shape& O1 = itL1.Value(); - TopTools_ListOfShape L2; - myImageOffset.LastImage(O1,L2); - LI.Append(L2); - } - NIOF.Bind(SI,LI); - } -// Modified by skv - Mon Apr 4 18:17:27 2005 Begin -// Supporting history. -// NIOF.Filter(myOffsetShape,TopAbs_FACE); - NIOF.Filter(myOffsetShape, theShapeType); -// Modified by skv - Mon Apr 4 18:17:27 2005 End - myInitOffset = NIOF; -} - //======================================================================= //function : MakeMissingWalls //purpose : @@ -2504,35 +2599,35 @@ void BRepOffset_MakeOffset::MakeMissingWalls () TopTools_DataMapIteratorOfDataMapOfShapeListOfShape iter(Contours); for (; iter.More(); iter.Next()) - { - TopoDS_Vertex StartVertex = TopoDS::Vertex(iter.Key()); - TopoDS_Edge StartEdge; - const TopTools_ListOfShape& aContour = iter.Value(); - TopTools_ListIteratorOfListOfShape itl(aContour); - Standard_Boolean FirstStep = Standard_True; - TopoDS_Edge PrevEdge; - TopoDS_Vertex PrevVertex = StartVertex; + { + TopoDS_Vertex StartVertex = TopoDS::Vertex(iter.Key()); + TopoDS_Edge StartEdge; + const TopTools_ListOfShape& aContour = iter.Value(); + TopTools_ListIteratorOfListOfShape itl(aContour); + Standard_Boolean FirstStep = Standard_True; + TopoDS_Edge PrevEdge; + TopoDS_Vertex PrevVertex = StartVertex; Standard_Boolean isBuildFromScratch = Standard_False; // Problems with edges. - for (; itl.More(); itl.Next()) - { - TopoDS_Edge anEdge = TopoDS::Edge(itl.Value()); - + for (; itl.More(); itl.Next()) + { + TopoDS_Edge anEdge = TopoDS::Edge(itl.Value()); + // Check for offset existence. - if (!myInitOffsetEdge.HasImage(anEdge)) - continue; - + if (!myInitOffsetEdge.HasImage(anEdge)) + continue; + // Check for existence of two different vertices. - TopTools_ListOfShape LOE, LOE2; - myInitOffsetEdge.LastImage( anEdge, LOE ); - myImageOffset.LastImage( LOE.Last(), LOE2 ); - TopoDS_Edge OE = TopoDS::Edge( LOE2.Last() ); - TopoDS_Vertex V1, V2, V3, V4; + TopTools_ListOfShape LOE, LOE2; + myInitOffsetEdge.LastImage( anEdge, LOE ); + myImageOffset.LastImage( LOE.Last(), LOE2 ); + TopoDS_Edge OE = TopoDS::Edge( LOE2.Last() ); + TopoDS_Vertex V1, V2, V3, V4; TopExp::Vertices(OE, V4, V3); TopExp::Vertices(anEdge, V1, V2); Standard_Real aF, aL; const Handle(Geom_Curve) &aC = BRep_Tool::Curve(anEdge, aF, aL); if (!aC.IsNull() && - (!aC->IsClosed() && !aC->IsPeriodic())) + (!aC->IsClosed() && !aC->IsPeriodic())) { gp_Pnt aPntF = BRep_Tool::Pnt(V1); gp_Pnt aPntL = BRep_Tool::Pnt(V2); @@ -2565,338 +2660,338 @@ void BRepOffset_MakeOffset::MakeMissingWalls () } TopoDS_Face aFace = TopoDS::Face(MapEF(anEdge)); - Standard_Boolean ToReverse = Standard_False; - if (!V1.IsSame(PrevVertex)) - { - TopoDS_Vertex aVtx = V1; V1 = V2; V2 = aVtx; - aVtx = V3; V3 = V4; V4 = aVtx; - ToReverse = Standard_True; - } + Standard_Boolean ToReverse = Standard_False; + if (!V1.IsSame(PrevVertex)) + { + TopoDS_Vertex aVtx = V1; V1 = V2; V2 = aVtx; + aVtx = V3; V3 = V4; V4 = aVtx; + ToReverse = Standard_True; + } - OE.Orientation(TopAbs::Reverse(anEdge.Orientation())); - TopoDS_Edge E3, E4; + OE.Orientation(TopAbs::Reverse(anEdge.Orientation())); + TopoDS_Edge E3, E4; Standard_Boolean ArcOnV2 = ((myJoin == GeomAbs_Arc) && (myInitOffsetEdge.HasImage(V2))); if (FirstStep || isBuildFromScratch) - { - E4 = BRepLib_MakeEdge( V1, V4 ); + { + E4 = BRepLib_MakeEdge( V1, V4 ); if (FirstStep) - StartEdge = E4; - } - else - E4 = PrevEdge; - if (V2.IsSame(StartVertex) && !ArcOnV2) - E3 = StartEdge; - else - E3 = BRepLib_MakeEdge( V2, V3 ); - E4.Reverse(); - + StartEdge = E4; + } + else + E4 = PrevEdge; + if (V2.IsSame(StartVertex) && !ArcOnV2) + E3 = StartEdge; + else + E3 = BRepLib_MakeEdge( V2, V3 ); + E4.Reverse(); + if (isBuildFromScratch) { E3.Reverse(); E4.Reverse(); } - TopoDS_Shape localAnEdge = anEdge.Oriented(TopAbs_FORWARD); - const TopoDS_Edge& anEdgeFWD = TopoDS::Edge(localAnEdge); - Standard_Real ParV1 = BRep_Tool::Parameter(V1, anEdgeFWD); - Standard_Real ParV2 = BRep_Tool::Parameter(V2, anEdgeFWD); - BRep_Builder BB; - TopoDS_Wire theWire; - BB.MakeWire(theWire); - if (ToReverse) - { - BB.Add(theWire, anEdge.Reversed()); - BB.Add(theWire, E3.Reversed()); - BB.Add(theWire, OE.Reversed()); - BB.Add(theWire, E4.Reversed()); - } - else - { - BB.Add(theWire, anEdge); - BB.Add(theWire, E3); - BB.Add(theWire, OE); - BB.Add(theWire, E4); - } + TopoDS_Shape localAnEdge = anEdge.Oriented(TopAbs_FORWARD); + const TopoDS_Edge& anEdgeFWD = TopoDS::Edge(localAnEdge); + Standard_Real ParV1 = BRep_Tool::Parameter(V1, anEdgeFWD); + Standard_Real ParV2 = BRep_Tool::Parameter(V2, anEdgeFWD); + BRep_Builder BB; + TopoDS_Wire theWire; + BB.MakeWire(theWire); + if (ToReverse) + { + BB.Add(theWire, anEdge.Reversed()); + BB.Add(theWire, E3.Reversed()); + BB.Add(theWire, OE.Reversed()); + BB.Add(theWire, E4.Reversed()); + } + else + { + BB.Add(theWire, anEdge); + BB.Add(theWire, E3); + BB.Add(theWire, OE); + BB.Add(theWire, E4); + } - BRepLib::BuildCurves3d( theWire, myTol ); - theWire.Closed(Standard_True); - TopoDS_Face NewFace; - Handle(Geom_Surface) theSurf; - BRepAdaptor_Curve BAcurve(anEdge); - BRepAdaptor_Curve BAcurveOE(OE); - Standard_Real fpar = BAcurve.FirstParameter(); - Standard_Real lpar = BAcurve.LastParameter(); - gp_Pnt PonE = BAcurve.Value(fpar); - gp_Pnt PonOE = BAcurveOE.Value(fpar); - gp_Dir OffsetDir = gce_MakeDir( PonE, PonOE ); - Handle(Geom2d_Line) EdgeLine2d, OELine2d, aLine2d, aLine2d2; - Standard_Boolean IsPlanar = Standard_False; - if (BAcurve.GetType() == GeomAbs_Circle && - BAcurveOE.GetType() == GeomAbs_Circle) - { - gp_Circ aCirc = BAcurve.Circle(); - gp_Circ aCircOE = BAcurveOE.Circle(); - gp_Lin anAxisLine(aCirc.Axis()); - gp_Dir CircAxisDir = aCirc.Axis().Direction(); - if (aCirc.Axis().IsParallel(aCircOE.Axis(), Precision::Confusion()) && - anAxisLine.Contains(aCircOE.Location(), Precision::Confusion())) - { //cylinder, plane or cone - if (Abs(aCirc.Radius() - aCircOE.Radius()) <= Precision::Confusion()) //case of cylinder - theSurf = GC_MakeCylindricalSurface(aCirc).Value(); - else if (aCirc.Location().Distance(aCircOE.Location()) <= Precision::Confusion()) {//case of plane - IsPlanar = Standard_True; + BRepLib::BuildCurves3d( theWire, myTol ); + theWire.Closed(Standard_True); + TopoDS_Face NewFace; + Handle(Geom_Surface) theSurf; + BRepAdaptor_Curve BAcurve(anEdge); + BRepAdaptor_Curve BAcurveOE(OE); + Standard_Real fpar = BAcurve.FirstParameter(); + Standard_Real lpar = BAcurve.LastParameter(); + gp_Pnt PonE = BAcurve.Value(fpar); + gp_Pnt PonOE = BAcurveOE.Value(fpar); + gp_Dir OffsetDir = gce_MakeDir( PonE, PonOE ); + Handle(Geom2d_Line) EdgeLine2d, OELine2d, aLine2d, aLine2d2; + Standard_Boolean IsPlanar = Standard_False; + if (BAcurve.GetType() == GeomAbs_Circle && + BAcurveOE.GetType() == GeomAbs_Circle) + { + gp_Circ aCirc = BAcurve.Circle(); + gp_Circ aCircOE = BAcurveOE.Circle(); + gp_Lin anAxisLine(aCirc.Axis()); + gp_Dir CircAxisDir = aCirc.Axis().Direction(); + if (aCirc.Axis().IsParallel(aCircOE.Axis(), Precision::Confusion()) && + anAxisLine.Contains(aCircOE.Location(), Precision::Confusion())) + { //cylinder, plane or cone + if (Abs(aCirc.Radius() - aCircOE.Radius()) <= Precision::Confusion()) //case of cylinder + theSurf = GC_MakeCylindricalSurface(aCirc).Value(); + else if (aCirc.Location().Distance(aCircOE.Location()) <= Precision::Confusion()) {//case of plane + IsPlanar = Standard_True; + // + gp_Pnt PonEL = BAcurve.Value(lpar); + if (PonEL.Distance(PonE) <= Precision::PConfusion()) { + Standard_Boolean bIsHole; + TopoDS_Edge aE1, aE2; + TopoDS_Wire aW1, aW2; + Handle(Geom_Plane) aPL; + IntTools_FClass2d aClsf; + // + if (aCirc.Radius()>aCircOE.Radius()) { + aE1 = anEdge; + aE2 = OE; + } else { + aE1 = OE; + aE2 = anEdge; + } + // + BB.MakeWire(aW1); + BB.Add(aW1, aE1); + BB.MakeWire(aW2); + BB.Add(aW2, aE2); + // + aPL = new Geom_Plane(aCirc.Location(), CircAxisDir); + for (Standard_Integer i = 0; i < 2; ++i) { + TopoDS_Wire& aW = (i==0) ? aW1 : aW2; + TopoDS_Edge& aE = (i==0) ? aE1 : aE2; // - gp_Pnt PonEL = BAcurve.Value(lpar); - if (PonEL.Distance(PonE) <= Precision::PConfusion()) { - Standard_Boolean bIsHole; - TopoDS_Edge aE1, aE2; - TopoDS_Wire aW1, aW2; - Handle(Geom_Plane) aPL; - IntTools_FClass2d aClsf; - // - if (aCirc.Radius()>aCircOE.Radius()) { - aE1 = anEdge; - aE2 = OE; - } else { - aE1 = OE; - aE2 = anEdge; - } - // - BB.MakeWire(aW1); - BB.Add(aW1, aE1); - BB.MakeWire(aW2); - BB.Add(aW2, aE2); - // - aPL = new Geom_Plane(aCirc.Location(), CircAxisDir); - for (Standard_Integer i = 0; i < 2; ++i) { - TopoDS_Wire& aW = (i==0) ? aW1 : aW2; - TopoDS_Edge& aE = (i==0) ? aE1 : aE2; - // - TopoDS_Face aFace; - BB.MakeFace(aFace, aPL, Precision::Confusion()); - BB.Add (aFace, aW); - aClsf.Init(aFace, Precision::Confusion()); - bIsHole=aClsf.IsHole(); - if ((bIsHole && !i) || (!bIsHole && i)) { - aW.Nullify(); - BB.MakeWire(aW); - BB.Add(aW, aE.Reversed()); - } - } - // - BB.MakeFace(NewFace, aPL, Precision::Confusion()); - BB.Add(NewFace, aW1); - BB.Add(NewFace, aW2); + TopoDS_Face aFace; + BB.MakeFace(aFace, aPL, Precision::Confusion()); + BB.Add (aFace, aW); + aClsf.Init(aFace, Precision::Confusion()); + bIsHole=aClsf.IsHole(); + if ((bIsHole && !i) || (!bIsHole && i)) { + aW.Nullify(); + BB.MakeWire(aW); + BB.Add(aW, aE.Reversed()); } } - else //case of cone + // + BB.MakeFace(NewFace, aPL, Precision::Confusion()); + BB.Add(NewFace, aW1); + BB.Add(NewFace, aW2); + } + } + else //case of cone + { + gp_Cone theCone = gce_MakeCone(aCirc.Location(), aCircOE.Location(), + aCirc.Radius(), aCircOE.Radius()); + gp_Ax3 theAx3(aCirc.Position()); + if (CircAxisDir * theCone.Axis().Direction() < 0.) + { + theAx3.ZReverse(); + CircAxisDir.Reverse(); + } + theCone.SetPosition(theAx3); + theSurf = new Geom_ConicalSurface(theCone); + } + if (!IsPlanar) { + TopLoc_Location Loc; + EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., 0.), gp_Dir2d(1., 0.)); + BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion()); + Standard_Real Coeff = (OffsetDir * CircAxisDir > 0.)? 1. : -1.; + OELine2d = new Geom2d_Line(gp_Pnt2d(0., OffsetVal*Coeff), gp_Dir2d(1., 0.)); + BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion()); + aLine2d = new Geom2d_Line(gp_Pnt2d(ParV2, 0.), gp_Dir2d(0., Coeff)); + aLine2d2 = new Geom2d_Line(gp_Pnt2d(ParV1, 0.), gp_Dir2d(0., Coeff)); + if (E3.IsSame(E4)) + { + if (Coeff > 0.) + BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion()); + else { - gp_Cone theCone = gce_MakeCone(aCirc.Location(), aCircOE.Location(), - aCirc.Radius(), aCircOE.Radius()); - gp_Ax3 theAx3(aCirc.Position()); - if (CircAxisDir * theCone.Axis().Direction() < 0.) - { - theAx3.ZReverse(); - CircAxisDir.Reverse(); - } - theCone.SetPosition(theAx3); - theSurf = new Geom_ConicalSurface(theCone); + BB.UpdateEdge(E3, aLine2d2, aLine2d, theSurf, Loc, Precision::Confusion()); + theWire.Nullify(); + BB.MakeWire(theWire); + BB.Add(theWire, anEdge.Oriented(TopAbs_REVERSED)); + BB.Add(theWire, E4); + BB.Add(theWire, OE.Oriented(TopAbs_FORWARD)); + BB.Add(theWire, E3); + theWire.Closed(Standard_True); } - if (!IsPlanar) { - TopLoc_Location Loc; - EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., 0.), gp_Dir2d(1., 0.)); - BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion()); - Standard_Real Coeff = (OffsetDir * CircAxisDir > 0.)? 1. : -1.; - OELine2d = new Geom2d_Line(gp_Pnt2d(0., OffsetVal*Coeff), gp_Dir2d(1., 0.)); - BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion()); - aLine2d = new Geom2d_Line(gp_Pnt2d(ParV2, 0.), gp_Dir2d(0., Coeff)); - aLine2d2 = new Geom2d_Line(gp_Pnt2d(ParV1, 0.), gp_Dir2d(0., Coeff)); - if (E3.IsSame(E4)) - { - if (Coeff > 0.) - BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion()); - else - { - BB.UpdateEdge(E3, aLine2d2, aLine2d, theSurf, Loc, Precision::Confusion()); - theWire.Nullify(); - BB.MakeWire(theWire); - BB.Add(theWire, anEdge.Oriented(TopAbs_REVERSED)); - BB.Add(theWire, E4); - BB.Add(theWire, OE.Oriented(TopAbs_FORWARD)); - BB.Add(theWire, E3); - theWire.Closed(Standard_True); - } - } - else - { - BB.SameParameter(E3, Standard_False); - BB.SameRange(E3, Standard_False); - BB.SameParameter(E4, Standard_False); - BB.SameRange(E4, Standard_False); - BB.UpdateEdge(E3, aLine2d, theSurf, Loc, Precision::Confusion()); - BB.Range(E3, theSurf, Loc, 0., OffsetVal); - BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion()); - BB.Range(E4, theSurf, Loc, 0., OffsetVal); - } - NewFace = BRepLib_MakeFace(theSurf, theWire); - } - } //cylinder or cone - } //if both edges are arcs of circles - if (NewFace.IsNull()) - { - BRepLib_MakeFace MF(theWire, Standard_True); //Only plane - if (MF.Error() == BRepLib_FaceDone) - { - NewFace = MF.Face(); - IsPlanar = Standard_True; - } - else //Extrusion (by thrusections) - { - Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(anEdge, fpar, lpar); - Handle(Geom_TrimmedCurve) TrEdgeCurve = - new Geom_TrimmedCurve( EdgeCurve, fpar, lpar ); - Standard_Real fparOE, lparOE; - Handle(Geom_Curve) OffsetCurve = BRep_Tool::Curve(OE, fparOE, lparOE); - Handle(Geom_TrimmedCurve) TrOffsetCurve = - new Geom_TrimmedCurve( OffsetCurve, fparOE, lparOE ); - GeomFill_Generator ThrusecGenerator; - ThrusecGenerator.AddCurve( TrEdgeCurve ); - ThrusecGenerator.AddCurve( TrOffsetCurve ); - ThrusecGenerator.Perform( Precision::PConfusion() ); - theSurf = ThrusecGenerator.Surface(); - //theSurf = new Geom_SurfaceOfLinearExtrusion( TrOffsetCurve, OffsetDir ); - Standard_Real Uf, Ul, Vf, Vl; - theSurf->Bounds(Uf, Ul, Vf, Vl); - TopLoc_Location Loc; - EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., Vf), gp_Dir2d(1., 0.)); - BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion()); - OELine2d = new Geom2d_Line(gp_Pnt2d(0., Vl), gp_Dir2d(1., 0.)); - BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion()); - Standard_Real UonV1 = (ToReverse)? Ul : Uf; - Standard_Real UonV2 = (ToReverse)? Uf : Ul; - aLine2d = new Geom2d_Line(gp_Pnt2d(UonV2, 0.), gp_Dir2d(0., 1.)); - aLine2d2 = new Geom2d_Line(gp_Pnt2d(UonV1, 0.), gp_Dir2d(0., 1.)); - if (E3.IsSame(E4)) - { - BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion()); - Handle(Geom_Curve) BSplC34 = theSurf->UIso( Uf ); - BB.UpdateEdge(E3, BSplC34, Precision::Confusion()); - BB.Range(E3, Vf, Vl); - } - else - { - BB.SameParameter(E3, Standard_False); - BB.SameRange(E3, Standard_False); - BB.SameParameter(E4, Standard_False); - BB.SameRange(E4, Standard_False); - BB.UpdateEdge(E3, aLine2d, theSurf, Loc, Precision::Confusion()); - BB.Range(E3, theSurf, Loc, Vf, Vl); - BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion()); - BB.Range(E4, theSurf, Loc, Vf, Vl); - Handle(Geom_Curve) BSplC3 = theSurf->UIso( UonV2 ); - BB.UpdateEdge(E3, BSplC3, Precision::Confusion()); - BB.Range(E3, Vf, Vl, Standard_True); //only for 3d curve - Handle(Geom_Curve) BSplC4 = theSurf->UIso( UonV1 ); - BB.UpdateEdge(E4, BSplC4, Precision::Confusion()); - BB.Range(E4, Vf, Vl, Standard_True); //only for 3d curve - } - NewFace = BRepLib_MakeFace(theSurf, theWire); - } - } - if (!IsPlanar) - { - Standard_Real fparOE = BAcurveOE.FirstParameter(); - Standard_Real lparOE = BAcurveOE.LastParameter(); - TopLoc_Location Loc; - if (Abs(fpar - fparOE) > Precision::Confusion()) - { - const TopoDS_Edge& anE4 = (ToReverse)? E3 : E4; - gp_Pnt2d fp2d = EdgeLine2d->Value(fpar); - gp_Pnt2d fp2dOE = OELine2d->Value(fparOE); - aLine2d2 = GCE2d_MakeLine( fp2d, fp2dOE ).Value(); - Handle(Geom_Curve) aCurve; - Standard_Real FirstPar = 0., LastPar = fp2d.Distance(fp2dOE); - Geom2dAdaptor_Curve AC2d( aLine2d2, FirstPar, LastPar ); - GeomAdaptor_Surface GAsurf( theSurf ); - Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d ); - Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf ); - Adaptor3d_CurveOnSurface ConS( HC2d, HSurf ); - Standard_Real max_deviation = 0., average_deviation; - GeomLib::BuildCurve3d(Precision::Confusion(), - ConS, FirstPar, LastPar, - aCurve, max_deviation, average_deviation); - BB.UpdateEdge( anE4, aCurve, max_deviation ); - BB.UpdateEdge( anE4, aLine2d2, theSurf, Loc, max_deviation ); - BB.Range( anE4, FirstPar, LastPar ); - } - if (Abs(lpar - lparOE) > Precision::Confusion()) - { - const TopoDS_Edge& anE3 = (ToReverse)? E4 : E3; - gp_Pnt2d lp2d = EdgeLine2d->Value(lpar); - gp_Pnt2d lp2dOE = OELine2d->Value(lparOE); - aLine2d = GCE2d_MakeLine( lp2d, lp2dOE ).Value(); - Handle(Geom_Curve) aCurve; - Standard_Real FirstPar = 0., LastPar = lp2d.Distance(lp2dOE); - Geom2dAdaptor_Curve AC2d( aLine2d, FirstPar, LastPar ); - GeomAdaptor_Surface GAsurf( theSurf ); - Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d ); - Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf ); - Adaptor3d_CurveOnSurface ConS( HC2d, HSurf ); - Standard_Real max_deviation = 0., average_deviation; - GeomLib::BuildCurve3d(Precision::Confusion(), - ConS, FirstPar, LastPar, - aCurve, max_deviation, average_deviation); - BB.UpdateEdge( anE3, aCurve, max_deviation ); - BB.UpdateEdge( anE3, aLine2d, theSurf, Loc, max_deviation ); - BB.Range( anE3, FirstPar, LastPar ); - } - } - BRepLib::SameParameter(NewFace); - BRepTools::Update(NewFace); - myWalls.Append(NewFace); - if (ArcOnV2) - { - TopoDS_Edge anArc = TopoDS::Edge(myInitOffsetEdge.Image(V2).First()); - TopoDS_Vertex arcV1, arcV2; - TopExp::Vertices(anArc, arcV1, arcV2); - Standard_Boolean ArcReverse = Standard_False; - if (!arcV1.IsSame(V3)) - { - TopoDS_Vertex aVtx = arcV1; arcV1 = arcV2; arcV2 = aVtx; - ArcReverse = Standard_True; - } - TopoDS_Edge EA1, EA2; - //EA1 = (ToReverse)? E3 : TopoDS::Edge(E3.Reversed()); - EA1 = E3; - EA1.Reverse(); - if (ToReverse) - EA1.Reverse(); - ////////////////////////////////////////////////////// - if (V2.IsSame(StartVertex)) - EA2 = StartEdge; - else - EA2 = BRepLib_MakeEdge( V2, arcV2 ); - anArc.Orientation( ((ArcReverse)? TopAbs_REVERSED : TopAbs_FORWARD) ); - if (EA1.Orientation() == TopAbs_REVERSED) - anArc.Reverse(); - EA2.Orientation(TopAbs::Reverse(EA1.Orientation())); - TopoDS_Wire arcWire; - BB.MakeWire(arcWire); - BB.Add(arcWire, EA1); - BB.Add(arcWire, anArc); - BB.Add(arcWire, EA2); - BRepLib::BuildCurves3d( arcWire, myTol ); - arcWire.Closed(Standard_True); - TopoDS_Face arcFace = BRepLib_MakeFace(arcWire, Standard_True); - BRepTools::Update(arcFace); - myWalls.Append(arcFace); - TopoDS_Shape localEA2 = EA2.Oriented(TopAbs_FORWARD); - const TopoDS_Edge& CEA2 = TopoDS::Edge(localEA2); - PrevEdge = CEA2; - PrevVertex = V2; - } - else - { + } + else + { + BB.SameParameter(E3, Standard_False); + BB.SameRange(E3, Standard_False); + BB.SameParameter(E4, Standard_False); + BB.SameRange(E4, Standard_False); + BB.UpdateEdge(E3, aLine2d, theSurf, Loc, Precision::Confusion()); + BB.Range(E3, theSurf, Loc, 0., OffsetVal); + BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion()); + BB.Range(E4, theSurf, Loc, 0., OffsetVal); + } + NewFace = BRepLib_MakeFace(theSurf, theWire); + } + } //cylinder or cone + } //if both edges are arcs of circles + if (NewFace.IsNull()) + { + BRepLib_MakeFace MF(theWire, Standard_True); //Only plane + if (MF.Error() == BRepLib_FaceDone) + { + NewFace = MF.Face(); + IsPlanar = Standard_True; + } + else //Extrusion (by thrusections) + { + Handle(Geom_Curve) EdgeCurve = BRep_Tool::Curve(anEdge, fpar, lpar); + Handle(Geom_TrimmedCurve) TrEdgeCurve = + new Geom_TrimmedCurve( EdgeCurve, fpar, lpar ); + Standard_Real fparOE, lparOE; + Handle(Geom_Curve) OffsetCurve = BRep_Tool::Curve(OE, fparOE, lparOE); + Handle(Geom_TrimmedCurve) TrOffsetCurve = + new Geom_TrimmedCurve( OffsetCurve, fparOE, lparOE ); + GeomFill_Generator ThrusecGenerator; + ThrusecGenerator.AddCurve( TrEdgeCurve ); + ThrusecGenerator.AddCurve( TrOffsetCurve ); + ThrusecGenerator.Perform( Precision::PConfusion() ); + theSurf = ThrusecGenerator.Surface(); + //theSurf = new Geom_SurfaceOfLinearExtrusion( TrOffsetCurve, OffsetDir ); + Standard_Real Uf, Ul, Vf, Vl; + theSurf->Bounds(Uf, Ul, Vf, Vl); + TopLoc_Location Loc; + EdgeLine2d = new Geom2d_Line(gp_Pnt2d(0., Vf), gp_Dir2d(1., 0.)); + BB.UpdateEdge(anEdge, EdgeLine2d, theSurf, Loc, Precision::Confusion()); + OELine2d = new Geom2d_Line(gp_Pnt2d(0., Vl), gp_Dir2d(1., 0.)); + BB.UpdateEdge(OE, OELine2d, theSurf, Loc, Precision::Confusion()); + Standard_Real UonV1 = (ToReverse)? Ul : Uf; + Standard_Real UonV2 = (ToReverse)? Uf : Ul; + aLine2d = new Geom2d_Line(gp_Pnt2d(UonV2, 0.), gp_Dir2d(0., 1.)); + aLine2d2 = new Geom2d_Line(gp_Pnt2d(UonV1, 0.), gp_Dir2d(0., 1.)); + if (E3.IsSame(E4)) + { + BB.UpdateEdge(E3, aLine2d, aLine2d2, theSurf, Loc, Precision::Confusion()); + Handle(Geom_Curve) BSplC34 = theSurf->UIso( Uf ); + BB.UpdateEdge(E3, BSplC34, Precision::Confusion()); + BB.Range(E3, Vf, Vl); + } + else + { + BB.SameParameter(E3, Standard_False); + BB.SameRange(E3, Standard_False); + BB.SameParameter(E4, Standard_False); + BB.SameRange(E4, Standard_False); + BB.UpdateEdge(E3, aLine2d, theSurf, Loc, Precision::Confusion()); + BB.Range(E3, theSurf, Loc, Vf, Vl); + BB.UpdateEdge(E4, aLine2d2, theSurf, Loc, Precision::Confusion()); + BB.Range(E4, theSurf, Loc, Vf, Vl); + Handle(Geom_Curve) BSplC3 = theSurf->UIso( UonV2 ); + BB.UpdateEdge(E3, BSplC3, Precision::Confusion()); + BB.Range(E3, Vf, Vl, Standard_True); //only for 3d curve + Handle(Geom_Curve) BSplC4 = theSurf->UIso( UonV1 ); + BB.UpdateEdge(E4, BSplC4, Precision::Confusion()); + BB.Range(E4, Vf, Vl, Standard_True); //only for 3d curve + } + NewFace = BRepLib_MakeFace(theSurf, theWire); + } + } + if (!IsPlanar) + { + Standard_Real fparOE = BAcurveOE.FirstParameter(); + Standard_Real lparOE = BAcurveOE.LastParameter(); + TopLoc_Location Loc; + if (Abs(fpar - fparOE) > Precision::Confusion()) + { + const TopoDS_Edge& anE4 = (ToReverse)? E3 : E4; + gp_Pnt2d fp2d = EdgeLine2d->Value(fpar); + gp_Pnt2d fp2dOE = OELine2d->Value(fparOE); + aLine2d2 = GCE2d_MakeLine( fp2d, fp2dOE ).Value(); + Handle(Geom_Curve) aCurve; + Standard_Real FirstPar = 0., LastPar = fp2d.Distance(fp2dOE); + Geom2dAdaptor_Curve AC2d( aLine2d2, FirstPar, LastPar ); + GeomAdaptor_Surface GAsurf( theSurf ); + Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d ); + Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf ); + Adaptor3d_CurveOnSurface ConS( HC2d, HSurf ); + Standard_Real max_deviation = 0., average_deviation; + GeomLib::BuildCurve3d(Precision::Confusion(), + ConS, FirstPar, LastPar, + aCurve, max_deviation, average_deviation); + BB.UpdateEdge( anE4, aCurve, max_deviation ); + BB.UpdateEdge( anE4, aLine2d2, theSurf, Loc, max_deviation ); + BB.Range( anE4, FirstPar, LastPar ); + } + if (Abs(lpar - lparOE) > Precision::Confusion()) + { + const TopoDS_Edge& anE3 = (ToReverse)? E4 : E3; + gp_Pnt2d lp2d = EdgeLine2d->Value(lpar); + gp_Pnt2d lp2dOE = OELine2d->Value(lparOE); + aLine2d = GCE2d_MakeLine( lp2d, lp2dOE ).Value(); + Handle(Geom_Curve) aCurve; + Standard_Real FirstPar = 0., LastPar = lp2d.Distance(lp2dOE); + Geom2dAdaptor_Curve AC2d( aLine2d, FirstPar, LastPar ); + GeomAdaptor_Surface GAsurf( theSurf ); + Handle(Geom2dAdaptor_HCurve) HC2d = new Geom2dAdaptor_HCurve( AC2d ); + Handle(GeomAdaptor_HSurface) HSurf = new GeomAdaptor_HSurface( GAsurf ); + Adaptor3d_CurveOnSurface ConS( HC2d, HSurf ); + Standard_Real max_deviation = 0., average_deviation; + GeomLib::BuildCurve3d(Precision::Confusion(), + ConS, FirstPar, LastPar, + aCurve, max_deviation, average_deviation); + BB.UpdateEdge( anE3, aCurve, max_deviation ); + BB.UpdateEdge( anE3, aLine2d, theSurf, Loc, max_deviation ); + BB.Range( anE3, FirstPar, LastPar ); + } + } + BRepLib::SameParameter(NewFace); + BRepTools::Update(NewFace); + myWalls.Append(NewFace); + if (ArcOnV2) + { + TopoDS_Edge anArc = TopoDS::Edge(myInitOffsetEdge.Image(V2).First()); + TopoDS_Vertex arcV1, arcV2; + TopExp::Vertices(anArc, arcV1, arcV2); + Standard_Boolean ArcReverse = Standard_False; + if (!arcV1.IsSame(V3)) + { + TopoDS_Vertex aVtx = arcV1; arcV1 = arcV2; arcV2 = aVtx; + ArcReverse = Standard_True; + } + TopoDS_Edge EA1, EA2; + //EA1 = (ToReverse)? E3 : TopoDS::Edge(E3.Reversed()); + EA1 = E3; + EA1.Reverse(); + if (ToReverse) + EA1.Reverse(); + ////////////////////////////////////////////////////// + if (V2.IsSame(StartVertex)) + EA2 = StartEdge; + else + EA2 = BRepLib_MakeEdge( V2, arcV2 ); + anArc.Orientation( ((ArcReverse)? TopAbs_REVERSED : TopAbs_FORWARD) ); + if (EA1.Orientation() == TopAbs_REVERSED) + anArc.Reverse(); + EA2.Orientation(TopAbs::Reverse(EA1.Orientation())); + TopoDS_Wire arcWire; + BB.MakeWire(arcWire); + BB.Add(arcWire, EA1); + BB.Add(arcWire, anArc); + BB.Add(arcWire, EA2); + BRepLib::BuildCurves3d( arcWire, myTol ); + arcWire.Closed(Standard_True); + TopoDS_Face arcFace = BRepLib_MakeFace(arcWire, Standard_True); + BRepTools::Update(arcFace); + myWalls.Append(arcFace); + TopoDS_Shape localEA2 = EA2.Oriented(TopAbs_FORWARD); + const TopoDS_Edge& CEA2 = TopoDS::Edge(localEA2); + PrevEdge = CEA2; + PrevVertex = V2; + } + else + { if (isBuildFromScratch) { PrevEdge = TopoDS::Edge(E4); @@ -2905,21 +3000,20 @@ void BRepOffset_MakeOffset::MakeMissingWalls () } else { - PrevEdge = E3; - PrevVertex = V2; - } + PrevEdge = E3; + PrevVertex = V2; + } } - FirstStep = Standard_False; - } + FirstStep = Standard_False; } + } } //======================================================================= //function : MakeShells //purpose : //======================================================================= - -void BRepOffset_MakeOffset::MakeShells () +void BRepOffset_MakeOffset::MakeShells() { #ifdef OCCT_DEBUG if (ChronBuild) { @@ -2928,30 +3022,264 @@ void BRepOffset_MakeOffset::MakeShells () Clock.Start(); } #endif - BRepTools_Quilt Glue; + + //if ((myJoin == GeomAbs_Intersection) && myInter) { + // + // make shells using MakerVolume algorithm + // + TopTools_IndexedDataMapOfShapeListOfShape anOrigins; + // + BOPCol_ListOfShape aLSF; const TopTools_ListOfShape& R = myImageOffset.Roots(); TopTools_ListIteratorOfListOfShape it(R); - - for ( ; it.More(); it.Next()) { + // + for (; it.More(); it.Next()) { TopTools_ListOfShape Image; myImageOffset.LastImage(it.Value(),Image); TopTools_ListIteratorOfListOfShape it2(Image); - for ( ; it2.More(); it2.Next()) { - Glue.Add(it2.Value()); + for (; it2.More(); it2.Next()) { + const TopoDS_Shape& aF = it2.Value(); + aLSF.Append(aF); + // + if (anOrigins.Contains(aF)) { + anOrigins.ChangeFromKey(aF).Append(it.Value()); + } + else { + TopTools_ListOfShape aLOr; + aLOr.Append(it.Value()); + anOrigins.Add(aF, aLOr); + } } } - - if (myThickening) - { + // + if (myThickening) { TopExp_Explorer Explo(myShape, TopAbs_FACE); - for (; Explo.More(); Explo.Next()) - Glue.Add(Explo.Current()); - - for (it.Initialize(myWalls); it.More(); it.Next()) - Glue.Add(it.Value()); + for (; Explo.More(); Explo.Next()) { + const TopoDS_Shape& aF = Explo.Current(); + aLSF.Append(aF); + } + // + it.Initialize(myWalls); + for (; it.More(); it.Next()) { + const TopoDS_Shape& aF = it.Value(); + aLSF.Append(aF); + } + } + // + Standard_Boolean bDone = Standard_False; + // build all possible solids + /*if (!myThickening && !myFaces.IsEmpty()) { + TopExp_Explorer Explo(myShape, TopAbs_FACE); + for (; Explo.More(); Explo.Next()) { + const TopoDS_Shape& aF = Explo.Current(); + aLSF.Append(aF); + } + }*/ + // + Standard_Boolean bFaces = !myFaces.IsEmpty(); + // + if ((myJoin == GeomAbs_Intersection) && myInter) { + Standard_Integer i, aNb; + TopTools_ListIteratorOfListOfShape aItLS, aItLS1; + BRep_Builder aBB; + // + TopoDS_Compound aCSF; + aBB.MakeCompound(aCSF); + // + BOPAlgo_Builder aGF; + // + aGF.SetArguments(aLSF); + aGF.Perform(); + bDone = (aGF.ErrorStatus() == 0); + if (bDone) { + const TopoDS_Shape& aR = aGF.Shape(); + TopExp_Explorer aExp(aR, TopAbs_FACE); + aLSF.Clear(); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aF = aExp.Current(); + aLSF.Append(aF); + aBB.Add(aCSF, aF); + } + // + bDone = ((myOffset > 0) || !bFaces); + if (bDone) { + UpdateOrigins(anOrigins, aGF); + // + BOPAlgo_MakerVolume aMV1; + // + aMV1.AddArgument(aCSF); + aMV1.SetIntersect(Standard_False); + // + if (bFaces) { + aNb = myFaces.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopoDS_Shape& aFEx = myFaces(i); + aMV1.AddArgument(aFEx); + } + aMV1.SetIntersect(Standard_True); + } + // + aMV1.Perform(); + bDone = (aMV1.ErrorStatus() == 0); + if (bDone) { + // + TopoDS_Shape aResult = aMV1.Shape(); + // + TopTools_IndexedMapOfShape aMFResult; + TopExp::MapShapes(aResult, TopAbs_FACE, aMFResult); + // + // check the result + Standard_Boolean bGood = Standard_True; + if (myRemoveInvalidFaces) { + BOPCol_ListIteratorOfListOfShape aItLSF(aLSF); + for (; aItLSF.More(); aItLSF.Next()) { + const TopoDS_Shape& aFx = aItLSF.Value(); + if (!aMFResult.Contains(aFx)) { + const TopTools_ListOfShape& aLFMx = aMV1.Modified(aFx); + if (aLFMx.IsEmpty()) { + bGood = Standard_False; + break; + } + } + } + } + // + TopoDS_Compound aShells; + // + aBB.MakeCompound(aShells); + // + if (!bGood) { + myOffsetShape = aShells; + } + else { + // collect images of the faces + TopTools_MapOfShape aMFaces; + aNb = myFaces.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopoDS_Shape& aFEx = myFaces(i); + const TopTools_ListOfShape& aLFEx = aMV1.Modified(aFEx); + if (!aLFEx.IsEmpty()) { + aItLS.Initialize(aLFEx); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Face& aFExIm = *(TopoDS_Face*)&aItLS.Value(); + aMFaces.Add(aFExIm); + } + } + else { + aMFaces.Add(aFEx); + } + } + // + if (aResult.ShapeType() == TopAbs_COMPOUND) { + // collect faces attached to only one solid + BOPCol_IndexedDataMapOfShapeListOfShape aMFS; + BOPCol_ListOfShape aLSF2; + // + BOPTools::MapShapesAndAncestors(aResult, TopAbs_FACE, TopAbs_SOLID, aMFS); + aNb = aMFS.Extent(); + bDone = (aNb > 0); + // + if (bDone) { + for (i = 1; i <= aNb; ++i) { + const BOPCol_ListOfShape& aLSx = aMFS(i); + if (aLSx.Extent() == 1) { + const TopoDS_Shape& aFx = aMFS.FindKey(i); + aLSF2.Append(aFx); + } + } + // + // make solids from the new list + BOPAlgo_MakerVolume aMV2; + // + aMV2.SetArguments(aLSF2); + aMV2.SetIntersect(Standard_False); + // + aMV2.Perform(); + bDone = (aMV2.ErrorStatus() == 0); + if (bDone) { + aResult = aMV2.Shape(); + if (aResult.ShapeType() == TopAbs_COMPOUND) { + BOPCol_ListOfShape aLSF3; + // + aExp.Init(aResult, TopAbs_FACE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current(); + // + // check orientation + if (!anOrigins.Contains(aF)) { + aLSF3.Append(aF); + continue; + } + // + const TopTools_ListOfShape& aLFOr = anOrigins.FindFromKey(aF); + aItLS.Initialize(aLFOr); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Face& aFOr = *(TopoDS_Face*)&aItLS.Value(); + // + if (CheckNormals(aF, aFOr)) { + aLSF3.Append(aF); + break; + } + } + } + // + // make solid containing most outer faces + BOPAlgo_MakerVolume aMV3; + // + aMV3.SetArguments(aLSF3); + aMV3.SetIntersect(Standard_False); + // + aMV3.Perform(); + bDone = (aMV3.ErrorStatus() == 0); + if (bDone) { + aResult = aMV3.Shape(); + } + } + } + } + } + // + TopExp_Explorer aExp(aResult, TopAbs_SHELL); + bDone = aExp.More(); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shell& aSh = *(TopoDS_Shell*)&aExp.Current(); + // + TopoDS_Shell aShellNew; + if (bFaces) { + aBB.MakeShell(aShellNew); + // + TopExp_Explorer aExp(aSh, TopAbs_FACE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Face& aFSh = *(TopoDS_Face*)&aExp.Current(); + if (!aMFaces.Contains(aFSh)) { + aBB.Add(aShellNew, aFSh); + } + } + } + else { + aShellNew = aSh; + } + // + aBB.Add(aShells, aShellNew); + } + myOffsetShape = aShells; + } + } + } + } + } + // + if (!bDone) { + BRepTools_Quilt Glue; + BOPCol_ListIteratorOfListOfShape aItLS; + // + aItLS.Initialize(aLSF); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Shape& aF = aItLS.Value(); + Glue.Add(aF); + } + myOffsetShape = Glue.Shells(); } - - myOffsetShape = Glue.Shells(); // //Set correct value for closed flag TopExp_Explorer Explo(myOffsetShape, TopAbs_SHELL); @@ -2965,14 +3293,13 @@ void BRepOffset_MakeOffset::MakeShells () aS.Closed(Standard_True); } } - } + } } //======================================================================= //function : MakeSolid //purpose : //======================================================================= - void BRepOffset_MakeOffset::MakeSolid () { if (myOffsetShape.IsNull()) return; @@ -3068,7 +3395,6 @@ void BRepOffset_MakeOffset::MakeSolid () //function : SelectShells //purpose : //======================================================================= - void BRepOffset_MakeOffset::SelectShells () { TopTools_MapOfShape FreeEdges; @@ -3083,7 +3409,7 @@ void BRepOffset_MakeOffset::SelectShells () const TopTools_ListOfShape& LA = myAnalyse.Ancestors(E); if (LA.Extent() < 2) { if (myAnalyse.Type(E).First().Type() == BRepOffset_FreeBoundary) { - FreeEdges.Add(E); + FreeEdges.Add(E); } } } @@ -3098,7 +3424,6 @@ void BRepOffset_MakeOffset::SelectShells () //function : OffsetFacesFromShapes //purpose : //======================================================================= - const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetFacesFromShapes() const { return myInitOffsetFace; @@ -3110,7 +3435,6 @@ const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetFacesFromShapes() const //function : GetJoinType //purpose : Query offset join type. //======================================================================= - GeomAbs_JoinType BRepOffset_MakeOffset::GetJoinType() const { return myJoin; @@ -3120,7 +3444,6 @@ GeomAbs_JoinType BRepOffset_MakeOffset::GetJoinType() const //function : OffsetEdgesFromShapes //purpose : //======================================================================= - const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetEdgesFromShapes() const { return myInitOffsetEdge; @@ -3132,19 +3455,15 @@ const BRepAlgo_Image& BRepOffset_MakeOffset::OffsetEdgesFromShapes() const //function : ClosingFaces //purpose : //======================================================================= - const TopTools_IndexedMapOfShape& BRepOffset_MakeOffset::ClosingFaces () const { return myFaces; } - - //======================================================================= //function : EncodeRegularity //purpose : //======================================================================= - void BRepOffset_MakeOffset::EncodeRegularity () { #ifdef OCCT_DEBUG @@ -3195,38 +3514,38 @@ void BRepOffset_MakeOffset::EncodeRegularity () if (F1.IsSame(F2)) { if (BRep_Tool::IsClosed(OE,F1)) { - // Temporary Debug for the Bench. - // Check with YFR. - // In mode intersection, the edges are not coded in myInitOffsetEdge - // so, manage case by case - // Note DUB; for Hidden parts, it is NECESSARY to code CN - // Analytic Surfaces. - if (myJoin == GeomAbs_Intersection) { - BRepAdaptor_Surface BS(F1,Standard_False); - GeomAbs_SurfaceType SType = BS.GetType(); - if (SType == GeomAbs_Cylinder || - SType == GeomAbs_Cone || - SType == GeomAbs_Sphere || - SType == GeomAbs_Torus ) { - B.Continuity(OE,F1,F1,GeomAbs_CN); - } - else { - // See YFR : MaJ of myInitOffsetFace - } - } - else if (myInitOffsetEdge.IsImage(ROE)) { - if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) { - const TopoDS_Face& FRoot = TopoDS::Face(Root1); - const TopoDS_Edge& EI = TopoDS::Edge(myInitOffsetEdge.ImageFrom(ROE)); - GeomAbs_Shape Conti = BRep_Tool::Continuity(EI,FRoot,FRoot); - if (Conti == GeomAbs_CN) { - B.Continuity(OE,F1,F1,GeomAbs_CN); - } - else if ( Conti > GeomAbs_C0) { - B.Continuity(OE,F1,F1,GeomAbs_G1); - } - } - } + // Temporary Debug for the Bench. + // Check with YFR. + // In mode intersection, the edges are not coded in myInitOffsetEdge + // so, manage case by case + // Note DUB; for Hidden parts, it is NECESSARY to code CN + // Analytic Surfaces. + if (myJoin == GeomAbs_Intersection) { + BRepAdaptor_Surface BS(F1,Standard_False); + GeomAbs_SurfaceType SType = BS.GetType(); + if (SType == GeomAbs_Cylinder || + SType == GeomAbs_Cone || + SType == GeomAbs_Sphere || + SType == GeomAbs_Torus ) { + B.Continuity(OE,F1,F1,GeomAbs_CN); + } + else { + // See YFR : MaJ of myInitOffsetFace + } + } + else if (myInitOffsetEdge.IsImage(ROE)) { + if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) { + const TopoDS_Face& FRoot = TopoDS::Face(Root1); + const TopoDS_Edge& EI = TopoDS::Edge(myInitOffsetEdge.ImageFrom(ROE)); + GeomAbs_Shape Conti = BRep_Tool::Continuity(EI,FRoot,FRoot); + if (Conti == GeomAbs_CN) { + B.Continuity(OE,F1,F1,GeomAbs_CN); + } + else if ( Conti > GeomAbs_C0) { + B.Continuity(OE,F1,F1,GeomAbs_G1); + } + } + } } continue; } @@ -3245,32 +3564,32 @@ void BRepOffset_MakeOffset::EncodeRegularity () TopoDS_Vertex V1,V2; TopExp::Vertices(TopoDS::Edge(Root1), V1, V2); if ( V1.IsSame(Root2) || V2.IsSame(Root2)) { - B.Continuity(OE,F1,F2,GeomAbs_G1); + B.Continuity(OE,F1,F2,GeomAbs_G1); } } else if ( Type1 == TopAbs_VERTEX && Type2 == TopAbs_EDGE) { TopoDS_Vertex V1,V2; TopExp::Vertices(TopoDS::Edge(Root2), V1, V2); if ( V1.IsSame(Root1) || V2.IsSame(Root1)) { - B.Continuity(OE,F1,F2,GeomAbs_G1); + B.Continuity(OE,F1,F2,GeomAbs_G1); } } else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_EDGE) { TopExp_Explorer exp2(Root1,TopAbs_EDGE); for ( ; exp2.More(); exp2.Next()) { - if ( exp2.Current().IsSame(Root2)) { - B.Continuity(OE,F1,F2,GeomAbs_G1); - break; - } + if ( exp2.Current().IsSame(Root2)) { + B.Continuity(OE,F1,F2,GeomAbs_G1); + break; + } } } else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_FACE) { TopExp_Explorer exp2(Root2,TopAbs_EDGE); for ( ; exp2.More(); exp2.Next()) { - if ( exp2.Current().IsSame(Root1)) { - B.Continuity(OE,F1,F2,GeomAbs_G1); - break; - } + if ( exp2.Current().IsSame(Root1)) { + B.Continuity(OE,F1,F2,GeomAbs_G1); + break; + } } } else if ( Type1 == TopAbs_FACE && Type2 == TopAbs_FACE) { @@ -3278,42 +3597,42 @@ void BRepOffset_MakeOffset::EncodeRegularity () // the initial shape, they will be tangent in the offset shape TopTools_ListOfShape LE,LV; BRepOffset_Tool::HasCommonShapes(TopoDS::Face(Root1), - TopoDS::Face(Root2), - LE,LV); + TopoDS::Face(Root2), + LE,LV); if ( LE.Extent() == 1) { - const TopoDS_Edge& Ed = TopoDS::Edge(LE.First()); - if ( myAnalyse.HasAncestor(Ed)) { - const BRepOffset_ListOfInterval& LI = myAnalyse.Type(Ed); - if (LI.Extent() == 1 && - LI.First().Type() == BRepOffset_Tangent) { - B.Continuity(OE,F1,F2,GeomAbs_G1); - } - } + const TopoDS_Edge& Ed = TopoDS::Edge(LE.First()); + if ( myAnalyse.HasAncestor(Ed)) { + const BRepOffset_ListOfInterval& LI = myAnalyse.Type(Ed); + if (LI.Extent() == 1 && + LI.First().Type() == BRepOffset_Tangent) { + B.Continuity(OE,F1,F2,GeomAbs_G1); + } + } } } else if ( Type1 == TopAbs_EDGE && Type2 == TopAbs_EDGE) { TopTools_ListOfShape LV; TopExp_Explorer exp1,exp2; for (exp1.Init(Root1,TopAbs_VERTEX); exp1.More(); exp1.Next()) { - TopExp_Explorer exp2(F2,TopAbs_EDGE); - for (exp2.Init(Root2,TopAbs_VERTEX); exp2.More(); exp2.Next()) { - if (exp1.Current().IsSame(exp2.Current())) { - LV.Append(exp1.Current()); - } - } + TopExp_Explorer exp2(F2,TopAbs_EDGE); + for (exp2.Init(Root2,TopAbs_VERTEX); exp2.More(); exp2.Next()) { + if (exp1.Current().IsSame(exp2.Current())) { + LV.Append(exp1.Current()); + } + } } if ( LV.Extent() == 1) { - TopTools_ListOfShape LEdTg; - myAnalyse.TangentEdges(TopoDS::Edge(Root1), - TopoDS::Vertex(LV.First()), - LEdTg); - TopTools_ListIteratorOfListOfShape it(LEdTg); - for (; it.More(); it.Next()) { - if ( it.Value().IsSame(Root2)) { - B.Continuity(OE,F1,F2,GeomAbs_G1); - break; - } - } + TopTools_ListOfShape LEdTg; + myAnalyse.TangentEdges(TopoDS::Edge(Root1), + TopoDS::Vertex(LV.First()), + LEdTg); + TopTools_ListIteratorOfListOfShape it(LEdTg); + for (; it.More(); it.Next()) { + if ( it.Value().IsSame(Root2)) { + B.Continuity(OE,F1,F2,GeomAbs_G1); + break; + } + } } } } @@ -3324,131 +3643,6 @@ void BRepOffset_MakeOffset::EncodeRegularity () } - -//======================================================================= -//function : UpDateTolerance -//purpose : -//======================================================================= - -void UpdateTolerance (TopoDS_Shape& S, - const TopTools_IndexedMapOfShape& Faces) -{ - BRep_Builder B; - TopTools_MapOfShape View; - TopoDS_Vertex V[2]; - - // The edges of caps are not modified. - Standard_Integer j; - for (j = 1; j <= Faces.Extent(); j++) { - const TopoDS_Shape& F = Faces(j); - TopExp_Explorer Exp; - for (Exp.Init(F,TopAbs_EDGE); Exp.More(); Exp.Next()) { - View.Add(Exp.Current()); - } - } - - TopExp_Explorer Exp; - for (Exp.Init(S,TopAbs_EDGE); Exp.More(); Exp.Next()) { - TopoDS_Edge E = TopoDS::Edge(Exp.Current()); - if (View.Add(E)) { - Handle(BRepCheck_Edge) EdgeCorrector = new BRepCheck_Edge(E); - Standard_Real Tol = EdgeCorrector->Tolerance(); - B.UpdateEdge (E,Tol); - - // Update the vertices. - TopExp::Vertices(E,V[0],V[1]); - - for (Standard_Integer i = 0 ; i <=1 ; i++) { - if (View.Add(V[i])) { - Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V[i].TShape()); - TV->Tolerance(0.); - Handle(BRepCheck_Vertex) VertexCorrector = new BRepCheck_Vertex(V[i]); - B.UpdateVertex (V[i],VertexCorrector->Tolerance()); - // use the occasion to clean the vertices. - (TV->ChangePoints()).Clear(); - } - B.UpdateVertex(V[i],Tol); - } - } - } -} - -//======================================================================= -//function : CorrectSolid -//purpose : -//======================================================================= -void CorrectSolid(TopoDS_Solid& theSol, TopTools_ListOfShape& theSolList) -{ - BRep_Builder aBB; - TopoDS_Shape anOuterShell; - NCollection_List aVols; - Standard_Real aVolMax = 0., anOuterVol = 0.; - - TopoDS_Iterator anIt(theSol); - for(; anIt.More(); anIt.Next()) - { - const TopoDS_Shape& aSh = anIt.Value(); - GProp_GProps aVProps; - BRepGProp::VolumeProperties(aSh, aVProps, Standard_True); - if(Abs(aVProps.Mass()) > aVolMax) - { - anOuterVol = aVProps.Mass(); - aVolMax = Abs(anOuterVol); - anOuterShell = aSh; - } - aVols.Append(aVProps.Mass()); - } - // - if(anOuterVol < 0.) - { - anOuterShell.Reverse(); - } - TopoDS_Solid aNewSol; - aBB.MakeSolid(aNewSol); - aNewSol.Closed(Standard_True); - aBB.Add(aNewSol, anOuterShell); - BRepClass3d_SolidClassifier aSolClass(aNewSol); - // - anIt.Initialize(theSol); - NCollection_List::Iterator aVIt(aVols); - for(; anIt.More(); anIt.Next(), aVIt.Next()) - { - TopoDS_Shell aSh = TopoDS::Shell(anIt.Value()); - if(aSh.IsSame(anOuterShell)) - { - continue; - } - else - { - TopExp_Explorer aVExp(aSh, TopAbs_VERTEX); - const TopoDS_Vertex& aV = TopoDS::Vertex(aVExp.Current()); - gp_Pnt aP = BRep_Tool::Pnt(aV); - aSolClass.Perform(aP, BRep_Tool::Tolerance(aV)); - if(aSolClass.State() == TopAbs_IN) - { - if(aVIt.Value() > 0.) - { - aSh.Reverse(); - } - aBB.Add(aNewSol, aSh); - } - else - { - if(aVIt.Value() < 0.) - { - aSh.Reverse(); - } - TopoDS_Solid aSol; - aBB.MakeSolid(aSol); - aSol.Closed(Standard_True); - aBB.Add(aSol, aSh); - theSolList.Append(aSol); - } - } - } - theSol = aNewSol; -} - //======================================================================= //function : CheckInputData //purpose : Check input data for possiblity of offset perform. @@ -3612,7 +3806,6 @@ Standard_Boolean BRepOffset_MakeOffset::CheckInputData() return Standard_True; } - //======================================================================= //function : CheckInputData //purpose : Check input data for possiblity of offset perform. @@ -3621,3 +3814,1181 @@ const TopoDS_Shape& BRepOffset_MakeOffset::GetBadShape() const { return myBadShape; } + +//======================================================================= +//function : RemoveInternalEdges +//purpose : +//======================================================================= +void BRepOffset_MakeOffset::RemoveInternalEdges() +{ + Standard_Boolean bRemoveWire, bRemoveEdge; + TopExp_Explorer aExpF, aExpW, aExpE; + TopTools_IndexedDataMapOfShapeListOfShape aDMELF; + // + TopExp::MapShapesAndAncestors(myOffsetShape, TopAbs_EDGE, TopAbs_FACE, aDMELF); + // + aExpF.Init(myOffsetShape, TopAbs_FACE); + for (; aExpF.More(); aExpF.Next()) { + TopoDS_Face& aF = *(TopoDS_Face*)&aExpF.Current(); + // + TopTools_ListOfShape aLIW; + // + aExpW.Init(aF, TopAbs_WIRE); + for (; aExpW.More(); aExpW.Next()) { + TopoDS_Wire& aW = *(TopoDS_Wire*)&aExpW.Current(); + // + bRemoveWire = Standard_True; + TopTools_ListOfShape aLIE; + // + aExpE.Init(aW, TopAbs_EDGE); + for (; aExpE.More(); aExpE.Next()) { + const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExpE.Current(); + if (aE.Orientation() != TopAbs_INTERNAL) { + bRemoveWire = Standard_False; + continue; + } + // + const TopTools_ListOfShape& aLF = aDMELF.FindFromKey(aE); + bRemoveEdge = (aLF.Extent() == 1); + if (bRemoveEdge) { + aLIE.Append(aE); + } + else { + bRemoveWire = Standard_False; + } + } + // + if (bRemoveWire) { + aLIW.Append(aW); + } + else if (aLIE.Extent()) { + RemoveShapes(aW, aLIE); + } + } + // + if (aLIW.Extent()) { + RemoveShapes(aF, aLIW); + } + } +} + +//======================================================================= +// static methods implementation +//======================================================================= + +//======================================================================= +//function : RemoveShapes +//purpose : Removes the shapes from the shape +//======================================================================= +void RemoveShapes(TopoDS_Shape& theS, + const TopTools_ListOfShape& theLS) +{ + BRep_Builder aBB; + // + Standard_Boolean bFree = theS.Free(); + theS.Free(Standard_True); + // + TopTools_ListIteratorOfListOfShape aIt(theLS); + for (; aIt.More(); aIt.Next()) { + const TopoDS_Shape& aSI = aIt.Value(); + aBB.Remove(theS, aSI); + } + // + theS.Free(bFree); +} + +//======================================================================= +//function : UpDateTolerance +//purpose : +//======================================================================= +void UpdateTolerance (TopoDS_Shape& S, + const TopTools_IndexedMapOfShape& Faces) +{ + BRep_Builder B; + TopTools_MapOfShape View; + TopoDS_Vertex V[2]; + + // The edges of caps are not modified. + Standard_Integer j; + for (j = 1; j <= Faces.Extent(); j++) { + const TopoDS_Shape& F = Faces(j); + TopExp_Explorer Exp; + for (Exp.Init(F,TopAbs_EDGE); Exp.More(); Exp.Next()) { + View.Add(Exp.Current()); + } + } + + TopExp_Explorer Exp; + for (Exp.Init(S,TopAbs_EDGE); Exp.More(); Exp.Next()) { + TopoDS_Edge E = TopoDS::Edge(Exp.Current()); + if (View.Add(E)) { + Handle(BRepCheck_Edge) EdgeCorrector = new BRepCheck_Edge(E); + Standard_Real Tol = EdgeCorrector->Tolerance(); + B.UpdateEdge (E,Tol); + + // Update the vertices. + TopExp::Vertices(E,V[0],V[1]); + + for (Standard_Integer i = 0 ; i <=1 ; i++) { + if (View.Add(V[i])) { + Handle(BRep_TVertex) TV = Handle(BRep_TVertex)::DownCast(V[i].TShape()); + TV->Tolerance(0.); + Handle(BRepCheck_Vertex) VertexCorrector = new BRepCheck_Vertex(V[i]); + B.UpdateVertex (V[i],VertexCorrector->Tolerance()); + // use the occasion to clean the vertices. + (TV->ChangePoints()).Clear(); + } + B.UpdateVertex(V[i],Tol); + } + } + } +} + +//======================================================================= +//function : FindParameter +//purpose : +//======================================================================= +Standard_Boolean FindParameter(const TopoDS_Vertex& V, + const TopoDS_Edge& E, + Standard_Real& U) +{ + // Search the vertex in the edge + + Standard_Boolean rev = Standard_False; + TopoDS_Shape VF; + TopAbs_Orientation orient = TopAbs_INTERNAL; + + TopoDS_Iterator itv(E.Oriented(TopAbs_FORWARD)); + + // if the edge has no vertices + // and is degenerated use the vertex orientation + // RLE, june 94 + + if (!itv.More() && BRep_Tool::Degenerated(E)) { + orient = V.Orientation(); + } + + while (itv.More()) { + const TopoDS_Shape& Vcur = itv.Value(); + if (V.IsSame(Vcur)) { + if (VF.IsNull()) { + VF = Vcur; + } + else { + rev = E.Orientation() == TopAbs_REVERSED; + if (Vcur.Orientation() == V.Orientation()) { + VF = Vcur; + } + } + } + itv.Next(); + } + + if (!VF.IsNull()) orient = VF.Orientation(); + + Standard_Real f,l; + + if (orient == TopAbs_FORWARD) { + BRep_Tool::Range(E,f,l); + //return (rev) ? l : f; + U = (rev) ? l : f; + return Standard_True; + } + + else if (orient == TopAbs_REVERSED) { + BRep_Tool::Range(E,f,l); + //return (rev) ? f : l; + U = (rev) ? f : l; + return Standard_True; + } + + else { + TopLoc_Location L; + const Handle(Geom_Curve)& C = BRep_Tool::Curve(E,L,f,l); + L = L.Predivided(V.Location()); + if (!C.IsNull() || BRep_Tool::Degenerated(E)) { + BRep_ListIteratorOfListOfPointRepresentation itpr + ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points()); + + while (itpr.More()) { + const Handle(BRep_PointRepresentation)& pr = itpr.Value(); + if (pr->IsPointOnCurve(C,L)) { + Standard_Real p = pr->Parameter(); + Standard_Real res = p;// SVV 4 nov 99 - to avoid warnings on Linux + if (!C.IsNull()) { + // Closed curves RLE 16 june 94 + if (Precision::IsNegativeInfinite(f)) + { + //return pr->Parameter();//p; + U = pr->Parameter(); + return Standard_True; + } + if (Precision::IsPositiveInfinite(l)) + { + //return pr->Parameter();//p; + U = pr->Parameter(); + return Standard_True; + } + gp_Pnt Pf = C->Value(f).Transformed(L.Transformation()); + gp_Pnt Pl = C->Value(l).Transformed(L.Transformation()); + Standard_Real tol = BRep_Tool::Tolerance(V); + if (Pf.Distance(Pl) < tol) { + if (Pf.Distance(BRep_Tool::Pnt(V)) < tol) { + if (V.Orientation() == TopAbs_FORWARD) res = f;//p = f; + else res = l;//p = l; + } + } + } + //return res;//p; + U = res; + return Standard_True; + } + itpr.Next(); + } + } + else { + // no 3d curve !! + // let us try with the first pcurve + Handle(Geom2d_Curve) PC; + Handle(Geom_Surface) S; + BRep_Tool::CurveOnSurface(E,PC,S,L,f,l); + L = L.Predivided(V.Location()); + BRep_ListIteratorOfListOfPointRepresentation itpr + ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points()); + + while (itpr.More()) { + const Handle(BRep_PointRepresentation)& pr = itpr.Value(); + if (pr->IsPointOnCurveOnSurface(PC,S,L)) { + Standard_Real p = pr->Parameter(); + // Closed curves RLE 16 june 94 + if (PC->IsClosed()) { + if ((p == PC->FirstParameter()) || + (p == PC->LastParameter())) { + if (V.Orientation() == TopAbs_FORWARD) p = PC->FirstParameter(); + else p = PC->LastParameter(); + } + } + //return p; + U = p; + return Standard_True; + } + itpr.Next(); + } + } + } + + //Standard_NoSuchObject::Raise("BRep_Tool:: no parameter on edge"); + return Standard_False; +} + +//======================================================================= +//function : GetEdgePoints +//purpose : gets the first, last and middle points of the edge +//======================================================================= +void GetEdgePoints(const TopoDS_Edge& anEdge, + const TopoDS_Face& aFace, + gp_Pnt& fPnt, gp_Pnt& mPnt, + gp_Pnt& lPnt) +{ + Standard_Real f, l; + Handle(Geom2d_Curve) theCurve = BRep_Tool::CurveOnSurface( anEdge, aFace, f, l ); + gp_Pnt2d fPnt2d = theCurve->Value(f); + gp_Pnt2d lPnt2d = theCurve->Value(l); + gp_Pnt2d mPnt2d = theCurve->Value(0.5*(f + l)); + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); + fPnt = aSurf->Value(fPnt2d.X(),fPnt2d.Y()); + lPnt = aSurf->Value(lPnt2d.X(),lPnt2d.Y()); + mPnt = aSurf->Value(mPnt2d.X(), mPnt2d.Y()); +} + +//======================================================================= +//function : FillContours +//purpose : fills free boundary contours and faces connected (MapEF) +//======================================================================= +void FillContours(const TopoDS_Shape& aShape, + const BRepOffset_Analyse& Analyser, + TopTools_DataMapOfShapeListOfShape& Contours, + TopTools_DataMapOfShapeShape& MapEF) +{ + TopTools_ListOfShape Edges; + + TopExp_Explorer Explo(aShape, TopAbs_FACE); + BRepTools_WireExplorer Wexp; + + for (; Explo.More(); Explo.Next()) + { + TopoDS_Face aFace = TopoDS::Face(Explo.Current()); + TopoDS_Iterator itf(aFace); + for (; itf.More(); itf.Next()) + { + TopoDS_Wire aWire = TopoDS::Wire(itf.Value()); + for (Wexp.Init(aWire, aFace); Wexp.More(); Wexp.Next()) + { + TopoDS_Edge anEdge = Wexp.Current(); + if (BRep_Tool::Degenerated(anEdge)) + continue; + const BRepOffset_ListOfInterval& Lint = Analyser.Type(anEdge); + if (!Lint.IsEmpty() && Lint.First().Type() == BRepOffset_FreeBoundary) + { + MapEF.Bind(anEdge, aFace); + Edges.Append(anEdge); + } + } + } + } + + TopTools_ListIteratorOfListOfShape itl; + while (!Edges.IsEmpty()) + { + TopoDS_Edge StartEdge = TopoDS::Edge(Edges.First()); + Edges.RemoveFirst(); + TopoDS_Vertex StartVertex, CurVertex; + TopExp::Vertices(StartEdge, StartVertex, CurVertex, Standard_True); + TopTools_ListOfShape aContour; + aContour.Append(StartEdge); + while (!CurVertex.IsSame(StartVertex)) + for (itl.Initialize(Edges); itl.More(); itl.Next()) + { + TopoDS_Edge anEdge = TopoDS::Edge(itl.Value()); + TopoDS_Vertex V1, V2; + TopExp::Vertices(anEdge, V1, V2); + if (V1.IsSame(CurVertex) || V2.IsSame(CurVertex)) + { + aContour.Append(anEdge); + CurVertex = (V1.IsSame(CurVertex))? V2 : V1; + Edges.Remove(itl); + break; + } + } + Contours.Bind(StartVertex, aContour); + } +} + +//======================================================================= +//function : RemoveCorks +//purpose : +//======================================================================= +void RemoveCorks (TopoDS_Shape& S, + TopTools_IndexedMapOfShape& Faces) +{ + TopoDS_Compound SS; + BRep_Builder B; + B.MakeCompound (SS); + //----------------------------------------------------- + // Construction of a shape without caps. + // and Orientation of caps as in shape S. + //----------------------------------------------------- + TopExp_Explorer exp(S,TopAbs_FACE); + for (; exp.More(); exp.Next()) { + const TopoDS_Shape& Cork = exp.Current(); + if (!Faces.Contains(Cork)) { + B.Add(SS,Cork); + } + else { + //Faces.Remove (Cork); + //begin instead of Remove// + TopoDS_Shape LastShape = Faces(Faces.Extent()); + Faces.RemoveLast(); + if (Faces.FindIndex(Cork) != 0) + Faces.Substitute(Faces.FindIndex(Cork), LastShape); + //end instead of Remove // + Faces.Add(Cork); // to reset it with proper orientation. + } + } + S = SS; +#ifdef DRAW + if ( AffichOffC) + DBRep::Set("myInit", SS); +#endif + +} + +//======================================================================= +//function : IsConnectedShell +//purpose : +//======================================================================= +Standard_Boolean IsConnectedShell( const TopoDS_Shape& S ) +{ + BRepTools_Quilt Glue; + Glue.Add( S ); + + TopoDS_Shape SS = Glue.Shells(); + TopExp_Explorer Explo( SS, TopAbs_SHELL ); + Explo.Next(); + if (Explo.More()) + return Standard_False; + + return Standard_True; +} + +//======================================================================= +//function : MakeList +//purpose : +//======================================================================= +void MakeList (TopTools_ListOfShape& OffsetFaces, + const BRepAlgo_Image& myInitOffsetFace, + const TopTools_IndexedMapOfShape& myFaces) +{ + TopTools_ListIteratorOfListOfShape itLOF(myInitOffsetFace.Roots()); + for ( ; itLOF.More(); itLOF.Next()) { + const TopoDS_Shape& Root = itLOF.Value(); + if (myInitOffsetFace.HasImage(Root)) { + if (!myFaces.Contains(Root)) { + OffsetFaces.Append(myInitOffsetFace.Image(Root).First()); + } + } + } +} + +//======================================================================= +//function : EvalMax +//purpose : +//======================================================================= +void EvalMax(const TopoDS_Shape& S, + Standard_Real& Tol) +{ + TopExp_Explorer exp; + for (exp.Init(S,TopAbs_VERTEX); exp.More(); exp.Next()) { + const TopoDS_Vertex& V = TopoDS::Vertex(exp.Current()); + Standard_Real TolV = BRep_Tool::Tolerance(V); + if (TolV > Tol) Tol = TolV; + } +} + +//======================================================================= +//function : TrimEdge +//purpose : Trim the edge of the largest of descendants in AsDes2d. +// Order in AsDes two vertices that have trimmed the edge. +//======================================================================= +void TrimEdge(TopoDS_Edge& NE, + const Handle(BRepAlgo_AsDes)& AsDes2d, + Handle(BRepAlgo_AsDes)& AsDes) +{ + Standard_Real aSameParTol = Precision::Confusion(); + + TopoDS_Vertex V1,V2; + Standard_Real U = 0.; + Standard_Real UMin = Precision::Infinite(); + Standard_Real UMax = -UMin; + + const TopTools_ListOfShape& LE = AsDes2d->Descendant(NE); + // + Standard_Boolean bTrim = Standard_False; + // + if (LE.Extent() > 1) { + TopTools_ListIteratorOfListOfShape it (LE); + for (; it.More(); it.Next()) { + TopoDS_Vertex V = TopoDS::Vertex(it.Value()); + if (NE.Orientation() == TopAbs_REVERSED) + V.Reverse(); + //V.Orientation(TopAbs_INTERNAL); + if (!FindParameter(V, NE, U)) { + Standard_Real f, l; + Handle(Geom_Curve) theCurve = BRep_Tool::Curve(NE, f, l); + gp_Pnt thePoint = BRep_Tool::Pnt(V); + GeomAPI_ProjectPointOnCurve Projector(thePoint, theCurve); + if (Projector.NbPoints() == 0) + Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge no projection"); + U = Projector.LowerDistanceParameter(); + } + if (U < UMin) { + UMin = U; V1 = V; + } + if (U > UMax) { + UMax = U; V2 = V; + } + } + // + if (V1.IsNull() || V2.IsNull()) { + Standard_ConstructionError::Raise("BRepOffset_MakeOffset::TrimEdge"); + } + if (!V1.IsSame(V2)) { + NE.Free( Standard_True ); + BRep_Builder B; + TopAbs_Orientation Or = NE.Orientation(); + NE.Orientation(TopAbs_FORWARD); + TopoDS_Vertex VF,VL; + TopExp::Vertices (NE,VF,VL); + B.Remove(NE,VF); + B.Remove(NE,VL); + B.Add (NE,V1.Oriented(TopAbs_FORWARD)); + B.Add (NE,V2.Oriented(TopAbs_REVERSED)); + B.Range(NE,UMin,UMax); + NE.Orientation(Or); + AsDes->Add(NE,V1.Oriented(TopAbs_FORWARD)); + AsDes->Add(NE,V2.Oriented(TopAbs_REVERSED)); + BRepLib::SameParameter(NE, aSameParTol, Standard_True); + // + bTrim = Standard_True; + } + } + // + if (!bTrim) { + if (!BRep_Tool::Degenerated(NE)) { + BRepAdaptor_Curve aBAC(NE); + if (!aBAC.IsClosed()) { + if (AsDes->HasAscendant(NE)) { + AsDes->Remove(NE); + } + } + } + } +} + +//======================================================================= +//function : CorrectSolid +//purpose : +//======================================================================= +void CorrectSolid(TopoDS_Solid& theSol, TopTools_ListOfShape& theSolList) +{ + BRep_Builder aBB; + TopoDS_Shape anOuterShell; + NCollection_List aVols; + Standard_Real aVolMax = 0., anOuterVol = 0.; + + TopoDS_Iterator anIt(theSol); + for(; anIt.More(); anIt.Next()) + { + const TopoDS_Shape& aSh = anIt.Value(); + GProp_GProps aVProps; + BRepGProp::VolumeProperties(aSh, aVProps, Standard_True); + if(Abs(aVProps.Mass()) > aVolMax) + { + anOuterVol = aVProps.Mass(); + aVolMax = Abs(anOuterVol); + anOuterShell = aSh; + } + aVols.Append(aVProps.Mass()); + } + // + if(anOuterVol < 0.) + { + anOuterShell.Reverse(); + } + TopoDS_Solid aNewSol; + aBB.MakeSolid(aNewSol); + aNewSol.Closed(Standard_True); + aBB.Add(aNewSol, anOuterShell); + BRepClass3d_SolidClassifier aSolClass(aNewSol); + // + anIt.Initialize(theSol); + NCollection_List::Iterator aVIt(aVols); + for(; anIt.More(); anIt.Next(), aVIt.Next()) + { + TopoDS_Shell aSh = TopoDS::Shell(anIt.Value()); + if(aSh.IsSame(anOuterShell)) + { + continue; + } + else + { + TopExp_Explorer aVExp(aSh, TopAbs_VERTEX); + const TopoDS_Vertex& aV = TopoDS::Vertex(aVExp.Current()); + gp_Pnt aP = BRep_Tool::Pnt(aV); + aSolClass.Perform(aP, BRep_Tool::Tolerance(aV)); + if(aSolClass.State() == TopAbs_IN) + { + if(aVIt.Value() > 0.) + { + aSh.Reverse(); + } + aBB.Add(aNewSol, aSh); + } + else + { + if(aVIt.Value() < 0.) + { + aSh.Reverse(); + } + TopoDS_Solid aSol; + aBB.MakeSolid(aSol); + aSol.Closed(Standard_True); + aBB.Add(aSol, aSh); + theSolList.Append(aSol); + } + } + } + theSol = aNewSol; +} + +//======================================================================= +//function : SortFaces +//purpose : +//======================================================================= +void SortFaces(const TopTools_ListOfShape& theLIm, + TopTools_ListOfShape& theLFImages, + const Standard_Boolean bKeepFirst) +{ + Standard_Integer bKeep; // 1 - keep; -1 - remove + Standard_Boolean bFlag; + TopTools_IndexedDataMapOfShapeListOfShape aDMELF; + TopTools_ListOfShape aLFKeep, aLFLeft, aLFTmp; + TopTools_MapOfShape aMV; + TopTools_ListIteratorOfListOfShape aItLF; + TopExp_Explorer aExp; + // + aLFLeft = theLIm; + // + bKeep = bKeepFirst ? 1 : -1; + for (;;) { + aLFTmp = aLFLeft; + // + aLFLeft.Clear(); + aLFKeep.Clear(); + aDMELF.Clear(); + // + // map list of images edge - faces + aItLF.Initialize(aLFTmp); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); + TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF); + } + // + // find images that have edge attached to only one face + aItLF.Initialize(aLFTmp); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); + aExp.Init(aFIm, TopAbs_EDGE); + for (bFlag = Standard_False; aExp.More(); aExp.Next()) { + const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current(); + const TopTools_ListOfShape& aLEF = aDMELF.FindFromKey(aE); + if (aLEF.Extent() == 1) { + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(aE, aV1, aV2); + aMV.Add(aV1); + aMV.Add(aV2); + // + bFlag = Standard_True; + } + } + // + if (bFlag) { + aLFKeep.Append(aFIm); + } + else { + aLFLeft.Append(aFIm); + } + } + // + // map shapes left for processing + aDMELF.Clear(); + aLFTmp = aLFLeft; + aLFLeft.Clear(); + // + aItLF.Initialize(aLFTmp); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); + TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF); + } + // + // find outer edges and check if they touch the first part of edges + aItLF.Initialize(aLFTmp); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); + aExp.Init(aFIm, TopAbs_EDGE); + for (bFlag = Standard_False; aExp.More() && !bFlag; aExp.Next()) { + const TopoDS_Edge& aE = *(TopoDS_Edge*)&aExp.Current(); + const TopTools_ListOfShape& aLEF = aDMELF.FindFromKey(aE); + if (aLEF.Extent() == 1) { + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(aE, aV1, aV2); + // + bFlag = aMV.Contains(aV1) || aMV.Contains(aV2); + } + } + // + if (bFlag) { + aLFKeep.Append(aFIm); + } + else { + aLFLeft.Append(aFIm); + } + } + // + if (bKeep == 1) { + // aLFKeep should be kept + // aLFLeft left for further processing + aItLF.Initialize(aLFKeep); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); + theLFImages.Append(aFIm); + } + } + // + if (aLFLeft.IsEmpty()) { + break; + } + // + bKeep *= -1; + } +} + +//======================================================================= +//function : FindShape +//purpose : +//======================================================================= +Standard_Boolean FindShape(const TopoDS_Shape& theSWhat, + const TopoDS_Shape& theSWhere, + TopoDS_Shape& theRes) +{ + Standard_Boolean bFound = Standard_False; + TopAbs_ShapeEnum aType = theSWhat.ShapeType(); + TopExp_Explorer aExp(theSWhere, aType); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aS = aExp.Current(); + if (aS.IsSame(theSWhat)) { + theRes = aS; + bFound = Standard_True; + break; + } + } + return bFound; +} + +//======================================================================= +//function : UpdateOrigins +//purpose : +//======================================================================= +void UpdateOrigins(TopTools_IndexedDataMapOfShapeListOfShape& theOrigins, + BOPAlgo_Builder& theGF) +{ + TopTools_ListOfShape aLSTmp; + TopTools_MapOfShape aMFence; + BOPCol_ListIteratorOfListOfShape aItA; + TopTools_ListIteratorOfListOfShape aIt, aIt1; + // + const BOPCol_ListOfShape& aLSU = theGF.Arguments(); + aItA.Initialize(aLSU); + for (; aItA.More(); aItA.Next()) { + const TopoDS_Shape& aS = aItA.Value(); + // + if (!theOrigins.Contains(aS)) { + continue; + } + // + const TopTools_ListOfShape& aLSIm = theGF.Modified(aS); + if (aLSIm.IsEmpty()) { + continue; + } + // + const TopTools_ListOfShape& aLS = theOrigins.FindFromKey(aS); + // + aIt.Initialize(aLSIm); + for (; aIt.More(); aIt.Next()) { + const TopoDS_Shape& aSIm = aIt.Value(); + // + if (!theOrigins.Contains(aSIm)) { + theOrigins.Add(aSIm, aLS); + continue; + } + // + aMFence.Clear(); + // + TopTools_ListOfShape& aLS1 = theOrigins.ChangeFromKey(aSIm); + aLSTmp.Assign(aLS1); + // + aLS1.Clear(); + aIt1.Initialize(aLSTmp); + for (; aIt1.More(); aIt1.Next()) { + const TopoDS_Shape& aS1 = aIt1.Value(); + if (aMFence.Add(aS1)) { + aLS1.Append(aS1); + } + } + // + aIt1.Initialize(aLS); + for (; aIt1.More(); aIt1.Next()) { + const TopoDS_Shape& aS1 = aIt1.Value(); + if (aMFence.Add(aS1)) { + aLS1.Append(aS1); + } + } + } + } +} + +//======================================================================= +//function : IsMicroEdge +//purpose : +//======================================================================= +Standard_Boolean IsMicroEdge(const TopoDS_Edge& theEdge, + const Handle(IntTools_Context)& theCtx) +{ + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(theEdge, aV1, aV2); + Standard_Boolean bNull = aV1.IsNull() || aV2.IsNull(); + if (bNull) { + return Standard_False; + } + // + Standard_Boolean bMicro; + Standard_Real aT1, aT2; + IntTools_ShrunkRange aSR; + // + BRepAdaptor_Curve aBAC(theEdge); + // + aT1 = BRep_Tool::Parameter(aV1, theEdge); + aT2 = BRep_Tool::Parameter(aV2, theEdge); + if (aT2 < aT1) { + Standard_Real aTmp = aT1; + aT1 = aT2; + aT2 = aTmp; + } + // + aSR.SetContext(theCtx); + aSR.SetData(theEdge, aT1, aT2, aV1, aV2); + aSR.Perform(); + bMicro = (aSR.ErrorStatus() != 0); + if (!bMicro) { + Standard_Real anEps, aTS1, aTS2, aTolV1, aTolV2; + // + aTolV1 = BRep_Tool::Tolerance(aV1); + aTolV2 = BRep_Tool::Tolerance(aV2); + // + anEps = aBAC.Resolution(aTolV1 + aTolV2); + if (anEps < 1.e-8) { + anEps = 1.e-8; + } + // + aSR.ShrunkRange(aTS1, aTS2); + bMicro = (aTS2 - aTS1) <= anEps; + } + // + if (bMicro) { + if (aBAC.GetType() == GeomAbs_Line) { + BRep_Builder aBB; + Standard_Real aLen = CPnts_AbscissaPoint::Length(aBAC); + // + aBB.UpdateVertex(aV1, aLen/2.); + aBB.UpdateVertex(aV2, aLen/2.); + } + } + // + return bMicro; +} + +//======================================================================= +//function : ComputeBiNormal +//purpose : +//======================================================================= +Standard_Boolean ComputeBiNormal(const TopoDS_Face& theF, + const TopoDS_Edge& theE, + gp_Dir& theDB) +{ + Standard_Boolean bDone = Standard_False; + Standard_Real aT1, aT2, aTm; + // + const Handle(Geom2d_Curve)& aC2d = + BRep_Tool::CurveOnSurface(theE, theF, aT1, aT2); + if (aC2d.IsNull()) { + return bDone; + } + // + gp_Pnt2d aP2dNear; + gp_Pnt aP, aPNear; + // + const Handle(Geom_Curve)& aC3d = + BRep_Tool::Curve(theE, aT1, aT2); + // + aTm = (aT1 + aT2) * 0.5; + aP = aC3d->Value(aTm); + // + BOPTools_AlgoTools3D::PointNearEdge(theE, theF, aTm, 1.e-5, aP2dNear, aPNear); + // + gp_Vec aVB(aP, aPNear); + theDB = gp_Dir(aVB); + return !bDone; +} + +//======================================================================= +//function : CheckBiNormals +//purpose : +//======================================================================= +Standard_Boolean CheckBiNormals + (const TopoDS_Face& aFIm, + const TopoDS_Face& aFOr, + const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins, + const TopTools_MapOfShape& theMFence, + Standard_Boolean& bKeep, + Standard_Boolean& bRemove, + const Standard_Boolean RemoveInvalidFaces) +{ + Standard_Boolean bChecked; + Standard_Integer aNbEdgesChecked; + Standard_Real anAngle; + TopTools_IndexedMapOfShape aMEInv; + // + aNbEdgesChecked = 0; + // + const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm); + TopExp_Explorer aExp(aWIm, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aExp.Current(); + // + if (BRep_Tool::Degenerated(aEIm)) { + continue; + } + // + if (!theOrigins.Contains(aEIm)) { + continue; + } + // + const TopTools_ListOfShape& aLEOr = theOrigins.FindFromKey(aEIm); + const TopoDS_Shape& aSOr = aLEOr.First(); + if (aSOr.ShapeType() != TopAbs_EDGE) { + continue; + } + // + if (aLEOr.Extent() > 1) { + TopTools_MapOfShape aME, aMV; + Standard_Integer aNbE, aNbV; + // + TopTools_ListIteratorOfListOfShape aItLS(aLEOr); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Edge& aEOr = *(TopoDS_Edge*)&aItLS.Value(); + aME.Add(aEOr); + // + TopExp_Explorer aExpE(aEOr, TopAbs_VERTEX); + for (; aExpE.More(); aExpE.Next()) { + const TopoDS_Shape& aV = aExpE.Current(); + aMV.Add(aV); + } + } + // + aNbV = aMV.Extent(); + aNbE = aME.Extent(); + // + if ((aNbE > 1) && (aNbV == 2*aNbE)) { + continue; + } + } + // + if (!RemoveInvalidFaces) { + if (theMFence.Contains(aEIm)) { + bChecked = Standard_True; + bKeep = Standard_True; + bRemove = Standard_False; + return bChecked; + } + } + // + const TopoDS_Edge& aEOr = *(TopoDS_Edge*)&aLEOr.First(); + // + TopoDS_Edge aEOrF; + if (!FindShape(aEOr, aFOr, aEOrF)) { + continue; + } + // + // compute bi-normal for face aFIm on the edge aEIm + gp_Dir aDB1; + if (!ComputeBiNormal(aFIm, aEIm, aDB1)) { + continue; + } + // + // compute bi-normal for face aFOr on the edge aEOrF + gp_Dir aDB2; + if (!ComputeBiNormal(aFOr, aEOrF, aDB2)) { + continue; + } + // + ++aNbEdgesChecked; + // + anAngle = aDB1.Angle(aDB2); + if (Abs(anAngle - M_PI) < 1.e-4) { + aMEInv.Add(aEIm); + } + } + // + bChecked = (aNbEdgesChecked > 0); + if (!bChecked) { + return bChecked; + } + // + // decide whether to remove the split face or not + bKeep = Standard_True; + bRemove = Standard_False; + // + Standard_Integer aNb = aMEInv.Extent(); + if (aNb == 0) { + return bChecked; + } + // + if (aNb == aNbEdgesChecked) { + bKeep = Standard_False; + bRemove = Standard_True; + } + // + if (!bRemove) { + for (Standard_Integer i = 1; i <= aNb; ++i) { + const TopoDS_Shape& aE = aMEInv(i); + if (theMFence.Contains(aE)) { + bKeep = Standard_False; + bRemove = Standard_True; + break; + } + } + } + // + return bChecked; +} + +//======================================================================= +//function : CheckBiNormals +//purpose : +//======================================================================= +void CheckBiNormals + (TopTools_ListOfShape& theLFImages, + const TopoDS_Face& theF, + const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins, + TopTools_ListOfShape& theLFKeep, + const Standard_Boolean RemoveInvalidFaces) +{ + Standard_Boolean bChecked, bKeep, bRem; + Standard_Integer i, aNb; + TopTools_ListOfShape aLFKeep; + TopTools_MapOfShape aMEToKeep; + TopTools_IndexedDataMapOfShapeListOfShape aDMELF; + TopTools_ListIteratorOfListOfShape aItLF; + // + // collect outer edges + aItLF.Initialize(theLFImages); + for (; aItLF.More(); aItLF.Next()) { + const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); + TopExp::MapShapesAndAncestors(aFIm, TopAbs_EDGE, TopAbs_FACE, aDMELF); + } + // + aNb = aDMELF.Extent(); + for (i = 1; i <= aNb; ++i) { + const TopTools_ListOfShape& aLF = aDMELF(i); + if (aLF.Extent() == 1) { + const TopoDS_Shape& aE = aDMELF.FindKey(i); + aMEToKeep.Add(aE); + } + } + // + const TopoDS_Face& aFOr = *(TopoDS_Face*)&theOrigins.FindFromKey(theF).First(); + // + aItLF.Initialize(theLFImages); + for (; aItLF.More(); ) { + const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLF.Value(); + // + bChecked = CheckBiNormals(aFIm, aFOr, theOrigins, aMEToKeep, bKeep, bRem, RemoveInvalidFaces); + // + if (bChecked) { + if (bRem) { + theLFImages.Remove(aItLF); + } + else { + if (bKeep) { + theLFKeep.Append(aFIm); + } + aItLF.Next(); + } + } + else { + aItLF.Next(); + } + } +} + +//======================================================================= +//function : CheckNormals +//purpose : +//======================================================================= +Standard_Boolean CheckNormals(const TopoDS_Face& theFIm, + const TopoDS_Face& theFOr) +{ + + Standard_Real aUMin, aUMax, aVMin, aVMax, aU, aV, anAngle; + gp_Pnt aP; + gp_Vec aVecU, aVecV, aVNIm, aVNOr; + Standard_Boolean bIsCollinear; + // + BRepAdaptor_Surface aSFIm(theFIm), aSFOr(theFOr); + // + aUMin = aSFIm.FirstUParameter(); + aUMax = aSFIm.LastUParameter(); + aVMin = aSFIm.FirstVParameter(); + aVMax = aSFIm.LastVParameter(); + // + aU = (aUMin + aUMax) * 0.5; + if (Precision::IsInfinite(aUMin) && + Precision::IsInfinite(aUMax)) { + aU = 0.; + } + else if (Precision::IsInfinite(aUMin) && + !Precision::IsInfinite(aUMax)) { + aU = aUMax; + } + else if (!Precision::IsInfinite(aUMin) && + Precision::IsInfinite(aUMax)) { + aU = aUMin; + } + // + aV = (aVMin + aVMax) * 0.5; + if (Precision::IsInfinite(aVMin) && + Precision::IsInfinite(aVMax)) { + aV = 0.; + } + else if (Precision::IsInfinite(aVMin) && + !Precision::IsInfinite(aVMax)) { + aV = aVMax; + } + else if (!Precision::IsInfinite(aVMin) && + Precision::IsInfinite(aVMax)) { + aV = aVMin; + } + // + aSFIm.D1(aU, aV, aP, aVecU, aVecV); + aVNIm = aVecU.Crossed(aVecV); + if (theFIm.Orientation() == TopAbs_REVERSED) { + aVNIm.Reverse(); + } + // + aSFOr.D1(aU, aV, aP, aVecU, aVecV); + aVNOr = aVecU.Crossed(aVecV); + if (theFOr.Orientation() == TopAbs_REVERSED) { + aVNOr.Reverse(); + } + // + anAngle = aVNIm.Angle(aVNOr); + bIsCollinear = (anAngle < Precision::Confusion()); + return bIsCollinear; +} + +//======================================================================= +//function : UpdateInitOffset +//purpose : Update and cleaning of myInitOffset +//======================================================================= +void UpdateInitOffset(BRepAlgo_Image& myInitOffset, + BRepAlgo_Image& myImageOffset, + const TopoDS_Shape& myOffsetShape, + const TopAbs_ShapeEnum &theShapeType) // skv +{ + BRepAlgo_Image NIOF; + const TopTools_ListOfShape& Roots = myInitOffset.Roots(); + TopTools_ListIteratorOfListOfShape it(Roots); + for (; it.More(); it.Next()) { + NIOF.SetRoot (it.Value()); + } + for (it.Initialize(Roots); it.More(); it.Next()) { + const TopoDS_Shape& SI = it.Value(); + TopTools_ListOfShape LI; + TopTools_ListOfShape L1; + myInitOffset.LastImage(SI,L1); + TopTools_ListIteratorOfListOfShape itL1(L1); + for (; itL1.More(); itL1.Next()) { + const TopoDS_Shape& O1 = itL1.Value(); + TopTools_ListOfShape L2; + myImageOffset.LastImage(O1,L2); + LI.Append(L2); + } + NIOF.Bind(SI,LI); + } +// Modified by skv - Mon Apr 4 18:17:27 2005 Begin +// Supporting history. +// NIOF.Filter(myOffsetShape,TopAbs_FACE); + NIOF.Filter(myOffsetShape, theShapeType); +// Modified by skv - Mon Apr 4 18:17:27 2005 End + myInitOffset = NIOF; +} diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.cdl b/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.cdl index a8a97f7277..c41af53722 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.cdl +++ b/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.cdl @@ -46,7 +46,8 @@ is Mode : Mode from BRepOffset = BRepOffset_Skin; Intersection : Boolean from Standard = Standard_False; SelfInter : Boolean from Standard = Standard_False; - Join : JoinType from GeomAbs = GeomAbs_Arc) + Join : JoinType from GeomAbs = GeomAbs_Arc; + RemoveIntEdges:Boolean from Standard = Standard_False) ---Purpose: Constructs a shape parallel to the shape S, where -- - S may be a face, a shell, a solid or a compound of these shape kinds; -- - Offset is the offset value. The offset shape is constructed: @@ -82,6 +83,8 @@ is -- - if Join is equal to GeomAbs_Intersection, then the parallels to the -- two adjacent faces are enlarged and intersected, -- so that there are no free edges on parallels to faces. + -- RemoveIntEdges flag defines whether to remove the INTERNAL edges + -- from the result or not. -- Warnings -- 1. All the faces of the shape S should be based on the surfaces -- with continuity at least C1. diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.cxx b/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.cxx index f4245d5bb7..9b1d0b73b0 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.cxx +++ b/src/BRepOffsetAPI/BRepOffsetAPI_MakeOffsetShape.cxx @@ -43,9 +43,11 @@ BRepOffsetAPI_MakeOffsetShape::BRepOffsetAPI_MakeOffsetShape const BRepOffset_Mode Mode, const Standard_Boolean Intersection, const Standard_Boolean SelfInter, - const GeomAbs_JoinType Join) + const GeomAbs_JoinType Join, + const Standard_Boolean RemoveIntEdges) { - myOffsetShape.Initialize (S,Offset,Tol,Mode,Intersection,SelfInter,Join); + myOffsetShape.Initialize (S,Offset,Tol,Mode,Intersection,SelfInter, + Join, RemoveIntEdges); Build(); } diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.cdl b/src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.cdl index ec8a6a4bec..bec7ba2638 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.cdl +++ b/src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.cdl @@ -53,7 +53,8 @@ is Mode : Mode from BRepOffset = BRepOffset_Skin; Intersection : Boolean from Standard = Standard_False; SelfInter : Boolean from Standard = Standard_False; - Join : JoinType from GeomAbs = GeomAbs_Arc) + Join : JoinType from GeomAbs = GeomAbs_Arc; + RemoveIntEdges : Boolean from Standard = Standard_False) ---Purpose: Constructs a hollowed solid from -- the solid S by removing the set of faces ClosingFaces from S, where: -- Offset defines the thickness of the walls. Its sign indicates @@ -88,6 +89,8 @@ is -- then the parallels to the two adjacent faces are -- enlarged and intersected, so that there are no free -- edges on parallels to faces. + -- - RemoveIntEdges flag defines whether to remove the INTERNAL edges + -- from the result or not. -- Warnings -- Since the algorithm of MakeThickSolid is based on -- MakeOffsetShape algorithm, the warnings are the same as for diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.cxx b/src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.cxx index e8d8652746..5f645ab080 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.cxx +++ b/src/BRepOffsetAPI/BRepOffsetAPI_MakeThickSolid.cxx @@ -44,9 +44,11 @@ BRepOffsetAPI_MakeThickSolid::BRepOffsetAPI_MakeThickSolid const BRepOffset_Mode Mode, const Standard_Boolean Intersection, const Standard_Boolean SelfInter, - const GeomAbs_JoinType Join) + const GeomAbs_JoinType Join, + const Standard_Boolean RemoveIntEdges) { - myOffsetShape.Initialize (S,Offset,Tol,Mode,Intersection,SelfInter,Join); + myOffsetShape.Initialize (S,Offset,Tol,Mode,Intersection,SelfInter, + Join, RemoveIntEdges); TopTools_ListIteratorOfListOfShape it(ClosingFaces); for (; it.More(); it.Next()) { myOffsetShape.AddFace(TopoDS::Face(it.Value())); diff --git a/src/BRepTest/BRepTest_FeatureCommands.cxx b/src/BRepTest/BRepTest_FeatureCommands.cxx index 987ce26f3c..be3fa17513 100644 --- a/src/BRepTest/BRepTest_FeatureCommands.cxx +++ b/src/BRepTest/BRepTest_FeatureCommands.cxx @@ -803,7 +803,7 @@ static Standard_Integer SPLS(Draw_Interpretor& , //======================================================================= Standard_Integer thickshell(Draw_Interpretor& , - Standard_Integer n, const char** a) + Standard_Integer n, const char** a) { //OSD_Chronometer Clock; @@ -818,9 +818,9 @@ Standard_Integer thickshell(Draw_Interpretor& , if (n > 4) { if (!strcmp(a[4],"i")) - JT = GeomAbs_Intersection; + JT = GeomAbs_Intersection; if (!strcmp(a[4],"t")) - JT = GeomAbs_Tangent; + JT = GeomAbs_Tangent; } Standard_Boolean Inter = Standard_False; //Standard_True; @@ -829,7 +829,7 @@ Standard_Integer thickshell(Draw_Interpretor& , Tol = Draw::Atof(a[5]); BRepOffset_MakeOffset B; - B.Initialize(S,Of,Tol,BRepOffset_Skin,Inter,0,JT, Standard_True); + B.Initialize(S,Of,Tol,BRepOffset_Skin,Inter,0,JT, Standard_False, Standard_True); // Clock.Start(); @@ -849,7 +849,7 @@ Standard_Integer thickshell(Draw_Interpretor& , //======================================================================= Standard_Integer offsetshape(Draw_Interpretor& , - Standard_Integer n, const char** a) + Standard_Integer n, const char** a) { //OSD_Chronometer Clock; @@ -907,63 +907,73 @@ static Standard_Boolean theYaBouchon; static Standard_Real TheTolerance = Precision::Confusion(); static Standard_Boolean TheInter = Standard_False; static GeomAbs_JoinType TheJoin = GeomAbs_Arc; +static Standard_Boolean RemoveIntEdges = Standard_False; +static Standard_Boolean RemoveInvalidFaces = Standard_False; Standard_Integer offsetparameter(Draw_Interpretor& di, - Standard_Integer n, const char** a) + Standard_Integer n, const char** a) { if ( n == 1 ) { - //cout << " OffsetParameter Tol Inter(c/p) JoinType(a/i)" << endl; - //cout << " Current Values" << endl; - //cout << " --> Tolerance :" << TheTolerance << endl; - //cout << " --> TheInter :"; - di << " OffsetParameter Tol Inter(c/p) JoinType(a/i)" << "\n"; + di << " OffsetParameter Tol Inter(c/p) JoinType(a/i/t) [RemoveInternalEdges(r/k) RemoveInvalidFaces(r/k)]" << "\n"; di << " Current Values" << "\n"; - di << " --> Tolerance :" << TheTolerance << "\n"; - di << " --> TheInter :"; + di << " --> Tolerance : " << TheTolerance << "\n"; + di << " --> TheInter : "; if ( TheInter) { - //cout << "Complet" ; di << "Complet" ; } else { - //cout << "Partial"; di << "Partial"; } - //cout << endl << " --> TheJoin :"; - di << "\n" << " --> TheJoin :"; + di << "\n" << " --> TheJoin : "; switch (TheJoin) { - //case GeomAbs_Arc: cout << " Arc"; break; - //case GeomAbs_Intersection: cout << " Intersection"; break; - case GeomAbs_Arc: di << " Arc"; break; - case GeomAbs_Intersection: di << " Intersection"; break; + case GeomAbs_Arc: di << "Arc"; break; + case GeomAbs_Intersection: di << "Intersection"; break; default: break ; } - //cout << endl; + // + di << "\n" << " --> Internal Edges : "; + if (RemoveIntEdges) { + di << "Remove"; + } + else { + di << "Keep"; + } + // + di << "\n" << " --> Invalid Faces : "; + if (RemoveInvalidFaces) { + di << "Remove"; + } + else { + di << "Keep"; + } di << "\n"; - + // return 0; } if ( n < 4 ) return 1; - + // TheTolerance = Draw::Atof(a[1]); TheInter = strcmp(a[2],"p"); - + // if ( !strcmp(a[3],"a")) TheJoin = GeomAbs_Arc; else if ( !strcmp(a[3],"i")) TheJoin = GeomAbs_Intersection; else if ( !strcmp(a[3],"t")) TheJoin = GeomAbs_Tangent; - - return 0; + // + RemoveIntEdges = (n >= 5) ? !strcmp(a[4], "r") : Standard_False; + RemoveInvalidFaces = (n == 6) ? !strcmp(a[5], "r") : Standard_False; + // + return 0; } - //======================================================================= //function : offsetinit //purpose : //======================================================================= Standard_Integer offsetload(Draw_Interpretor& , - Standard_Integer n, const char** a) + Standard_Integer n, const char** a) { if ( n < 2) return 1; TopoDS_Shape S = DBRep::Get(a[1]); @@ -973,7 +983,8 @@ Standard_Integer offsetload(Draw_Interpretor& , TheRadius = Of; // Standard_Boolean Inter = Standard_True; - TheOffset.Initialize(S,Of,TheTolerance,BRepOffset_Skin,TheInter,0,TheJoin); + TheOffset.Initialize(S,Of,TheTolerance,BRepOffset_Skin,TheInter,0,TheJoin, + RemoveIntEdges,Standard_False,RemoveInvalidFaces); //------------------------------------------ // recuperation et chargement des bouchons. //---------------------------------------- @@ -1076,7 +1087,7 @@ Standard_Integer offsetperform(Draw_Interpretor& theCommands, //======================================================================= static Standard_Integer Debou(Draw_Interpretor& theCommands, - Standard_Integer narg, const char** a) + Standard_Integer narg, const char** a) { Standard_Integer i ; Standard_Integer newnarg ;