diff --git a/src/Blend/Blend_Point.cdl b/src/Blend/Blend_Point.cdl index 20a86b97ff..1179ac7ece 100644 --- a/src/Blend/Blend_Point.cdl +++ b/src/Blend/Blend_Point.cdl @@ -160,6 +160,11 @@ is PC1,PC2 : Real from Standard); ---Purpose: Creates a point on two curves. + SetParameter(me : in out; + Param : Real from Standard); + ---C++: inline + ---Purpose: Changes parameter on existing point + Parameter(me) returns Real from Standard ---C++: inline diff --git a/src/Blend/Blend_Point.lxx b/src/Blend/Blend_Point.lxx index 3836ebe932..fa1a4313a6 100644 --- a/src/Blend/Blend_Point.lxx +++ b/src/Blend/Blend_Point.lxx @@ -15,6 +15,11 @@ #include #include +inline void Blend_Point::SetParameter(const Standard_Real Param) +{ + prm = Param; +} + inline const gp_Pnt& Blend_Point::PointOnS1 () const { return pt1; diff --git a/src/Blend/Blend_Walking.cdl b/src/Blend/Blend_Walking.cdl index c27137b2e9..3f23cf825a 100644 --- a/src/Blend/Blend_Walking.cdl +++ b/src/Blend/Blend_Walking.cdl @@ -54,8 +54,9 @@ raises NotDone from StdFail is - Create(Surf1,Surf2: TheSurface; Domain1,Domain2: TheTopolTool) - + Create(Surf1,Surf2: TheSurface; + Domain1,Domain2: TheTopolTool; + HGuide : HElSpine from ChFiDS) returns Walking from Blend; @@ -67,7 +68,6 @@ is Perform(me: in out; F : in out Function from Blend; FInv : in out FuncInv from Blend; - HGuide : HElSpine from ChFiDS; Pdep : Real from Standard; Pmax : Real from Standard; MaxStep : Real from Standard; @@ -166,11 +166,22 @@ is InternalPerform (me: in out;F : in out Function from Blend; FInv : in out FuncInv from Blend; - HGuide : HElSpine from ChFiDS; Bound : Real from Standard) is static private; + CorrectExtremityOnOneRst (me; IndexOfRst : Integer from Standard; + theU : Real from Standard; + theV : Real from Standard; + theParam : Real from Standard; + thePntOnRst : Pnt from gp; + NewU : out Real from Standard; + NewV : out Real from Standard; + NewPoint : out Pnt from gp; + NewParam : out Real from Standard) + returns Boolean from Standard + is static private; + IsDone(me) @@ -266,6 +277,10 @@ fields domain2 : TheTopolTool; recdomain1 : TheTopolTool; recdomain2 : TheTopolTool; + hguide : HElSpine from ChFiDS; + ToCorrectOnRst1 : Boolean from Standard; + ToCorrectOnRst2 : Boolean from Standard; + CorrectedParam : Real from Standard; tolesp : Real from Standard; tolgui : Real from Standard; diff --git a/src/Blend/Blend_Walking_1.gxx b/src/Blend/Blend_Walking_1.gxx index e1455a0669..44f18d3643 100644 --- a/src/Blend/Blend_Walking_1.gxx +++ b/src/Blend/Blend_Walking_1.gxx @@ -15,8 +15,10 @@ Blend_Walking::Blend_Walking(const TheSurface& Surf1, const TheSurface& Surf2, const Handle(TheTopolTool)& Domain1, - const Handle(TheTopolTool)& Domain2): + const Handle(TheTopolTool)& Domain2, + const Handle(ChFiDS_HElSpine)& HGuide): sol(1,4),surf1(Surf1),surf2(Surf2), + ToCorrectOnRst1(Standard_False),ToCorrectOnRst2(Standard_False), done(Standard_False), clasonS1(Standard_True),clasonS2(Standard_True), check2d(Standard_True),check(Standard_True), @@ -26,7 +28,8 @@ Blend_Walking::Blend_Walking(const TheSurface& Surf1, domain1 = Domain1; domain2 = Domain2; recdomain1 = Domain1; - recdomain2 = Domain2; + recdomain2 = Domain2; + hguide = HGuide; } void Blend_Walking::SetDomainsToRecadre(const Handle(TheTopolTool)& Domain1, @@ -56,7 +59,6 @@ void Blend_Walking::AddSingularPoint(const Blend_Point& P) void Blend_Walking::Perform(Blend_Function& Func, Blend_FuncInv& FuncInv, - const Handle(ChFiDS_HElSpine)& HGuide, const Standard_Real Pdep, const Standard_Real Pmax, const Standard_Real MaxStep, @@ -135,6 +137,9 @@ void Blend_Walking::Perform(Blend_Function& Func, nbcomputedsection = 1; #endif // Mettre a jour la ligne. + //Correct first parameter if needed + if (ToCorrectOnRst1 || ToCorrectOnRst2) + previousP.SetParameter(CorrectedParam); line->Append(previousP); if(doextremities){ @@ -155,7 +160,7 @@ void Blend_Walking::Perform(Blend_Function& Func, } } - InternalPerform(Func,FuncInv,HGuide,Pmax); + InternalPerform(Func,FuncInv,Pmax); done = Standard_True; } @@ -255,6 +260,8 @@ Standard_Boolean Blend_Walking::PerformFirstSection (Blend_Function& Func, Standard_Boolean Isvtx1 = Standard_False, Isvtx2 = Standard_False; TheVertex Vtx1, Vtx2; gp_Pnt2d p2d; + Standard_Real CorrectedU = 0., CorrectedV = 0.; + gp_Pnt CorrectedPnt; Func.GetTolerance(tolerance, tolesp); Func.GetBounds(infbound, supbound); @@ -358,6 +365,10 @@ Standard_Boolean Blend_Walking::PerformFirstSection (Blend_Function& Func, ParSol(2) = p2d.Y(); ParSol(3) = solrst1(3); ParSol(4) = solrst1(4); + gp_Pnt thePntOnRst = TheSurfaceTool::Value(surf1,ParSol(1),ParSol(2)); + if (CorrectExtremityOnOneRst(1, ParSol(3), ParSol(4), param, thePntOnRst, + CorrectedU,CorrectedV,CorrectedPnt,CorrectedParam)) + ToCorrectOnRst1 = Standard_True; } else { //if (recad2) { @@ -377,6 +388,10 @@ Standard_Boolean Blend_Walking::PerformFirstSection (Blend_Function& Func, ParSol(2) = solrst2(4); ParSol(3) = p2d.X(); ParSol(4) = p2d.Y(); + gp_Pnt thePntOnRst = TheSurfaceTool::Value(surf2,ParSol(3),ParSol(4)); + if (CorrectExtremityOnOneRst(2, ParSol(1), ParSol(2), param, thePntOnRst, + CorrectedU,CorrectedV,CorrectedPnt,CorrectedParam)) + ToCorrectOnRst2 = Standard_True; } Psol = param; @@ -387,26 +402,32 @@ Standard_Boolean Blend_Walking::PerformFirstSection (Blend_Function& Func, { case Blend_OnRst1: { - #ifdef OCCT_DEBUG - if (Blend_GettraceDRAWSECT()) - { - Drawsect(surf1, surf2, sol, param, Func); - } - #endif +#ifdef OCCT_DEBUG + if (Blend_GettraceDRAWSECT()) + { + Drawsect(surf1, surf2, sol, param, Func); + } +#endif MakeExtremity(Ext1, Standard_True, Index1, solrst1(1), Isvtx1, Vtx1); - Ext2.SetValue(previousP.PointOnS2(), sol(3), sol(4), tolesp); + if (ToCorrectOnRst1) + Ext2.SetValue(CorrectedPnt, CorrectedU, CorrectedV, tolesp); + else + Ext2.SetValue(previousP.PointOnS2(), sol(3), sol(4), tolesp); } break; case Blend_OnRst2: { - #ifdef OCCT_DEBUG - if (Blend_GettraceDRAWSECT()) - { - Drawsect(surf1, surf2, sol, param, Func); - } - #endif - Ext1.SetValue(previousP.PointOnS1(), sol(1), sol(2), tolesp); +#ifdef OCCT_DEBUG + if (Blend_GettraceDRAWSECT()) + { + Drawsect(surf1, surf2, sol, param, Func); + } +#endif + if (ToCorrectOnRst2) + Ext1.SetValue(CorrectedPnt, CorrectedU, CorrectedV, tolesp); + else + Ext1.SetValue(previousP.PointOnS1(), sol(1), sol(2), tolesp); MakeExtremity(Ext2, Standard_False, Index2, solrst2(1), Isvtx2, Vtx2); } break; @@ -462,8 +483,7 @@ Standard_Boolean Blend_Walking::Continu(Blend_Function& Func, previousP.ParametersOnS1(sol(1),sol(2)); previousP.ParametersOnS2(sol(3),sol(4)); - Handle(ChFiDS_HElSpine) anHGuide; - InternalPerform(Func,FuncInv,anHGuide,P); + InternalPerform(Func,FuncInv,P); return Standard_True; } @@ -504,8 +524,7 @@ Standard_Boolean Blend_Walking::Continu(Blend_Function& Func, if(OnS1) clasonS1 = Standard_False; else clasonS2 = Standard_False; - Handle(ChFiDS_HElSpine) anHGuide; - InternalPerform(Func,FuncInv,anHGuide,P); + InternalPerform(Func,FuncInv,P); clasonS1 = Standard_True; clasonS2 = Standard_True; @@ -551,8 +570,7 @@ Standard_Boolean Blend_Walking::Complete(Blend_Function& Func, previousP.ParametersOnS1(sol(1),sol(2)); previousP.ParametersOnS2(sol(3),sol(4)); - Handle(ChFiDS_HElSpine) anHGuide; - InternalPerform(Func,FuncInv,anHGuide,Pmin); + InternalPerform(Func,FuncInv,Pmin); iscomplete = Standard_True; return Standard_True; diff --git a/src/Blend/Blend_Walking_4.gxx b/src/Blend/Blend_Walking_4.gxx index 26b4a3bc14..6d31e16ac6 100644 --- a/src/Blend/Blend_Walking_4.gxx +++ b/src/Blend/Blend_Walking_4.gxx @@ -13,6 +13,29 @@ // commercial license or contractual agreement. #include +#include +#include + +static void RecadreIfPeriodic(Standard_Real& NewU, + Standard_Real& NewV, + const Standard_Real OldU, + const Standard_Real OldV, + const Standard_Real UPeriod, + const Standard_Real VPeriod) +{ + if (UPeriod > 0.) + { + Standard_Real sign = (NewU < OldU)? 1 : -1; + while (Abs(NewU - OldU) > UPeriod/2) + NewU += sign * UPeriod; + } + if (VPeriod > 0.) + { + Standard_Real sign = (NewV < OldV)? 1 : -1; + while (Abs(NewV - OldV) > VPeriod/2) + NewV += sign * VPeriod; + } +} static void evalpinit(math_Vector& parinit, const Blend_Point& previousP, @@ -67,7 +90,6 @@ static void evalpinit(math_Vector& parinit, void Blend_Walking::InternalPerform(Blend_Function& Func, Blend_FuncInv& FuncInv, - const Handle(ChFiDS_HElSpine)& HGuide, const Standard_Real Bound) { @@ -263,55 +285,62 @@ void Blend_Walking::InternalPerform(Blend_Function& Func, sol(3) = p2d.X(); sol(4) = p2d.Y(); Pnt2 = TheSurfaceTool::Value(surf2,sol(3),sol(4)); - if (!HGuide.IsNull()) + const Standard_Real TolProd = 1.e-5; + Standard_Real SavedParams [2]; + Standard_Boolean SameDirs [2] = {Standard_False, Standard_False}; + ChFiDS_ElSpine& theElSpine = hguide->ChangeCurve(); + SavedParams[0] = theElSpine.GetSavedFirstParameter(); + SavedParams[1] = theElSpine.GetSavedLastParameter(); + for (Standard_Integer ind = 0; ind < 2; ind++) { - const Standard_Real TolProd = 1.e-5; - Standard_Real SavedParams [2]; - Standard_Boolean SameDirs [2] = {Standard_False, Standard_False}; - ChFiDS_ElSpine& theElSpine = HGuide->ChangeCurve(); - SavedParams[0] = theElSpine.GetSavedFirstParameter(); - SavedParams[1] = theElSpine.GetSavedLastParameter(); - for (Standard_Integer ind = 0; ind < 2; ind++) + if (!Precision::IsInfinite(SavedParams[ind])) { - if (!Precision::IsInfinite(SavedParams[ind])) - { - //Check the original first and last parameters of guide curve - //for equality to found parameter : - //check equality of tangent to guide curve and - //normal to plane built on 3 points: - //point on guide curve and points on restrictions of adjacent - //surfaces. - gp_Pnt Pnt0; - gp_Vec Dir0; - HGuide->D1(SavedParams[ind], Pnt0, Dir0); - Standard_Real Length = Dir0.Magnitude(); - if (Length <= gp::Resolution()) - continue; - Dir0 /= Length; - gce_MakePln PlaneBuilder(Pnt0, Pnt1, Pnt2); - if (!PlaneBuilder.IsDone()) - continue; - gp_Pln thePlane = PlaneBuilder.Value(); - gp_Dir DirPlane = thePlane.Axis().Direction(); - gp_Vec theProd = Dir0 ^ DirPlane; - Standard_Real ProdMod = theProd.Magnitude(); - if (ProdMod <= TolProd) - SameDirs[ind] = Standard_True; - } + //Check the original first and last parameters of guide curve + //for equality to found parameter : + //check equality of tangent to guide curve and + //normal to plane built on 3 points: + //point on guide curve and points on restrictions of adjacent + //surfaces. + gp_Pnt Pnt0; + gp_Vec Dir0; + hguide->D1(SavedParams[ind], Pnt0, Dir0); + Standard_Real Length = Dir0.Magnitude(); + if (Length <= gp::Resolution()) + continue; + Dir0 /= Length; + gce_MakePln PlaneBuilder(Pnt0, Pnt1, Pnt2); + if (!PlaneBuilder.IsDone()) + continue; + gp_Pln thePlane = PlaneBuilder.Value(); + gp_Dir DirPlane = thePlane.Axis().Direction(); + gp_Vec theProd = Dir0 ^ DirPlane; + Standard_Real ProdMod = theProd.Magnitude(); + if (ProdMod <= TolProd) + SameDirs[ind] = Standard_True; } - Standard_Real theParam = Precision::Infinite(); - //Choose the closest parameter - if (SameDirs[0] && SameDirs[1]) - theParam = (Abs(param - SavedParams[0]) < Abs(param - SavedParams[1]))? - SavedParams[0] : SavedParams[1]; - else if (SameDirs[0]) - theParam = SavedParams[0]; - else if (SameDirs[1]) - theParam = SavedParams[1]; - - if (!Precision::IsInfinite(theParam)) - param = theParam; } + Standard_Real theParam = Precision::Infinite(); + //Choose the closest parameter + if (SameDirs[0] && SameDirs[1]) + theParam = (Abs(param - SavedParams[0]) < Abs(param - SavedParams[1]))? + SavedParams[0] : SavedParams[1]; + else if (SameDirs[0]) + theParam = SavedParams[0]; + else if (SameDirs[1]) + theParam = SavedParams[1]; + + Standard_Real NewU, NewV, NewParam; + gp_Pnt NewPnt; + Standard_Boolean Corrected = CorrectExtremityOnOneRst(1, sol(3), sol(4), param, Pnt1, + NewU, NewV, NewPnt, NewParam); + if (Corrected) + { + if (Abs(param - NewParam) < Abs(param - theParam)) + theParam = NewParam; + } + + if (!Precision::IsInfinite(theParam)) + param = theParam; } else if (recad1) { // sol sur 1 @@ -328,6 +357,17 @@ void Blend_Walking::InternalPerform(Blend_Function& Func, sol(2) = p2d.Y(); sol(3) = solrst1(3); sol(4) = solrst1(4); + gp_Pnt thePntOnRst = TheSurfaceTool::Value(surf1,sol(1),sol(2)); + Standard_Real NewU, NewV, NewParam; + gp_Pnt NewPnt; + Standard_Boolean Corrected = CorrectExtremityOnOneRst(1, sol(3), sol(4), param, thePntOnRst, + NewU, NewV, NewPnt, NewParam); + if (Corrected) + { + param = NewParam; + sol(3) = NewU; + sol(4) = NewV; + } } else if (recad2) { //sol sur 2 @@ -345,6 +385,17 @@ void Blend_Walking::InternalPerform(Blend_Function& Func, sol(2) = solrst2(4); sol(3) = p2d.X(); sol(4) = p2d.Y(); + gp_Pnt thePntOnRst = TheSurfaceTool::Value(surf2,sol(3),sol(4)); + Standard_Real NewU, NewV, NewParam; + gp_Pnt NewPnt; + Standard_Boolean Corrected = CorrectExtremityOnOneRst(2, sol(1), sol(2), param, thePntOnRst, + NewU, NewV, NewPnt, NewParam); + if (Corrected) + { + param = NewParam; + sol(1) = NewU; + sol(2) = NewV; + } } else { State = Blend_OK; @@ -610,3 +661,146 @@ void Blend_Walking::InternalPerform(Blend_Function& Func, } } + +Standard_Boolean Blend_Walking::CorrectExtremityOnOneRst(const Standard_Integer IndexOfRst, + const Standard_Real theU, + const Standard_Real theV, + const Standard_Real theParam, + const gp_Pnt& thePntOnRst, + Standard_Real& NewU, + Standard_Real& NewV, + gp_Pnt& NewPoint, + Standard_Real& NewParam) const +{ + const Standard_Real TolAng = 0.001; //bug OCC25701 + + ChFiDS_ElSpine& theElSpine = hguide->ChangeCurve(); + if (theElSpine.NbVertices() == 0) + return Standard_False; + + Handle(TheTopolTool) DomainOfRst = (IndexOfRst == 1)? recdomain1 : recdomain2; + TheSurface SurfOfRst = (IndexOfRst == 1)? surf1 : surf2; + TheSurface AnotherSurf = (IndexOfRst == 1)? surf2 : surf1; + + //Correct point on surface 2 + //First we find right + Standard_Real Ends [2]; + Ends[0] = TheArcTool::FirstParameter(DomainOfRst->Value()); + Ends[1] = TheArcTool::LastParameter(DomainOfRst->Value()); + Standard_Real GlobalMinSqDist = Precision::Infinite(); + Standard_Real ParamOnGuide = 0; + gp_Pnt PointOnGuide; + for (Standard_Integer k = 0; k < 2; k++) + { + gp_Pnt2d P2dOnEnd = TheArcTool::Value(DomainOfRst->Value(), Ends[k]); + gp_Pnt PntOnEnd = TheSurfaceTool::Value(SurfOfRst, P2dOnEnd.X(), P2dOnEnd.Y()); + Extrema_ExtPC projoncurv(PntOnEnd, theElSpine); + if (!projoncurv.IsDone()) + continue; + Standard_Real MinSqDist = Precision::Infinite(); + Standard_Integer imin = 0; + for (Standard_Integer ind = 1; ind <= projoncurv.NbExt(); ind++) + { + Standard_Real aSqDist = projoncurv.SquareDistance(ind); + if (aSqDist < MinSqDist) + { + MinSqDist = aSqDist; + imin = ind; + } + } + if (MinSqDist < GlobalMinSqDist) + { + GlobalMinSqDist = MinSqDist; + ParamOnGuide = projoncurv.Point(imin).Parameter(); + PointOnGuide = projoncurv.Point(imin).Value(); + } + } + NewParam = ParamOnGuide; + if (hguide->IsPeriodic()) + { + Standard_Real Period = hguide->Period(); + Standard_Real sign = (NewParam < theParam)? 1 : -1; + while (Abs(NewParam - theParam) > Period/2) + NewParam += sign *Period; + } + + //Second we find right point and tangent on guide + GlobalMinSqDist = Precision::Infinite(); + gp_Ax1 theAx1; + for (Standard_Integer ind = 1; ind <= theElSpine.NbVertices(); ind++) + { + const gp_Ax1& anAx1 = theElSpine.VertexWithTangent(ind); + gp_Pnt aPnt = anAx1.Location(); + Standard_Real aSqDist = PointOnGuide.SquareDistance(aPnt); + if (aSqDist < GlobalMinSqDist) + { + GlobalMinSqDist = aSqDist; + theAx1 = anAx1; + } + } + const gp_Pnt& Pnt0 = theAx1.Location(); + const gp_Dir& Dir0 = theAx1.Direction(); + //Check new point: is it real solution? + gp_Pnt OldPonGuide = hguide->Value(theParam); + gp_Pnt PntOnSurf2 = TheSurfaceTool::Value(AnotherSurf,theU,theV); //old point + gce_MakePln PlaneBuilder(thePntOnRst, OldPonGuide, PntOnSurf2); + if (!PlaneBuilder.IsDone()) + return Standard_False; + gp_Pln OldPlane = PlaneBuilder.Value(); + gp_Dir OldDir = OldPlane.Axis().Direction(); + Standard_Real Angle = OldDir.Angle(Dir0); + if (Angle > M_PI/2) + Angle = M_PI - Angle; + if (Angle > TolAng) + return Standard_False; + /////////////////////////////////////// + //Project the point(theU,theV) on the plane(Pnt0,Dir0) + gp_Vec aVec(Pnt0, PntOnSurf2); + gp_Vec aTranslation( (aVec.XYZ() * Dir0.XYZ()) * Dir0.XYZ() ); + gp_Pnt PntOnPlane = PntOnSurf2.Translated(-aTranslation); + + //Check new point again: does point on restriction belong to the plane? + PlaneBuilder = gce_MakePln(thePntOnRst, Pnt0, PntOnPlane); + if (!PlaneBuilder.IsDone()) + return Standard_False; + gp_Pln NewPlane = PlaneBuilder.Value(); + const gp_Dir& DirOfNewPlane = NewPlane.Axis().Direction(); + Angle = Dir0.Angle(DirOfNewPlane); + if (Angle > M_PI/2) + Angle = M_PI - Angle; + if (Angle > TolAng) + return Standard_False; + //////////////////////////////////////////////////////////////////////// + + //Project the point on the surface 2 + Extrema_ExtPS projonsurf(PntOnPlane, AnotherSurf->Surface(), + Precision::PConfusion(), Precision::PConfusion(), + Extrema_ExtFlag_MIN); + if (projonsurf.IsDone()) + { + Standard_Real MinSqDist = Precision::Infinite(); + Standard_Integer imin = 0; + for (Standard_Integer ind = 1; ind <= projonsurf.NbExt(); ind++) + { + Standard_Real aSqDist = projonsurf.SquareDistance(ind); + if (aSqDist < MinSqDist) + { + MinSqDist = aSqDist; + imin = ind; + } + } + if (imin) + { + Extrema_POnSurf NewPOnSurf2 = projonsurf.Point(imin); + NewPoint = NewPOnSurf2.Value(); + NewPOnSurf2.Parameter(NewU, NewV); + Standard_Real uperiod = (AnotherSurf->IsUPeriodic())? AnotherSurf->UPeriod() : 0.; + Standard_Real vperiod = (AnotherSurf->IsVPeriodic())? AnotherSurf->VPeriod() : 0.; + RecadreIfPeriodic(NewU, NewV, theU, theV, + uperiod, vperiod); + return Standard_True; + } + } + + return Standard_False; +} diff --git a/src/ChFi3d/ChFi3d_Builder_0.cxx b/src/ChFi3d/ChFi3d_Builder_0.cxx index a57c2e3e35..2ea8423b08 100644 --- a/src/ChFi3d/ChFi3d_Builder_0.cxx +++ b/src/ChFi3d/ChFi3d_Builder_0.cxx @@ -3954,6 +3954,16 @@ Standard_EXPORT const BRepAdaptor_Curve& edc = Spine->CurrentElementarySpine(IF); tolpared = edc.Resolution(tol); Cv = BRep_Tool::Curve(E, First, Last); + //Add vertex with tangent + if (ES.IsPeriodic()) + { + Standard_Real ParForElSpine = (E.Orientation() == TopAbs_FORWARD)? First : Last; + gp_Pnt PntForElSpine; + gp_Vec DirForElSpine; + Cv->D1(ParForElSpine, PntForElSpine, DirForElSpine); + ES.AddVertexWithTangent(gp_Ax1(PntForElSpine, DirForElSpine)); + } + ///////////////////////// urefdeb = Spine->FirstParameter(IF); checkdeb = (nwf > urefdeb); if(checkdeb) { @@ -4080,6 +4090,13 @@ Standard_EXPORT } // Cv = BRep_Tool::Curve(E, First, Last); + //Add vertex with tangent + Standard_Real ParForElSpine = (E.Orientation() == TopAbs_FORWARD)? First : Last; + gp_Pnt PntForElSpine; + gp_Vec DirForElSpine; + Cv->D1(ParForElSpine, PntForElSpine, DirForElSpine); + ES.AddVertexWithTangent(gp_Ax1(PntForElSpine, DirForElSpine)); + ///////////////////////// if(IEdge == IL) { Standard_Real ureffin = Spine->LastParameter(iloc); Standard_Boolean checkfin = (nwl < ureffin); diff --git a/src/ChFi3d/ChFi3d_Builder_6.cxx b/src/ChFi3d/ChFi3d_Builder_6.cxx index 78fc8c07ad..0135f062bc 100644 --- a/src/ChFi3d/ChFi3d_Builder_6.cxx +++ b/src/ChFi3d/ChFi3d_Builder_6.cxx @@ -684,6 +684,24 @@ Standard_Boolean ChFi3d_Builder::StoreData(Handle(ChFiDS_SurfData)& Data, if (length2 > Precision::Confusion()) GeomLib::ExtendSurfByLength(Surf,length2,1,Standard_False,Standard_True); + //Correction of surface on extremities + if (length1 <= Precision::Confusion()) + { + gp_Pnt P11, P21; + P11 = lin->StartPointOnFirst().Value(); + P21 = lin->StartPointOnSecond().Value(); + Surf->SetPole(1, 1, P11); + Surf->SetPole(Surf->NbUPoles(), 1, P21); + } + if (length2 <= Precision::Confusion()) + { + gp_Pnt P12, P22; + P12 = lin->EndPointOnFirst().Value(); + P22 = lin->EndPointOnSecond().Value(); + Surf->SetPole(1, Surf->NbVPoles(), P12); + Surf->SetPole(Surf->NbUPoles(), Surf->NbVPoles(), P22); + } + Data->ChangeSurf(DStr.AddSurface(TopOpeBRepDS_Surface(Surf,tolget3d))); #ifdef DRAW @@ -1475,7 +1493,7 @@ Standard_Boolean ChFi3d_Builder::ComputeData Standard_Real TolGuide=tolguide, TolEsp = tolesp; Standard_Integer nbptmin = 4; - BRepBlend_Walking TheWalk(S1,S2,I1,I2); + BRepBlend_Walking TheWalk(S1,S2,I1,I2,HGuide); //Start of removal, 2D path controls //that qui s'accomodent mal des surfaces a parametrages non homogenes @@ -1573,7 +1591,7 @@ Standard_Boolean ChFi3d_Builder::ComputeData if (5*TolGuide > MS) TolGuide = MS/5; if (5*TolEsp > MS) TolEsp = MS/5; } - TheWalk.Perform(Func,FInv,HGuide,NewFirst,Target,MS,TolGuide, + TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide, ParSol,TolEsp,Fleche,Appro); if (!TheWalk.IsDone()) { #ifdef OCCT_DEBUG @@ -2068,7 +2086,7 @@ Standard_Boolean ChFi3d_Builder::SimulData const Standard_Boolean RecOnS1, const Standard_Boolean RecOnS2) { - BRepBlend_Walking TheWalk(S1,S2,I1,I2); + BRepBlend_Walking TheWalk(S1,S2,I1,I2,HGuide); TheWalk.Check2d(Standard_False); Standard_Real MS = MaxStep; @@ -2113,7 +2131,7 @@ Standard_Boolean ChFi3d_Builder::SimulData if (5*TolEsp > MS) TolEsp = MS/5; } - TheWalk.Perform(Func,FInv,HGuide,NewFirst,Target,MS,TolGuide, + TheWalk.Perform(Func,FInv,NewFirst,Target,MS,TolGuide, ParSol,TolEsp,Fleche,Appro); if (!TheWalk.IsDone()) { diff --git a/src/ChFi3d/ChFi3d_ChBuilder.cxx b/src/ChFi3d/ChFi3d_ChBuilder.cxx index 9acabb7b49..04ceed1965 100644 --- a/src/ChFi3d/ChFi3d_ChBuilder.cxx +++ b/src/ChFi3d/ChFi3d_ChBuilder.cxx @@ -1289,7 +1289,7 @@ Standard_Boolean ChFi3d_ChBuilder::PerformFirstSection BRepBlend_Chamfer Func(S1,S2,HGuide); Func.Set(dis,dis,Choix); - BRepBlend_Walking TheWalk(S1,S2,I1,I2); + BRepBlend_Walking TheWalk(S1,S2,I1,I2,HGuide); //calculate an approximate starting solution gp_Vec TgF, TgL, tmp1, tmp2, d1gui; @@ -1346,7 +1346,7 @@ Standard_Boolean ChFi3d_ChBuilder::PerformFirstSection BRepBlend_Chamfer Func(S1,S2,HGuide); Func.Set(dis1,dis2,Choix); - BRepBlend_Walking TheWalk(S1,S2,I1,I2); + BRepBlend_Walking TheWalk(S1,S2,I1,I2,HGuide); //calculate an approximate starting solution gp_Vec TgF, TgL, tmp1, tmp2, d1gui; @@ -1407,7 +1407,7 @@ Standard_Boolean ChFi3d_ChBuilder::PerformFirstSection if (disonF1) { BRepBlend_ChAsym Func(S1,S2,HGuide); Func.Set(dis1, angle, Ch); - BRepBlend_Walking TheWalk(S1,S2,I1,I2); + BRepBlend_Walking TheWalk(S1,S2,I1,I2,HGuide); //calculate an approximate starting solution gp_Vec TgF, TgL, tmp1, tmp2, d1gui; @@ -1469,7 +1469,7 @@ Standard_Boolean ChFi3d_ChBuilder::PerformFirstSection Standard_Real Rtemp; BRepBlend_ChAsym Func(S2,S1,HGuide); Func.Set(dis1, angle, Ch); - BRepBlend_Walking TheWalk(S2,S1,I2,I1); + BRepBlend_Walking TheWalk(S2,S1,I2,I1,HGuide); //calculate an approximate starting solution gp_Vec TgF, TgL, tmp1, tmp2, d1gui; diff --git a/src/ChFi3d/ChFi3d_FilBuilder.cxx b/src/ChFi3d/ChFi3d_FilBuilder.cxx index b0a1ddcd49..98aaf957b3 100644 --- a/src/ChFi3d/ChFi3d_FilBuilder.cxx +++ b/src/ChFi3d/ChFi3d_FilBuilder.cxx @@ -1198,7 +1198,7 @@ Standard_Boolean ChFi3d_FilBuilder::PerformFirstSection BRepBlend_ConstRad Func(S1,S2,HGuide); Func.Set(fsp->Radius(),Choix); Func.Set(myShape); - BRepBlend_Walking TheWalk(S1,S2,I1,I2); + BRepBlend_Walking TheWalk(S1,S2,I1,I2,HGuide); return TheWalk.PerformFirstSection(Func,Par,SolDep, tolesp,TolGuide,Pos1,Pos2); } @@ -1206,7 +1206,7 @@ Standard_Boolean ChFi3d_FilBuilder::PerformFirstSection BRepBlend_EvolRad Func(S1,S2,HGuide,fsp->Law(HGuide)); Func.Set(Choix); Func.Set(myShape); - BRepBlend_Walking TheWalk(S1,S2,I1,I2); + BRepBlend_Walking TheWalk(S1,S2,I1,I2,HGuide); return TheWalk.PerformFirstSection(Func,Par,SolDep, tolesp,TolGuide,Pos1,Pos2); } diff --git a/src/ChFiDS/ChFiDS_ElSpine.cdl b/src/ChFiDS/ChFiDS_ElSpine.cdl index 6b5483e2f4..4253ff11b9 100644 --- a/src/ChFiDS/ChFiDS_ElSpine.cdl +++ b/src/ChFiDS/ChFiDS_ElSpine.cdl @@ -26,9 +26,11 @@ uses Elips from gp, Hypr from gp, Parab from gp, + Ax1 from gp, BezierCurve from Geom, BSplineCurve from Geom, Array1OfReal from TColStd, + SequenceOfAx1 from TColgp, SurfData from ChFiDS, Shape from GeomAbs, CurveType from GeomAbs, @@ -116,9 +118,17 @@ is LastPointAndTgt(me; P : out Pnt from gp; T : out Vec from gp); + NbVertices(me) returns Integer from Standard; + + VertexWithTangent(me; Index : Integer from Standard) + returns Ax1 from gp; + ---C++: return const & + SetFirstPointAndTgt(me : in out; P : Pnt from gp; T : Vec from gp); SetLastPointAndTgt(me : in out; P : Pnt from gp; T : Vec from gp); + + AddVertexWithTangent(me : in out; anAx1 : Ax1 from gp); SetCurve(me : in out; C : Curve from Geom); @@ -187,6 +197,7 @@ ptfirst : Pnt from gp; ptlast : Pnt from gp; tgfirst : Vec from gp; tglast : Vec from gp; +VerticesWithTangents : SequenceOfAx1 from TColgp; previous : SurfData from ChFiDS; next : SurfData from ChFiDS; diff --git a/src/ChFiDS/ChFiDS_ElSpine.cxx b/src/ChFiDS/ChFiDS_ElSpine.cxx index a7d47fa28e..d404427b90 100644 --- a/src/ChFiDS/ChFiDS_ElSpine.cxx +++ b/src/ChFiDS/ChFiDS_ElSpine.cxx @@ -311,6 +311,16 @@ void ChFiDS_ElSpine::SetLastPointAndTgt(const gp_Pnt& P, tglast = T; } +//======================================================================= +//function : AddVertexWithTangent +//purpose : +//======================================================================= + +void ChFiDS_ElSpine::AddVertexWithTangent(const gp_Ax1& anAx1) +{ + VerticesWithTangents.Append(anAx1); +} + //======================================================================= //function : FirstPointAndTgt //purpose : @@ -335,6 +345,26 @@ void ChFiDS_ElSpine::LastPointAndTgt(gp_Pnt& P, T = tglast; } +//======================================================================= +//function : NbVertices +//purpose : +//======================================================================= + +Standard_Integer ChFiDS_ElSpine::NbVertices() const +{ + return VerticesWithTangents.Length(); +} + +//======================================================================= +//function : VertexWithTangent +//purpose : +//======================================================================= + +const gp_Ax1& ChFiDS_ElSpine::VertexWithTangent(const Standard_Integer Index) const +{ + return VerticesWithTangents(Index); +} + //======================================================================= //function : SetCurve //purpose : diff --git a/src/TColgp/TColgp.cdl b/src/TColgp/TColgp.cdl index 1dbef3c5b8..f7ecfcb8b2 100644 --- a/src/TColgp/TColgp.cdl +++ b/src/TColgp/TColgp.cdl @@ -169,6 +169,8 @@ is instantiates Sequence from TCollection (Vec from gp); class SequenceOfXYZ instantiates Sequence from TCollection (XYZ from gp); + class SequenceOfAx1 + instantiates Sequence from TCollection (Ax1 from gp); -- HSequences of 3D objects. diff --git a/tests/bugs/modalg_5/bug25701 b/tests/bugs/modalg_5/bug25701 new file mode 100644 index 0000000000..c24eb000f9 --- /dev/null +++ b/tests/bugs/modalg_5/bug25701 @@ -0,0 +1,42 @@ +puts "===========" +puts "OCC25701" +puts "===========" +puts "" +###################################################### +# Problem with the symmetry of fillet on two perpendicular cylinders +###################################################### + +restore [locate_data_file bug25701_rx.brep] rx + +explode rx e +smallview +donly rx rx_2 rx_5 +compound rx_2 rx_5 q + +fillet x rx 2.5 q +explode x e +donly x x_9 +fit + +mkcurve cx_9 x_9 + +set log [dump cx_9] + +regexp {Degree +([-0-9.+eE]+), +([-0-9.+eE]+) Poles, +([-0-9.+eE]+)} ${log} full Degree Poles KnotsPoles +puts "Degree=${Degree}" +puts "Poles=${Poles}" +puts "KnotsPoles=${KnotsPoles}" +puts "" + +set tol_abs 1.e-11 +set tol_rel 0.01 +set expected_V 0. + +for {set i 1} {${i} <= ${Poles}} {incr i} { + set exp_string " +${i} : +(\[-0-9.+eE\]+), +(\[-0-9.+eE\]+)" + regexp ${exp_string} ${log} full U_i V_i + puts "i=${i} U_i=${U_i} V_i=${V_i}" + checkreal "V_$i" ${V_i} ${expected_V} ${tol_abs} ${tol_rel} +} + +set only_screen_axo 1