diff --git a/src/BOPTest/BOPTest_BOPCommands.cxx b/src/BOPTest/BOPTest_BOPCommands.cxx index f4944b96a2..bcd8aa1030 100644 --- a/src/BOPTest/BOPTest_BOPCommands.cxx +++ b/src/BOPTest/BOPTest_BOPCommands.cxx @@ -103,7 +103,7 @@ static Standard_Integer bopnews (Draw_Interpretor&, Standard_Integer, const ch theCommands.Add("bsection", "Use >bsection r s1 s2 [-n2d/-n2d1/-n2d2] [-na]", __FILE__, bsection, g); // - theCommands.Add("bopcurves", "use bopcurves F1 F2", __FILE__, bopcurves, g); + theCommands.Add("bopcurves", "use bopcurves F1 F2 [-2d]", __FILE__, bopcurves, g); theCommands.Add("bopnews", "use bopnews -v[e,f]" , __FILE__, bopnews, g); } @@ -541,7 +541,7 @@ Standard_Integer bopcurves (Draw_Interpretor& di, const char** a) { if (n<3) { - di << " use bopcurves F1 F2\n"; + di << " use bopcurves F1 F2 [-2d]\n"; return 1; } @@ -569,14 +569,25 @@ Standard_Integer bopcurves (Draw_Interpretor& di, const TopoDS_Face& aF1=*(TopoDS_Face*)(&S1); const TopoDS_Face& aF2=*(TopoDS_Face*)(&S2); - Standard_Boolean aToApproxC3d, aToApproxC2dOnS1, aToApproxC2dOnS2, anIsDone; + Standard_Boolean aToApproxC3d, aToApproxC2dOnS1, aToApproxC2dOnS2, anIsDone, bMake2dCurves; Standard_Integer i, aNbCurves; Standard_Real anAppTol, aTolR; TCollection_AsciiString aNm("c_"); - aToApproxC3d=Standard_True; - aToApproxC2dOnS1=Standard_False; - aToApproxC2dOnS2=Standard_False; + bMake2dCurves = Standard_False; + if (n > 3) { + if (!strcasecmp(a[3],"-2d")) { + bMake2dCurves = Standard_True; + } else { + di << "Wrong key. To build 2d curves use: bopcurves F1 F2 -2d \n"; + return 1; + } + } + // + + aToApproxC3d = Standard_True; + aToApproxC2dOnS1 = bMake2dCurves; + aToApproxC2dOnS2 = bMake2dCurves; anAppTol=0.0000001; @@ -595,7 +606,7 @@ Standard_Integer bopcurves (Draw_Interpretor& di, return 1; } - aFF.PrepareLines3D(); + aFF.PrepareLines3D(Standard_False); const IntTools_SequenceOfCurves& aSCs=aFF.Lines(); // @@ -607,22 +618,68 @@ Standard_Integer bopcurves (Draw_Interpretor& di, di << " has no 3d curve\n"; return 1; } + else + { + di << aNbCurves << " curve(s) found.\n"; + } for (i=1; i<=aNbCurves; i++) { const IntTools_Curve& anIC=aSCs(i); - Handle (Geom_Curve) aC3D=anIC.Curve(); + Handle (Geom_Curve) aC3D = anIC.Curve(); if (aC3D.IsNull()) { - di << " has Null 3d curve# " << i << "%d\n"; + di << " has Null 3d curve# " << i << "\n"; continue; } TCollection_AsciiString anIndx(i), aNmx; - aNmx=aNm+anIndx; - Standard_CString name= aNmx.ToCString(); - DrawTrSurf::Set(name, aC3D); - di << name << " "; + aNmx = aNm + anIndx; + + Standard_CString nameC = aNmx.ToCString(); + + DrawTrSurf::Set(nameC, aC3D); + di << nameC << " "; + // + if (bMake2dCurves) { + Handle(Geom2d_Curve) aPC1 = anIC.FirstCurve2d(); + Handle(Geom2d_Curve) aPC2 = anIC.SecondCurve2d(); + // + if (aPC1.IsNull() && aPC2.IsNull()) { + di << " \n has Null 2d curves# " << i << "\n"; + continue; + } + // + if (aPC1.IsNull()) { + TCollection_AsciiString pc2N("c2d2_"), pc2Nx; + pc2Nx = pc2N + anIndx; + Standard_CString nameC2d2 = pc2Nx.ToCString(); + // + DrawTrSurf::Set(nameC2d2, aPC2); + di << "(" << nameC2d2 << ") "; + di << " \n Null first 2d curve of the curve #" << i << "\n"; + continue; + } else { + TCollection_AsciiString pc1N("c2d1_"), pc1Nx; + pc1Nx = pc1N + anIndx; + Standard_CString nameC2d1 = pc1Nx.ToCString(); + // + DrawTrSurf::Set(nameC2d1, aPC1); + di << "(" << nameC2d1; + } + // + if (aPC2.IsNull()) { + di << ") \n Null second 2d curve of the curve #" << i << "\n"; + continue; + } else { + TCollection_AsciiString pc2N("c2d2_"), pc2Nx; + pc2Nx = pc2N + anIndx; + Standard_CString nameC2d2 = pc2Nx.ToCString(); + // + DrawTrSurf::Set(nameC2d2, aPC2); + di << ", " << nameC2d2 << ") "; + } + } } di << "\n"; diff --git a/src/IntPatch/IntPatch_PrmPrmIntersection.cxx b/src/IntPatch/IntPatch_PrmPrmIntersection.cxx index b581ba68ea..82fda552d6 100644 --- a/src/IntPatch/IntPatch_PrmPrmIntersection.cxx +++ b/src/IntPatch/IntPatch_PrmPrmIntersection.cxx @@ -1371,7 +1371,11 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& if(dminiPointLigne > SeuildPointLigne) { PW.Perform(StartParams,UminLig1,VminLig1,UminLig2,VminLig2,UmaxLig1,VmaxLig1,UmaxLig2,VmaxLig2); if(PW.IsDone()) { - if(PW.NbPoints()>2) { + if(PW.NbPoints()>2) + { + //Try to extend the intersection line to boundary, if it is possibly + Standard_Boolean hasBeenAdded = PW.PutToBoundary(Surf1, Surf2); + RejetLigne = Standard_False; Point3dDebut = PW.Value(1).Value(); const IntSurf_PntOn2S& PointFin = PW.Value(PW.NbPoints()); @@ -1419,8 +1423,8 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Standard_Real TolTang = TolTangency; Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2); if (RestrictLine){ - IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang); - IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang); + IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang,hasBeenAdded); + IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang,hasBeenAdded); } if(wline->NbVertex() == 0) { @@ -2125,10 +2129,14 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur // if( iPWNbPoints > 2 ) { + //Try to extend the intersection line to boundary, if it is possibly + Standard_Boolean hasBeenAdded = PW.PutToBoundary(Surf1, Surf2); + const Standard_Integer aMinNbPoints = 40; if(iPWNbPoints < aMinNbPoints) { - PW.SeekAdditionalPoints(Surf1, Surf2, aMinNbPoints); + hasBeenAdded = + PW.SeekAdditionalPoints(Surf1, Surf2, aMinNbPoints) || hasBeenAdded; iPWNbPoints = PW.NbPoints(); } @@ -2224,8 +2232,8 @@ void IntPatch_PrmPrmIntersection::Perform (const Handle(Adaptor3d_HSurface)& Sur Standard_Real TolTang = TolTangency; Handle(IntPatch_WLine) wline = new IntPatch_WLine(PW.Line(),Standard_False,trans1,trans2); - IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang); - IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang); + IntPatch_RstInt::PutVertexOnLine(wline,Surf1,D1,Surf2,Standard_True,TolTang,hasBeenAdded); + IntPatch_RstInt::PutVertexOnLine(wline,Surf2,D2,Surf1,Standard_False,TolTang,hasBeenAdded); if(wline->NbVertex() == 0) { diff --git a/src/IntPatch/IntPatch_RstInt.cdl b/src/IntPatch/IntPatch_RstInt.cdl index 29e0ad0d5f..5746f7647e 100644 --- a/src/IntPatch/IntPatch_RstInt.cdl +++ b/src/IntPatch/IntPatch_RstInt.cdl @@ -34,7 +34,8 @@ is Domain : TopolTool from Adaptor3d; OtherSurf : HSurface from Adaptor3d; OnFirst : Boolean from Standard ; - Tol : Real from Standard) + Tol : Real from Standard; + hasBeenAdded: Boolean from Standard = Standard_False) raises DomainError from Standard; --- The exception is raised if the Line from is neither diff --git a/src/IntPatch/IntPatch_RstInt.cxx b/src/IntPatch/IntPatch_RstInt.cxx index 8a5ca2ce38..f6a7710658 100644 --- a/src/IntPatch/IntPatch_RstInt.cxx +++ b/src/IntPatch/IntPatch_RstInt.cxx @@ -445,7 +445,8 @@ void IntPatch_RstInt::PutVertexOnLine (Handle(IntPatch_Line)& L, const Handle(Adaptor3d_TopolTool)& Domain, const Handle(Adaptor3d_HSurface)& OtherSurf, const Standard_Boolean OnFirst, - const Standard_Real Tol ) + const Standard_Real Tol, + const Standard_Boolean hasBeenAdded) { // Domain est le domaine de restriction de la surface Surf. @@ -1229,7 +1230,7 @@ void IntPatch_RstInt::PutVertexOnLine (Handle(IntPatch_Line)& L, */ wlin->SetPeriod(pu1,pv1,pu2,pv2); - wlin->ComputeVertexParameters(Tol); + wlin->ComputeVertexParameters(Tol, hasBeenAdded); } else { #ifdef DEB diff --git a/src/IntPatch/IntPatch_WLine.cdl b/src/IntPatch/IntPatch_WLine.cdl index d22d273ea6..c3624cc755 100644 --- a/src/IntPatch/IntPatch_WLine.cdl +++ b/src/IntPatch/IntPatch_WLine.cdl @@ -236,7 +236,9 @@ is is static; - ComputeVertexParameters(me: mutable; Tol: Real from Standard) + ComputeVertexParameters(me: mutable; + Tol: Real from Standard; + hasBeenAdded: Boolean from Standard = Standard_False) ---Purpose: Set the parameters of all the vertex on the line. -- if a vertex is already in the line, diff --git a/src/IntPatch/IntPatch_WLine.cxx b/src/IntPatch/IntPatch_WLine.cxx index 14cdfbb120..635f86c719 100644 --- a/src/IntPatch/IntPatch_WLine.cxx +++ b/src/IntPatch/IntPatch_WLine.cxx @@ -238,8 +238,9 @@ inline Standard_Boolean CompareVerticesOnS2(const IntPatch_Point& vtx1, const In {return CompareVerticesOnSurf (vtx1, vtx2, Standard_False);} -void IntPatch_WLine::ComputeVertexParameters(const Standard_Real RTol) { - +void IntPatch_WLine::ComputeVertexParameters( const Standard_Real RTol, + const Standard_Boolean hasBeenAdded) +{ // MSV Oct 15, 2001: use tolerance of vertex instead of RTol where // it is possible @@ -463,9 +464,9 @@ void IntPatch_WLine::ComputeVertexParameters(const Standard_Real RTol) { Standard_Real dmini = Precision::Confusion(); dmini*=dmini; for(i=2; i<=nbponline; i++) { - //const IntSurf_PntOn2S& aPntOn2S1=curv->Value(i-1); - //const IntSurf_PntOn2S& aPntOn2S2=curv->Value(i); - Standard_Real d = (curv->Value(i-1).Value()).SquareDistance((curv->Value(i).Value())); + const IntSurf_PntOn2S& aPnt1=curv->Value(i-1); + const IntSurf_PntOn2S& aPnt2=curv->Value(i); + Standard_Real d = (aPnt1.Value()).SquareDistance((aPnt2.Value())); if(d < dmini) { curv->RemovePoint(i); nbponline--; @@ -473,10 +474,10 @@ void IntPatch_WLine::ComputeVertexParameters(const Standard_Real RTol) { //-- On recadre les Vertex si besoin //-- for(j=1; j<=nbvtx; j++) { - indicevertex = svtx.Value(j).ParameterOnLine(); - if(indicevertex >= i) { - svtx.ChangeValue(j).SetParameter(indicevertex-1.0); - } + indicevertex = svtx.Value(j).ParameterOnLine(); + if(indicevertex >= i) { + svtx.ChangeValue(j).SetParameter(indicevertex-1.0); + } } //modified by NIZNHY-PKV Mon Feb 11 09:28:02 2002 f i--; @@ -487,7 +488,30 @@ void IntPatch_WLine::ComputeVertexParameters(const Standard_Real RTol) { for(i=1; i<=nbvtx; i++) { const gp_Pnt& P = svtx.Value(i).Value(); Standard_Real vTol = svtx.Value(i).Tolerance(); - indicevertex = svtx.Value(i).ParameterOnLine(); + + if(hasBeenAdded) + { + if(nbvtx == 2) + { + if(i == nbvtx) + { + indicevertex = curv->NbPoints(); + } + else + { + indicevertex = svtx.Value(i).ParameterOnLine(); + } + } + else + { + indicevertex = svtx.Value(i).ParameterOnLine(); + } + } + else + { + indicevertex = svtx.Value(i).ParameterOnLine(); + } + indicevertexonline = (Standard_Integer)indicevertex; //-------------------------------------------------- //-- On Compare le vertex avec les points de la ligne diff --git a/src/IntWalk/IntWalk_PWalking.cdl b/src/IntWalk/IntWalk_PWalking.cdl index 5c49296c7d..61c59a09b8 100644 --- a/src/IntWalk/IntWalk_PWalking.cdl +++ b/src/IntWalk/IntWalk_PWalking.cdl @@ -265,6 +265,8 @@ theDirectionFlag: Boolean from Standard) theStep0U2V2: Real from Standard = 1.0e-6) returns Boolean from Standard is private; + -- Finds one intersection point of two given surfaces with given + -- initial point. DistanceMinimizeByExtrema(me : in out; theASurf1 : ThePSurface ; @@ -274,11 +276,36 @@ theDirectionFlag: Boolean from Standard) theStep0V: Real from Standard = 1.0) returns Boolean from Standard is private; + -- Finds one intersection point of two given surfaces with given + -- initial point. + SeekPointOnBoundary(me : in out; + theASurf1 , theASurf2 : ThePSurface ; + theU1, theV1, theU2, theV2: Real from Standard; + isTheFirst : Boolean from Standard) + returns Boolean from Standard + is private; + -- Unites and correctly coordinates of work of + -- "DistanceMinimizeByGradient" and "DistanceMinimizeByExtrema" functions. + + + PutToBoundary( me : in out; + theASurf1 , theASurf2 : ThePSurface) + -- Tries to extend existing intersection line + -- (as set of points) to surface's boundaries, + -- if it is possibly. + -- If line is scienter far from boundaries + -- or is (almost) parralel with some boundary, + -- extending is not required. + returns Boolean from Standard; + + SeekAdditionalPoints( me : in out; theASurf1 , theASurf2 : ThePSurface; theMinNbPoints : Integer from Standard) returns Boolean from Standard; + -- Unites and correctly coordinates of work of + -- "DistanceMinimizeByGradient" and "DistanceMinimizeByExtrema" functions. fields diff --git a/src/IntWalk/IntWalk_PWalking_1.gxx b/src/IntWalk/IntWalk_PWalking_1.gxx index 0955a2567a..85e62228f8 100644 --- a/src/IntWalk/IntWalk_PWalking_1.gxx +++ b/src/IntWalk/IntWalk_PWalking_1.gxx @@ -65,6 +65,167 @@ void ComputePasInit(Standard_Real *pasuv, pasuv[2]=Increment*du2; pasuv[3]=Increment*dv2; } + +//======================================================================= +//function : IsParallel +//purpose : Checks if theLine is parallel of some boundary of given +// surface (it is determined by theCheckSurf1 flag). +// Parallelism assumes small oscillations (swing is less or +// equal than theToler). +// Small lines (if first and last parameters in the Surface +// are almost equal) are classified as parallel (as same as +// any point can be considered as parallel of any line). +//======================================================================= +static void IsParallel(const Handle(IntSurf_LineOn2S)& theLine, + const Standard_Boolean theCheckSurf1, + const Standard_Real theToler, + Standard_Boolean& theIsUparallel, + Standard_Boolean& theIsVparallel) +{ + const Standard_Integer aNbPointsMAX = 23; + + theIsUparallel = theIsVparallel = Standard_True; + + Standard_Integer aNbPoints = theLine->NbPoints(); + if(aNbPoints > aNbPointsMAX) + { + aNbPoints = aNbPointsMAX; + } + else if(aNbPoints < 3) + { + //Here we cannot estimate parallelism. + //Do all same as for small lines + return; + } + + Standard_Real aStep = IntToReal(theLine->NbPoints()) / aNbPoints; + Standard_Real aNPoint = 1.0; + + Standard_Real aUmin = RealLast(), aUmax = RealFirst(), aVmin = RealLast(), aVmax = RealFirst(); + for(Standard_Integer aNum = 1; aNum <= aNbPoints; aNum++, aNPoint += aStep) + { + if(aNPoint > aNbPoints) + { + aNPoint = aNbPoints; + } + + Standard_Real u, v; + if(theCheckSurf1) + theLine->Value(RealToInt(aNPoint)).ParametersOnS1(u, v); + else + theLine->Value(RealToInt(aNPoint)).ParametersOnS2(u, v); + + if(u < aUmin) + aUmin = u; + + if(u > aUmax) + aUmax = u; + + if(v < aVmin) + aVmin = v; + + if(v > aVmax) + aVmax = v; + } + + theIsVparallel = ((aUmax - aUmin) < theToler); + theIsUparallel = ((aVmax - aVmin) < theToler); +} + +//======================================================================= +//function : Checking +//purpose : Check, if given point is in surface's boundaries. +// If "yes" then theFactTol = 0.0, else theFactTol is +// equal maximal deviation. +//======================================================================= +static Standard_Boolean Checking( const Handle(Adaptor3d_HSurface)& theASurf1, + const Handle(Adaptor3d_HSurface)& theASurf2, + Standard_Real& theU1, + Standard_Real& theV1, + Standard_Real& theU2, + Standard_Real& theV2, + Standard_Real& theFactTol) +{ + const Standard_Real aTol = Precision::PConfusion(); + const Standard_Real aU1bFirst = theASurf1->FirstUParameter(); + const Standard_Real aU1bLast = theASurf1->LastUParameter(); + const Standard_Real aU2bFirst = theASurf2->FirstUParameter(); + const Standard_Real aU2bLast = theASurf2->LastUParameter(); + const Standard_Real aV1bFirst = theASurf1->FirstVParameter(); + const Standard_Real aV1bLast = theASurf1->LastVParameter(); + const Standard_Real aV2bFirst = theASurf2->FirstVParameter(); + const Standard_Real aV2bLast = theASurf2->LastVParameter(); + + Standard_Boolean isOnOrIn = Standard_True; + theFactTol = 0.0; + + Standard_Real aDelta = aU1bFirst - theU1; + if(aDelta > aTol) + { + theU1 = aU1bFirst; + theFactTol = Max(theFactTol, aDelta); + isOnOrIn = Standard_False; + } + + aDelta = theU1 - aU1bLast; + if(aDelta > aTol) + { + theU1 = aU1bLast; + theFactTol = Max(theFactTol, aDelta); + isOnOrIn = Standard_False; + } + + aDelta = aV1bFirst - theV1; + if(aDelta > aTol) + { + theV1 = aV1bFirst; + theFactTol = Max(theFactTol, aDelta); + isOnOrIn = Standard_False; + } + + aDelta = theV1 - aV1bLast; + if(aDelta > aTol) + { + theV1 = aV1bLast; + theFactTol = Max(theFactTol, aDelta); + isOnOrIn = Standard_False; + } + + aDelta = aU2bFirst - theU2; + if(aDelta > aTol) + { + theU2 = aU2bFirst; + theFactTol = Max(theFactTol, aDelta); + isOnOrIn = Standard_False; + } + + aDelta = theU2 - aU2bLast; + if(aDelta > aTol) + { + theU2 = aU2bLast; + theFactTol = Max(theFactTol, aDelta); + isOnOrIn = Standard_False; + } + + aDelta = aV2bFirst - theV2; + if(aDelta > aTol) + { + theV2 = aV2bFirst; + theFactTol = Max(theFactTol, aDelta); + isOnOrIn = Standard_False; + } + + aDelta = theV2 - aV2bLast; + if(aDelta > aTol) + { + theV2 = aV2bLast; + theFactTol = Max(theFactTol, aDelta); + isOnOrIn = Standard_False; + } + + return isOnOrIn; +} + //================================================================================== // function : IntWalk_PWalking::IntWalk_PWalking // purpose : @@ -1636,14 +1797,19 @@ Standard_Boolean IntWalk_PWalking::ExtendLineInCommonZone(const IntImp_ConstIsop return bOutOfTangentZone; } -Standard_Boolean IntWalk_PWalking::DistanceMinimizeByGradient(const Handle(Adaptor3d_HSurface)& theASurf1, - const Handle(Adaptor3d_HSurface)& theASurf2, - Standard_Real& theU1, - Standard_Real& theV1, - Standard_Real& theU2, - Standard_Real& theV2, - const Standard_Real theStep0U1V1, - const Standard_Real theStep0U2V2) +//======================================================================= +//function : DistanceMinimizeByGradient +//purpose : +//======================================================================= +Standard_Boolean IntWalk_PWalking:: + DistanceMinimizeByGradient( const Handle(Adaptor3d_HSurface)& theASurf1, + const Handle(Adaptor3d_HSurface)& theASurf2, + Standard_Real& theU1, + Standard_Real& theV1, + Standard_Real& theU2, + Standard_Real& theV2, + const Standard_Real theStep0U1V1, + const Standard_Real theStep0U2V2) { const Standard_Integer aNbIterMAX = 60; const Standard_Real aTol = 1.0e-14; @@ -1698,13 +1864,21 @@ Standard_Boolean IntWalk_PWalking::DistanceMinimizeByGradient(const Handle(Adapt while(flRepeat) { Standard_Real anAdd = aGradFu*aSTEPuv; - Standard_Real aPARu = (anAdd >= 0.0)? (theU1 - Max(anAdd, Epsilon(theU1))) : (theU1 + Max(-anAdd, Epsilon(theU1))); + Standard_Real aPARu = (anAdd >= 0.0)? + (theU1 - Max(anAdd, Epsilon(theU1))) : + (theU1 + Max(-anAdd, Epsilon(theU1))); anAdd = aGradFv*aSTEPuv; - Standard_Real aPARv = (anAdd >= 0.0)? (theV1 - Max(anAdd, Epsilon(theV1))) : (theV1 + Max(-anAdd, Epsilon(theV1))); + Standard_Real aPARv = (anAdd >= 0.0)? + (theV1 - Max(anAdd, Epsilon(theV1))) : + (theV1 + Max(-anAdd, Epsilon(theV1))); anAdd = aGradFU*aStepUV; - Standard_Real aParU = (anAdd >= 0.0)? (theU2 - Max(anAdd, Epsilon(theU2))) : (theU2 + Max(-anAdd, Epsilon(theU2))); + Standard_Real aParU = (anAdd >= 0.0)? + (theU2 - Max(anAdd, Epsilon(theU2))) : + (theU2 + Max(-anAdd, Epsilon(theU2))); anAdd = aGradFV*aStepUV; - Standard_Real aParV = (anAdd >= 0.0)? (theV2 - Max(anAdd, Epsilon(theV2))) : (theV2 + Max(-anAdd, Epsilon(theV2))); + Standard_Real aParV = (anAdd >= 0.0)? + (theV2 - Max(anAdd, Epsilon(theV2))) : + (theV2 + Max(-anAdd, Epsilon(theV2))); gp_Pnt aPt1, aPt2; @@ -1750,12 +1924,17 @@ Standard_Boolean IntWalk_PWalking::DistanceMinimizeByGradient(const Handle(Adapt return aStatus; } -Standard_Boolean IntWalk_PWalking::DistanceMinimizeByExtrema( const Handle(Adaptor3d_HSurface)& theASurf, - const gp_Pnt& theP0, - Standard_Real& theU0, - Standard_Real& theV0, - const Standard_Real theStep0U, - const Standard_Real theStep0V) +//======================================================================= +//function : DistanceMinimizeByExtrema +//purpose : +//======================================================================= +Standard_Boolean IntWalk_PWalking:: + DistanceMinimizeByExtrema(const Handle(Adaptor3d_HSurface)& theASurf, + const gp_Pnt& theP0, + Standard_Real& theU0, + Standard_Real& theV0, + const Standard_Real theStep0U, + const Standard_Real theStep0V) { const Standard_Real aTol = 1.0e-14; gp_Pnt aPS; @@ -1801,9 +1980,318 @@ Standard_Boolean IntWalk_PWalking::DistanceMinimizeByExtrema( const Handle(Adapt return (aSQDistPrev < aTol); } -Standard_Boolean IntWalk_PWalking::SeekAdditionalPoints(const Handle(Adaptor3d_HSurface)& theASurf1, - const Handle(Adaptor3d_HSurface)& theASurf2, - const Standard_Integer theMinNbPoints) +//======================================================================= +//function : SeekPointOnBoundary +//purpose : +//======================================================================= +Standard_Boolean IntWalk_PWalking:: + SeekPointOnBoundary(const Handle(Adaptor3d_HSurface)& theASurf1, + const Handle(Adaptor3d_HSurface)& theASurf2, + const Standard_Real theU1, + const Standard_Real theV1, + const Standard_Real theU2, + const Standard_Real theV2, + const Standard_Boolean isTheFirst) +{ + const Standard_Real aTol = 1.0e-14; + Standard_Boolean isOK = Standard_False; + Standard_Real U1prec = theU1, V1prec = theV1, U2prec = theU2, V2prec = theV2; + + Standard_Boolean flFinish = Standard_False; + + Standard_Integer aNbIter = 20; + while(!flFinish) + { + flFinish = Standard_False; + Standard_Boolean aStatus = Standard_False; + + do + { + aNbIter--; + aStatus = DistanceMinimizeByGradient(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec); + if(aStatus) + { + break; + } + + aStatus = DistanceMinimizeByExtrema(theASurf1, theASurf2->Value(U2prec, V2prec), U1prec, V1prec); + if(aStatus) + { + break; + } + + aStatus = DistanceMinimizeByExtrema(theASurf2, theASurf1->Value(U1prec, V1prec), U2prec, V2prec); + if(aStatus) + { + break; + } + } + while(!aStatus && (aNbIter > 0)); + + if(aStatus) + { + const Standard_Real aTolMax = 1.0e-8; + Standard_Real aTolF = 0.0; + + Standard_Real u1 = U1prec, v1 = V1prec, u2 = U2prec, v2 = V2prec; + + flFinish = Checking(theASurf1, theASurf2, U1prec, V1prec, U2prec, V2prec, aTolF); + + if(aTolF <= aTolMax) + { + gp_Pnt aP1 = theASurf1->Value(u1, v1), + aP2 = theASurf2->Value(u2, v2); + gp_Pnt aPInt(0.5*(aP1.XYZ() + aP2.XYZ())); + + const Standard_Real aSQDist1 = aPInt.SquareDistance(aP1), + aSQDist2 = aPInt.SquareDistance(aP2); + if((aSQDist1 < aTol) && (aSQDist2 < aTol)) + { + IntSurf_PntOn2S anIP; + anIP.SetValue(aPInt, u1, v1, u2, v2); + + if(isTheFirst) + line->InsertBefore(1,anIP); + else + line->Add(anIP); + + isOK = Standard_True; + } + } + } + else + { + break; + } + + if(aNbIter < 0) + break; + } + + return isOK; +} + +//======================================================================= +//function : PutToBoundary +//purpose : +//======================================================================= +Standard_Boolean IntWalk_PWalking:: + PutToBoundary(const Handle(Adaptor3d_HSurface)& theASurf1, + const Handle(Adaptor3d_HSurface)& theASurf2) +{ + const Standard_Real aTolMin = Precision::Confusion(); + + Standard_Boolean hasBeenAdded = Standard_False; + + const Standard_Real aU1bFirst = theASurf1->FirstUParameter(); + const Standard_Real aU1bLast = theASurf1->LastUParameter(); + const Standard_Real aU2bFirst = theASurf2->FirstUParameter(); + const Standard_Real aU2bLast = theASurf2->LastUParameter(); + const Standard_Real aV1bFirst = theASurf1->FirstVParameter(); + const Standard_Real aV1bLast = theASurf1->LastVParameter(); + const Standard_Real aV2bFirst = theASurf2->FirstVParameter(); + const Standard_Real aV2bLast = theASurf2->LastVParameter(); + + Standard_Real aTol = 1.0; + aTol = Min(aTol, aU1bLast - aU1bFirst); + aTol = Min(aTol, aU2bLast - aU2bFirst); + aTol = Min(aTol, aV1bLast - aV1bFirst); + aTol = Min(aTol, aV2bLast - aV2bFirst)*1.0e-3; + + if(aTol <= 2.0*aTolMin) + return hasBeenAdded; + + Standard_Boolean isNeedAdding = Standard_False; + Standard_Boolean isU1parallel = Standard_False, isV1parallel = Standard_False; + Standard_Boolean isU2parallel = Standard_False, isV2parallel = Standard_False; + IsParallel(line, Standard_True, aTol, isU1parallel, isV1parallel); + IsParallel(line, Standard_False, aTol, isU2parallel, isV2parallel); + + const Standard_Integer aNbPnts = line->NbPoints(); + Standard_Real u1, v1, u2, v2; + line->Value(1).Parameters(u1, v1, u2, v2); + Standard_Real aDelta = 0.0; + + if(!isV1parallel) + { + aDelta = u1 - aU1bFirst; + if((aTolMin < aDelta) && (aDelta < aTol)) + { + u1 = aU1bFirst - aDelta; + isNeedAdding = Standard_True; + } + else + { + aDelta = aU1bLast - u1; + if((aTolMin < aDelta) && (aDelta < aTol)) + { + u1 = aU1bLast + aDelta; + isNeedAdding = Standard_True; + } + } + } + + if(!isV2parallel) + { + aDelta = u2 - aU2bFirst; + if((aTolMin < aDelta) && (aDelta < aTol)) + { + u2 = aU2bFirst - aDelta; + isNeedAdding = Standard_True; + } + else + { + aDelta = aU2bLast - u2; + if((aTolMin < aDelta) && (aDelta < aTol)) + { + u2 = aU2bLast + aDelta; + isNeedAdding = Standard_True; + } + } + } + + if(!isU1parallel) + { + aDelta = v1 - aV1bFirst; + if((aTolMin < aDelta) && (aDelta < aTol)) + { + v1 = aV1bFirst - aDelta; + isNeedAdding = Standard_True; + } + else + { + aDelta = aV1bLast - v1; + if((aTolMin < aDelta) && (aDelta < aTol)) + { + v1 = aV1bLast + aDelta; + isNeedAdding = Standard_True; + } + } + } + + if(!isU2parallel) + { + aDelta = v2 - aV2bFirst; + if((aTolMin < aDelta) && (aDelta < aTol)) + { + v2 = aV2bFirst - aDelta; + isNeedAdding = Standard_True; + } + else + { + aDelta = aV2bLast - v2; + if((aTolMin < aDelta) && (aDelta < aTol)) + { + v2 = aV2bLast + aDelta; + isNeedAdding = Standard_True; + } + } + } + + if(isNeedAdding) + { + hasBeenAdded = + SeekPointOnBoundary(theASurf1, theASurf2, u1, + v1, u2, v2, Standard_True); + } + + isNeedAdding = Standard_False; + line->Value(aNbPnts).Parameters(u1, v1, u2, v2); + + if(!isV1parallel) + { + aDelta = u1 - aU1bFirst; + if((aTolMin < aDelta) && (aDelta < aTol)) + { + u1 = aU1bFirst - aDelta; + isNeedAdding = Standard_True; + } + else + { + aDelta = aU1bLast - u1; + if((aTolMin < aDelta) && (aDelta < aTol)) + { + u1 = aU1bLast + aDelta; + isNeedAdding = Standard_True; + } + } + } + + if(!isV2parallel) + { + aDelta = u2 - aU2bFirst; + if((aTolMin < aDelta) && (aDelta < aTol)) + { + u2 = aU2bFirst - aDelta; + isNeedAdding = Standard_True; + } + else + { + aDelta = aU2bLast - u2; + if((aTolMin < aDelta) && (aDelta < aTol)) + { + u2 = aU2bLast + aDelta; + isNeedAdding = Standard_True; + } + } + } + + if(!isU1parallel) + { + aDelta = v1 - aV1bFirst; + if((aTolMin < aDelta) && (aDelta < aTol)) + { + v1 = aV1bFirst - aDelta; + isNeedAdding = Standard_True; + } + else + { + aDelta = aV1bLast - v1; + if((aTolMin < aDelta) && (aDelta < aTol)) + { + v1 = aV1bLast + aDelta; + isNeedAdding = Standard_True; + } + } + } + + if(!isU2parallel) + { + aDelta = v2 - aV2bFirst; + if((aTolMin < aDelta) && (aDelta < aTol)) + { + v2 = aV2bFirst - aDelta; + isNeedAdding = Standard_True; + } + else + { + aDelta = aV2bLast - v2; + if((aTolMin < aDelta) && (aDelta < aTol)) + { + v2 = aV2bLast + aDelta; + isNeedAdding = Standard_True; + } + } + } + + if(isNeedAdding) + { + hasBeenAdded = + SeekPointOnBoundary(theASurf1, theASurf2, u1, + v1, u2, v2, Standard_False); + } + + return hasBeenAdded; +} + +//======================================================================= +//function : SeekAdditionalPoints +//purpose : +//======================================================================= +Standard_Boolean IntWalk_PWalking:: + SeekAdditionalPoints( const Handle(Adaptor3d_HSurface)& theASurf1, + const Handle(Adaptor3d_HSurface)& theASurf2, + const Standard_Integer theMinNbPoints) { const Standard_Real aTol = 1.0e-14; Standard_Integer aNbPoints = line->NbPoints(); @@ -1915,3 +2403,5 @@ Standard_Boolean IntWalk_PWalking::SeekAdditionalPoints(const Handle(Adaptor3d_H return isPrecise; } + + diff --git a/tests/bugs/modalg_5/bug24472 b/tests/bugs/modalg_5/bug24472 index f1de831b59..255e723a7e 100755 --- a/tests/bugs/modalg_5/bug24472 +++ b/tests/bugs/modalg_5/bug24472 @@ -23,8 +23,6 @@ proc checkList {List Tolerance D_good} { } } } -smallview - restore [locate_data_file bug24472_Pipe_1.brep] b1 explode b1 f diff --git a/tests/bugs/modalg_5/bug24585_1 b/tests/bugs/modalg_5/bug24585_1 new file mode 100644 index 0000000000..462b19679c --- /dev/null +++ b/tests/bugs/modalg_5/bug24585_1 @@ -0,0 +1,77 @@ +puts "=========" +puts "OCC24585" +puts "=========" +puts "" +########################################################### +# Wrong pcurve of the section curve +########################################################### +set MaxTol 1.0e-7 +set NbCurv_OK 1 + +restore [locate_data_file bug24585_b1.brep] b1 +restore [locate_data_file bug24585_b2.brep] b2 + +mksurface s1 b1 +bounds s1 U1f_exp U1l_exp V1f_exp V1l_exp + +set log [bopcurves b1 b2 -2d] + +regexp {Tolerance Reached=+([-0-9.+eE]+)\n+([-0-9.+eE]+)} ${log} full Toler NbCurv + +if {${NbCurv} != ${NbCurv_OK}} { + puts "Error: ${NbCurv_OK} curve(s) expected, but ${NbCurv} found." +} + +if {${Toler} > ${MaxTol}} { + puts "Error: Tolerance is too big!" +} + +#Theoretically, c2d1_1 must cover U-diapason of surface s1 fully. + +set log [dump c2d1_1] + +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 Pole 1 +set exp_string " +${Pole} : +(\[-0-9.+eE\]+), +(\[-0-9.+eE\]+)" +regexp ${exp_string} ${log} full U_begin V_begin + +puts "Pole=${Pole}" +puts "U_begin=${U_begin}" +puts "V_begin=${V_begin}" +dset U_begin ${U_begin} +puts "" + +set Pole ${Poles} +set exp_string " +${Pole} : +(\[-0-9.+eE\]+), +(\[-0-9.+eE\]+)" +regexp ${exp_string} ${log} full U_end V_end + +puts "Pole=${Pole}" +puts "U_end=${U_end}" +puts "V_end=${V_end}" +dset U_end ${U_end} +puts "" + +set delta_f [dval U1f_exp-U_begin] + +#ATTENTION!!! U_begin must be strictly equal U1f_exp (without any tolerance) +if {${delta_f} != 0} { + puts "Error: Bad value. U_begin = [dval U_begin], Ufirst = [dval U1f_exp]." +} else { + puts "OK: Good value. U_begin matches with Ufirst of surface." +} + +puts "" + +set delta_l [dval U1l_exp-U_end] + +#ATTENTION!!! U_end must be strictly equal U1l_exp (without any tolerance) +if {${delta_l} != 0} { + puts "Error: Bad value. U_end = [dval U_end], Ulast = [dval U1l_exp]." +} else { + puts "OK: Good value. U_end matches with Ulast of surface." +} \ No newline at end of file diff --git a/tests/bugs/modalg_5/bug24585_2 b/tests/bugs/modalg_5/bug24585_2 new file mode 100644 index 0000000000..2c2492adea --- /dev/null +++ b/tests/bugs/modalg_5/bug24585_2 @@ -0,0 +1,31 @@ +puts "=========" +puts "OCC24585" +puts "=========" +puts "" +########################################################### +# Wrong pcurve of the section curve +########################################################### + +restore [locate_data_file bug24585_b1.brep] b1 +restore [locate_data_file bug24585_b2.brep] b2 + +bclearobjects +bcleartools +baddobjects b1 b2 + +bfillds +bbuild result + +set square 933.33 + +set nb_v_good 10 +set nb_e_good 11 +set nb_w_good 4 +set nb_f_good 3 +set nb_sh_good 0 +set nb_sol_good 0 +set nb_compsol_good 0 +set nb_compound_good 1 +set nb_shape_good 29 + +set 2dviewer 1