From: emv Date: Thu, 4 Jun 2015 07:53:22 +0000 (+0300) Subject: 0025926: 3D offset in mode "Complete" with Join type "Intersection" X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=999dacb4d0b0c1c858961e144be4c0173bd4a49c;p=occt-copy.git 0025926: 3D offset in mode "Complete" with Join type "Intersection" 3D offset algorithm extension for degenerate (colliding) cases. --- diff --git a/src/BRepOffset/BRepOffset_Inter2d.cxx b/src/BRepOffset/BRepOffset_Inter2d.cxx index 2c6c6438a2..7e694d9f14 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); - - 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); + //--------------------------------------------------------------- + // 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); } } 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 +852,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 +957,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(); - - 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); - } - - 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(); - } - } + { + 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); + + //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 ); + + //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 +1120,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())); - - 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 ); - } - } + { + 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; + } + } + } + + 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 +1289,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 +1354,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 +1386,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 +1399,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 +1418,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 +1427,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 +1441,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++; @@ -1486,17 +1489,17 @@ 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); + } } } } @@ -1504,6 +1507,8 @@ void BRepOffset_Inter2d::ConnexIntByInt TopoDS_Face FIO = TopoDS::Face(OFI.Face()); if (MES.IsBound(FIO)) FIO = TopoDS::Face(MES(FIO)); + 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 +1520,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,43 +1551,43 @@ 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()), + AsDes,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); + 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); + } } CurE = NextE; } diff --git a/src/BRepOffset/BRepOffset_Inter3d.cxx b/src/BRepOffset/BRepOffset_Inter3d.cxx index 334d800ccc..37c632ab16 100644 --- a/src/BRepOffset/BRepOffset_Inter3d.cxx +++ b/src/BRepOffset/BRepOffset_Inter3d.cxx @@ -49,8 +49,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 +64,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); @@ -99,9 +99,9 @@ static void ExtentEdge(const TopoDS_Face& /*F*/, //======================================================================= static void SelectEdge (const TopoDS_Face& /*F*/, - const TopoDS_Face& /*EF*/, - const TopoDS_Edge& E, - TopTools_ListOfShape& LInt) + const TopoDS_Face& /*EF*/, + const TopoDS_Edge& E, + TopTools_ListOfShape& LInt) { //------------------------------------------------------------ // Proofing on the intersections on periodical faces @@ -145,14 +145,14 @@ static void SelectEdge (const TopoDS_Face& /*F*/, 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(); + if (anExt.IsMin(i)) { + const gp_Pnt &aPMin = anExt.Point(i).Value(); - aSqrDist1 = PFirst.SquareDistance(aPMin); - isMinFound = Standard_True; + aSqrDist1 = PFirst.SquareDistance(aPMin); + isMinFound = Standard_True; - break; - } + break; + } } } if (!isMinFound) { @@ -167,14 +167,14 @@ static void SelectEdge (const TopoDS_Face& /*F*/, 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(); + if (anExt.IsMin(i)) { + const gp_Pnt &aPMin = anExt.Point(i).Value(); - aSqrDist2 = PLast.SquareDistance(aPMin); - isMinFound = Standard_True; + aSqrDist2 = PLast.SquareDistance(aPMin); + isMinFound = Standard_True; - break; - } + break; + } } } if (!isMinFound) { @@ -207,7 +207,7 @@ static void SelectEdge (const TopoDS_Face& /*F*/, //======================================================================= void BRepOffset_Inter3d::CompletInt(const TopTools_ListOfShape& SetOfFaces, - const BRepAlgo_Image& InitOffsetFace) + const BRepAlgo_Image& InitOffsetFace) { //--------------------------------------------------------------- // Calculate the intersections of offset faces @@ -250,8 +250,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 +261,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 +273,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 +356,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 +384,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); + } + } + } + } + } + } } } } @@ -491,87 +497,87 @@ void BRepOffset_Inter3d::ConnexIntByInt if (!L.IsEmpty()) { 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_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 + } } } } @@ -616,48 +622,48 @@ void BRepOffset_Inter3d::ContextIntByInt else WCF = CF; 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)) { - //---------------------------------------------------------------- - // 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; + //---------------------------------------------------------------- + // 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()); @@ -666,34 +672,34 @@ void BRepOffset_Inter3d::ContextIntByInt 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); + BRepOffset_Tool::EnLargeFace(OF,NF,1,1); + MES.Bind(OF,NF); } else { - NF = TopoDS::Face(MES(OF)); + 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,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); - } + 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); + } } } } @@ -705,10 +711,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 +734,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 +793,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 +813,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 +840,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 +919,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 +940,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 +993,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 e37b08d567..ca16ccca38 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,7 +36,9 @@ 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 @@ -45,38 +47,38 @@ is 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; + 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; - + Thickening : Boolean from Standard = Standard_False) + returns MakeOffset from BRepOffset; + ---Category: Initialization. Initialize (me : in out; - S : Shape from TopoDS; + 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; + 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) + Thickening : 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 +90,7 @@ is ---Category: Querying. GetAnalyse(me) - ---C++: return const & + ---C++: return const & returns Analyse from BRepOffset is static; @@ -96,18 +98,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 +117,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; @@ -143,18 +145,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 ; @@ -174,7 +188,7 @@ is SelectShells (me : in out) is static private; - + EncodeRegularity( me : in out) is static private; @@ -182,19 +196,19 @@ 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 + ---Purpose: Private method used to build walls for thickening the shell is static private; fields @@ -211,7 +225,7 @@ fields 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; diff --git a/src/BRepOffset/BRepOffset_MakeOffset.cxx b/src/BRepOffset/BRepOffset_MakeOffset.cxx index 69ca982442..8e5e4aaa32 100644 --- a/src/BRepOffset/BRepOffset_MakeOffset.cxx +++ b/src/BRepOffset/BRepOffset_MakeOffset.cxx @@ -144,7 +144,7 @@ //======================================================================= static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges, - Handle(BRepAlgo_AsDes) AsDes) + Handle(BRepAlgo_AsDes) AsDes) { TopTools_ListOfShape LVP; TopTools_ListIteratorOfListOfShape it1LE ; @@ -155,34 +155,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++; } @@ -240,12 +240,12 @@ static void DEBVerticesControl (const TopTools_IndexedMapOfShape& NewEdges, static void UpdateTolerance ( TopoDS_Shape& myShape, - const TopTools_IndexedMapOfShape& myFaces); + const TopTools_IndexedMapOfShape& myFaces); static Standard_Boolean FindParameter(const TopoDS_Vertex& V, - const TopoDS_Edge& E, - Standard_Real& U) + const TopoDS_Edge& E, + Standard_Real& U) { // Search the vertex in the edge @@ -267,13 +267,13 @@ static Standard_Boolean FindParameter(const TopoDS_Vertex& V, const TopoDS_Shape& Vcur = itv.Value(); if (V.IsSame(Vcur)) { if (VF.IsNull()) { - VF = Vcur; + VF = Vcur; } else { - rev = E.Orientation() == TopAbs_REVERSED; - if (Vcur.Orientation() == V.Orientation()) { - VF = Vcur; - } + rev = E.Orientation() == TopAbs_REVERSED; + if (Vcur.Orientation() == V.Orientation()) { + VF = Vcur; + } } } itv.Next(); @@ -303,42 +303,42 @@ static Standard_Boolean FindParameter(const TopoDS_Vertex& V, L = L.Predivided(V.Location()); if (!C.IsNull() || BRep_Tool::Degenerated(E)) { BRep_ListIteratorOfListOfPointRepresentation itpr - ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points()); + ((*((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(); + 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 { @@ -349,25 +349,25 @@ static Standard_Boolean FindParameter(const TopoDS_Vertex& V, BRep_Tool::CurveOnSurface(E,PC,S,L,f,l); L = L.Predivided(V.Location()); BRep_ListIteratorOfListOfPointRepresentation itpr - ((*((Handle(BRep_TVertex)*) &V.TShape()))->Points()); + ((*((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(); + 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(); } } } @@ -401,9 +401,9 @@ static void GetEdgePoints(const TopoDS_Edge& anEdge, //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) + const BRepOffset_Analyse& Analyser, + TopTools_DataMapOfShapeListOfShape& Contours, + TopTools_DataMapOfShapeShape& MapEF) { TopTools_ListOfShape Edges; @@ -415,21 +415,21 @@ static void FillContours(const TopoDS_Shape& aShape, 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); - } - } - } + { + 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; @@ -442,19 +442,19 @@ static void FillContours(const TopoDS_Shape& aShape, 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; - } - } + 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); } } @@ -476,13 +476,13 @@ BRepOffset_MakeOffset::BRepOffset_MakeOffset() //======================================================================= 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 Thickening) : myOffset (Offset), myTol (Tol), @@ -506,13 +506,13 @@ myDone (Standard_False) //======================================================================= 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 Thickening) { myOffset = Offset; myShape = S; @@ -565,7 +565,7 @@ void BRepOffset_MakeOffset::AddFace(const TopoDS_Face& F) { //======================================================================= 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); @@ -577,7 +577,7 @@ void BRepOffset_MakeOffset::SetOffsetOnFace(const TopoDS_Face& F, //======================================================================= static void RemoveCorks (TopoDS_Shape& S, - TopTools_IndexedMapOfShape& Faces) + TopTools_IndexedMapOfShape& Faces) { TopoDS_Compound SS; BRep_Builder B; @@ -632,14 +632,17 @@ static Standard_Boolean IsConnectedShell( const TopoDS_Shape& S ) //======================================================================= static void MakeList (TopTools_ListOfShape& OffsetFaces, - const BRepAlgo_Image& myInitOffsetFace, - const TopTools_IndexedMapOfShape& myFaces) + 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()); + if (myInitOffsetFace.HasImage(Root)) { + if (!myFaces.Contains(Root)) { + OffsetFaces.Append(myInitOffsetFace.Image(Root).First()); + } + } } } @@ -708,25 +711,31 @@ void BRepOffset_MakeOffset::MakeOffsetShape() //----------------- // Intersection 3d . //----------------- - BRepOffset_Inter3d Inter(myAsDes,Side,myTol); - Intersection3D (Inter); - //----------------- - // Intersection2D - //----------------- - TopTools_IndexedMapOfShape& Modif = Inter.TouchedFaces(); - TopTools_IndexedMapOfShape& NewEdges = Inter.NewEdges(); - - if (!Modif.IsEmpty()) Intersection2D (Modif,NewEdges); - //------------------------------------------------------- - // Unwinding 2D and reconstruction of modified faces - //---------------------------------------------------- - MakeLoops (Modif); - //----------------------------------------------------- - // Reconstruction of non modified faces sharing - // reconstructed edges - //------------------------------------------------------ - if (!Modif.IsEmpty()) MakeFaces (Modif); + + //if (!Intersection3D()) { + BRepOffset_Inter3d Inter(myAsDes,Side,myTol); + Intersection3D (Inter); + //----------------- + // Intersection2D + //----------------- + TopTools_IndexedMapOfShape& Modif = Inter.TouchedFaces(); + TopTools_IndexedMapOfShape& NewEdges = Inter.NewEdges(); + + if (!Modif.IsEmpty()) Intersection2D (Modif,NewEdges); + //------------------------------------------------------- + // Unwinding 2D and reconstruction of modified faces + //---------------------------------------------------- + MakeLoops (Modif); + //----------------------------------------------------- + // Reconstruction of non modified faces sharing + // reconstructed edges + //------------------------------------------------------ + if (!Modif.IsEmpty()) MakeFaces (Modif); + //} + + + // if (myThickening) MakeMissingWalls(); @@ -881,8 +890,8 @@ const TopoDS_Shape& BRepOffset_MakeOffset::Shape() const //======================================================================= static void TrimEdge (TopoDS_Edge& NE, - const Handle(BRepAlgo_AsDes)& AsDes2d, - Handle(BRepAlgo_AsDes)& AsDes) + const Handle(BRepAlgo_AsDes)& AsDes2d, + Handle(BRepAlgo_AsDes)& AsDes) { Standard_Real aSameParTol = Precision::Confusion(); @@ -898,23 +907,23 @@ static void TrimEdge (TopoDS_Edge& NE, for (; it.More(); it.Next()) { TopoDS_Vertex V = TopoDS::Vertex(it.Value()); if (NE.Orientation() == TopAbs_REVERSED) - V.Reverse(); + 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(); - } + { + 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; + UMin = U; V1 = V; } if (U > UMax) { - UMax = U; V2 = V; + UMax = U; V2 = V; } } if (V1.IsNull() || V2.IsNull()) { @@ -940,6 +949,606 @@ static void TrimEdge (TopoDS_Edge& NE, } } + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//======================================================================= +//function : SortFaces +//purpose : +//======================================================================= +static 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 touche 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 : +//======================================================================= +static 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 : ComputeBiNormal +//purpose : +//======================================================================= +static 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 : UpdateOrigins +//purpose : +//======================================================================= +static 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 : 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; + // + // firstly it is necessary to fuse all the edges + 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; + } + aLS.Append(aE); + } + } + // + if (aLS.Extent() > 1) { + BOPAlgo_PaveFiller aPF; + // + aPF.SetArguments(aLS); + aPF.Perform(); + if (aPF.ErrorStatus() == 0) { + BOPAlgo_Builder aGFE; + // + aGFE.SetArguments(aLS); + aGFE.PerformWithFiller(aPF); + 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_Shape& aF = 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_Shape& aEIm = aItLE1.Value(); + aLS.Append(aEIm); + if (!aMFE.Contains(aEIm)) { + ++iCountE; + } + } + } + else { + aLS.Append(aE); + if (!aMFE.Contains(aE)) { + ++iCountE; + } + } + } + // + TopTools_ListOfShape aLFImages; + // + // split the face by the edges + if (!iCountE) { + aLFImages.Append(aF); + theImage.Bind(aF, aLFImages); + 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(); + bKeep = aME.Contains(aE); + } + // + if (bKeep) { + aItLE.Next(); + } + else { + aLFImages.Remove(aItLE); + } + } + // + // check offset faces on the coincidence of the + // bi-normal directions with the original faces + // + UpdateOrigins(theOrigins, aGF); + // + Standard_Real anAngle; + Standard_Boolean bRem; + TopTools_ListOfShape aLFKeep; + // + const TopoDS_Face& aFOr = *(TopoDS_Face*)&theOrigins.FindFromKey(aF).First(); + // + aItLE.Initialize(aLFImages); + for (; aItLE.More(); ) { + const TopoDS_Face& aFIm = *(TopoDS_Face*)&aItLE.Value(); + const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm); + // + bKeep = Standard_True; + bRem = Standard_True; + // + TopExp_Explorer aExp(aWIm, TopAbs_EDGE); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aExp.Current(); + // + if (!theOrigins.Contains(aEIm)) { + continue; + } + // + const TopTools_ListOfShape& aLEOr = theOrigins.FindFromKey(aEIm); + // + if (aLEOr.Extent() > 1) { + TopTools_MapOfShape aME, aMV; + Standard_Integer aNbE, aNbV; + // + TopTools_ListIteratorOfListOfShape aItLS1(aLEOr); + for (; aItLS1.More(); aItLS1.Next()) { + const TopoDS_Edge& aEOr = *(TopoDS_Edge*)&aItLS1.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; + } + } + // + const TopoDS_Shape& 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; + } + // + // check coincidence of bi-normals + anAngle = aDB1.Angle(aDB2); + if (Abs(anAngle - M_PI) < Precision::Confusion()) { + bKeep = Standard_False; + bRem = bRem && Standard_True; + } + else { + bRem = Standard_False; + } + // + if (!bKeep && !bRem) { + break; + } + } + // + if (bRem) { + aLFImages.Remove(aItLE); + } + else { + if (bKeep) { + aLFKeep.Append(aFIm); + } + aItLE.Next(); + } + } + // + TopTools_ListOfShape aLFTmp = aLFImages; + aLFImages.Clear(); + // limit the face + SortFaces(aLFTmp, aLFImages, Standard_True); + // + 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 { + theLFailed.Append(aF); + } + } + // + // fill history for edges + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItEIm(anEImages); + for (; aItEIm.More(); aItEIm.Next()) { + const TopoDS_Shape& aE = aItEIm.Key(); + const TopTools_ListOfShape& aLEIm = aItEIm.Value(); + if (theImage.HasImage(aE)) { + theImage.Add(aE, aLEIm); + } + else { + theImage.Bind(aE, aLEIm); + } + } +} + //======================================================================= //function : BuildOffsetByInter //purpose : @@ -979,27 +1588,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); @@ -1047,6 +1656,7 @@ 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()); @@ -1056,43 +1666,72 @@ void BRepOffset_MakeOffset::BuildOffsetByInter() 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); - } + if (Build.IsBound(EI)) { + NE = Build(EI); + if (NE.ShapeType() == TopAbs_EDGE) { + if (anOrigins.Contains(NE)) { + anOrigins.ChangeFromKey(NE).Append(EI); + } + else { + TopTools_ListOfShape aLSx; + aLSx.Append(EI); + 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(EI); + } + else { + TopTools_ListOfShape aLSx; + aLSx.Append(EI); + anOrigins.Add(NEC, aLSx); + } + // + 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 (anOrigins.Contains(NE)) { + anOrigins.ChangeFromKey(NE).Append(EI); + } + else { + TopTools_ListOfShape aLSx; + aLSx.Append(EI); + anOrigins.Add(NE, aLSx); + } + /////////////////////////////////////////////// + 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); + } } } } @@ -1109,6 +1748,15 @@ 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); + } } } @@ -1129,8 +1777,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 @@ -1144,91 +1802,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 { @@ -1236,26 +1894,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)); + } + } } } } @@ -1272,49 +1930,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); - - if (MES.IsBound(aNewEdge)) - aNewEdge = MES(aNewEdge); - - if (IMOE.HasImage(aNewEdge)) { - const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewEdge); - - myInitOffsetEdge.Bind (anEdgeRef, aListNewE); - } else - myInitOffsetEdge.Bind (anEdgeRef, aNewEdge); - } + 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 (IMOE.HasImage(aNewEdge)) { + const TopTools_ListOfShape& aListNewE = IMOE.Image(aNewEdge); + + myInitOffsetEdge.Bind (anEdgeRef, aListNewE); + } else + myInitOffsetEdge.Bind (anEdgeRef, aNewEdge); + } } } } @@ -1330,38 +1988,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 } } @@ -1413,27 +2071,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); @@ -1449,60 +2107,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); } } } @@ -1521,42 +2179,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)); + } + } } } } @@ -1577,12 +2235,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); @@ -1591,27 +2249,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()); } } } @@ -1669,14 +2327,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); } } } @@ -1690,28 +2348,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); + } + } + } } } } @@ -1740,26 +2398,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 { @@ -1767,8 +2425,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); @@ -1785,9 +2443,9 @@ 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); } @@ -1829,7 +2487,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); } } @@ -1983,7 +2641,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()) @@ -2192,12 +2850,10 @@ void BRepOffset_MakeOffset::CorrectConicalFaces() } } - //======================================================================= //function : Intersection3D //purpose : //======================================================================= - void BRepOffset_MakeOffset::Intersection3D(BRepOffset_Inter3d& Inter) { #ifdef OCCT_DEBUG @@ -2208,7 +2864,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 @@ -2245,7 +2901,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) { @@ -2301,8 +2957,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. //----------------------------------------- @@ -2356,9 +3022,9 @@ void BRepOffset_MakeOffset::MakeFaces(TopTools_IndexedMapOfShape& /*Modif*/) //======================================================================= static void UpdateInitOffset (BRepAlgo_Image& myInitOffset, - BRepAlgo_Image& myImageOffset, - const TopoDS_Shape& myOffsetShape, - const TopAbs_ShapeEnum &theShapeType) // skv + BRepAlgo_Image& myImageOffset, + const TopoDS_Shape& myOffsetShape, + const TopAbs_ShapeEnum &theShapeType) // skv { BRepAlgo_Image NIOF; const TopTools_ListOfShape& Roots = myInitOffset.Roots(); @@ -2412,82 +3078,82 @@ void BRepOffset_MakeOffset::MakeMissingWalls () TopoDS_Edge PrevEdge; TopoDS_Vertex PrevVertex = StartVertex; for (; itl.More(); itl.Next()) - { - TopoDS_Edge anEdge = TopoDS::Edge(itl.Value()); - if (!myInitOffsetEdge.HasImage(anEdge)) - continue; - //if (BRep_Tool::Degenerated(anEdge)) - //continue; - TopoDS_Face aFace = TopoDS::Face(MapEF(anEdge)); - //TopoDS_Edge OE = TopoDS::Edge(myInitOffsetEdge.Image(anEdge).First()); - 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(anEdge, V1, V2/*, Standard_True*/); - TopExp::Vertices(OE, V4, V3/*, 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; - } - //Temporary - //anEdge.Reverse(); - OE.Orientation(TopAbs::Reverse(anEdge.Orientation())); - TopoDS_Edge E3, E4; - if (FirstStep) - { - E4 = BRepLib_MakeEdge( V1, V4 ); - StartEdge = E4; - } - else - E4 = PrevEdge; - Standard_Boolean ArcOnV2 = ((myJoin == GeomAbs_Arc) && (myInitOffsetEdge.HasImage(V2))); - if (V2.IsSame(StartVertex) && !ArcOnV2) - E3 = StartEdge; - else - E3 = BRepLib_MakeEdge( V2, V3 ); - 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); - } - 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) + { + TopoDS_Edge anEdge = TopoDS::Edge(itl.Value()); + if (!myInitOffsetEdge.HasImage(anEdge)) + continue; + //if (BRep_Tool::Degenerated(anEdge)) + //continue; + TopoDS_Face aFace = TopoDS::Face(MapEF(anEdge)); + //TopoDS_Edge OE = TopoDS::Edge(myInitOffsetEdge.Image(anEdge).First()); + 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(anEdge, V1, V2/*, Standard_True*/); + TopExp::Vertices(OE, V4, V3/*, 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; + } + //Temporary + //anEdge.Reverse(); + OE.Orientation(TopAbs::Reverse(anEdge.Orientation())); + TopoDS_Edge E3, E4; + if (FirstStep) + { + E4 = BRepLib_MakeEdge( V1, V4 ); + StartEdge = E4; + } + else + E4 = PrevEdge; + Standard_Boolean ArcOnV2 = ((myJoin == GeomAbs_Arc) && (myInitOffsetEdge.HasImage(V2))); + if (V2.IsSame(StartVertex) && !ArcOnV2) + E3 = StartEdge; + else + E3 = BRepLib_MakeEdge( V2, V3 ); + 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); + } + 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(); @@ -2597,175 +3263,239 @@ void BRepOffset_MakeOffset::MakeMissingWalls () } } //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 - { - PrevEdge = E3; - PrevVertex = V2; - } - FirstStep = Standard_False; - } + 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 + { + PrevEdge = E3; + PrevVertex = V2; + } + FirstStep = Standard_False; + } } } //======================================================================= -//function : MakeShells +//function : CheckNormals //purpose : //======================================================================= +static 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; +} -void BRepOffset_MakeOffset::MakeShells () +//======================================================================= +//function : MakeShells +//purpose : +//======================================================================= +void BRepOffset_MakeOffset::MakeShells() { #ifdef OCCT_DEBUG if (ChronBuild) { @@ -2774,30 +3504,165 @@ 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) - { - 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()); + // + if (myThickening) { + TopExp_Explorer Explo(myShape, TopAbs_FACE); + for (; Explo.More(); Explo.Next()) { + const TopoDS_Shape& aF = Explo.Current(); + aLSF.Append(aF); } - - myOffsetShape = Glue.Shells(); + // + 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); + } + }*/ + // + if ((myJoin == GeomAbs_Intersection) && myInter) { + Standard_Integer i, aNb; + TopTools_ListIteratorOfListOfShape aItLS, aItLS1; + // + BOPAlgo_Builder aGF; + // + aGF.SetArguments(aLSF); + aGF.Perform(); + if (aGF.ErrorStatus() == 0) { + 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); + } + // + UpdateOrigins(anOrigins, aGF); + } + // + if (myFaces.IsEmpty()) { + BOPAlgo_MakerVolume aMV1; + // + aMV1.SetArguments(aLSF); + aMV1.SetIntersect(Standard_False); + // + aMV1.Perform(); + bDone = (aMV1.ErrorStatus() == 0); + if (bDone) { + TopoDS_Compound aShells; + BRep_Builder aBB; + // + aBB.MakeCompound(aShells); + // + TopoDS_Shape aResult = aMV1.Shape(); + 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 TopoDS_Shape& aFx = aMFS.FindKey(i); + const BOPCol_ListOfShape& aLSx = aMFS(i); + if (aLSx.Extent() == 1) { + // check orientation + const TopoDS_Face& aF = *(TopoDS_Face*)&aFx; + if (!anOrigins.Contains(aF)) { + aLSF2.Append(aFx); + continue; + } + // + const TopTools_ListOfShape& aLFOr = anOrigins.FindFromKey(aFx); + aItLS.Initialize(aLFOr); + for (; aItLS.More(); aItLS.Next()) { + const TopoDS_Face& aFOr = *(TopoDS_Face*)&aItLS.Value(); + // + if (CheckNormals(aF, aFOr)) { + aLSF2.Append(aFx); + break; + } + } + } + } + // + // make solid containing most outer faces + BOPAlgo_MakerVolume aMV2; + // + aMV2.SetArguments(aLSF2); + aMV2.SetIntersect(Standard_False); + // + aMV2.Perform(); + bDone = (aMV2.ErrorStatus() == 0); + if (bDone) { + aResult = aMV2.Shape(); + } + } + } + // + TopExp_Explorer aExp(aResult, TopAbs_SHELL); + bDone = aExp.More(); + for (; aExp.More(); aExp.Next()) { + const TopoDS_Shape& aSh = aExp.Current(); + aBB.Add(aShells, aSh); + } + 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(); + } } //======================================================================= @@ -2862,7 +3727,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); } } } @@ -2974,38 +3839,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; } @@ -3024,32 +3889,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) { @@ -3057,42 +3922,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; + } + } } } } @@ -3110,7 +3975,7 @@ void BRepOffset_MakeOffset::EncodeRegularity () //======================================================================= static void UpdateTolerance (TopoDS_Shape& S, - const TopTools_IndexedMapOfShape& Faces) + const TopTools_IndexedMapOfShape& Faces) { BRep_Builder B; TopTools_MapOfShape View; @@ -3138,15 +4003,15 @@ static void UpdateTolerance (TopoDS_Shape& S, 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); + 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); } } }