diff --git a/src/BRepCheck/BRepCheck_Edge.cxx b/src/BRepCheck/BRepCheck_Edge.cxx index e0261a065f..b65d247453 100644 --- a/src/BRepCheck/BRepCheck_Edge.cxx +++ b/src/BRepCheck/BRepCheck_Edge.cxx @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -171,6 +172,7 @@ void BRepCheck_Edge::Minimum() if (!myCref.IsNull()) { Handle(BRep_GCurve) GCref (Handle(BRep_GCurve)::DownCast (myCref)); + Standard_Real eps = Precision::PConfusion(); Standard_Real First,Last; GCref->Range(First,Last); if (Last<=First) { @@ -186,20 +188,82 @@ void BRepCheck_Edge::Minimum() Handle(Geom_Curve) C3d = Handle(Geom_Curve)::DownCast (myCref->Curve3D()->Transformed (/*myCref->Location()*/L.Transformation())); - GeomAdaptor_Curve GAC3d(C3d, C3d->TransformedParameter(First, L.Transformation()), + Standard_Boolean IsPeriodic = C3d->IsPeriodic(); + Standard_Real aPeriod = RealLast(); + if(IsPeriodic) + { + aPeriod = C3d->Period(); + } + Standard_Real f = C3d->FirstParameter(), l = C3d->LastParameter(); + if (C3d->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) + { + const Handle(Geom_Curve)& aC = Handle(Geom_TrimmedCurve)::DownCast (C3d)->BasisCurve(); + f = aC->FirstParameter(); + l = aC->LastParameter(); + IsPeriodic = aC->IsPeriodic(); + if(IsPeriodic) + { + aPeriod = aC->Period(); + } + } + if(IsPeriodic && (Last - First > aPeriod + eps)) + { + myCref.Nullify(); + BRepCheck::Add(lst,BRepCheck_InvalidRange); + } + else if(!IsPeriodic && (First < f - eps || Last > l + eps)) + { + myCref.Nullify(); + BRepCheck::Add(lst,BRepCheck_InvalidRange); + } + else + { + GeomAdaptor_Curve GAC3d(C3d, C3d->TransformedParameter(First, L.Transformation()), C3d->TransformedParameter(Last, L.Transformation())); - myHCurve = new GeomAdaptor_HCurve(GAC3d); + myHCurve = new GeomAdaptor_HCurve(GAC3d); + } } else { // curve on surface Handle(Geom_Surface) Sref = myCref->Surface(); Sref = Handle(Geom_Surface)::DownCast (Sref->Transformed(myCref->Location().Transformation())); const Handle(Geom2d_Curve)& PCref = myCref->PCurve(); - Handle(GeomAdaptor_HSurface) GAHSref = new GeomAdaptor_HSurface(Sref); - Handle(Geom2dAdaptor_HCurve) GHPCref = - new Geom2dAdaptor_HCurve(PCref,First,Last); - Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref); - myHCurve = new Adaptor3d_HCurveOnSurface(ACSref); + Standard_Boolean IsPeriodic = PCref->IsPeriodic(); + Standard_Real aPeriod = RealLast(); + if(IsPeriodic) + { + aPeriod = PCref->Period(); + } + Standard_Real f = PCref->FirstParameter(), l = PCref->LastParameter(); + if (PCref->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) + { + const Handle(Geom2d_Curve)& aC = Handle(Geom2d_TrimmedCurve)::DownCast (PCref)->BasisCurve(); + f = aC->FirstParameter(); + l = aC->LastParameter(); + IsPeriodic = aC->IsPeriodic(); + if(IsPeriodic) + { + aPeriod = aC->Period(); + } + } + if(IsPeriodic && (Last - First > aPeriod + eps)) + { + myCref.Nullify(); + BRepCheck::Add(lst,BRepCheck_InvalidRange); + } + else if(!IsPeriodic && (First < f - eps || Last > l + eps)) + { + myCref.Nullify(); + BRepCheck::Add(lst,BRepCheck_InvalidRange); + } + else + { + Handle(GeomAdaptor_HSurface) GAHSref = new GeomAdaptor_HSurface(Sref); + Handle(Geom2dAdaptor_HCurve) GHPCref = + new Geom2dAdaptor_HCurve(PCref,First,Last); + Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref); + myHCurve = new Adaptor3d_HCurveOnSurface(ACSref); + } } } } @@ -276,6 +340,7 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S) Standard_Boolean pcurvefound = Standard_False; BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves()); + Standard_Real eps = Precision::PConfusion(); while (itcr.More()) { const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); if (cr != myCref && cr->IsCurveOnSurface(Su,L)) { @@ -291,12 +356,43 @@ void BRepCheck_Edge::InContext(const TopoDS_Shape& S) } // gka OCC // Modified by skv - Tue Apr 27 11:50:35 2004 Begin - if (Abs(ff-First) > Precision::PConfusion() || - Abs(ll-Last) > Precision::PConfusion()) { + if (Abs(ff-First) > eps || + Abs(ll-Last) > eps) { BRepCheck::Add(lst,BRepCheck_InvalidSameRangeFlag); BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag); } // Modified by skv - Tue Apr 27 11:50:37 2004 End + // + const Handle(Geom2d_Curve)& pc = cr->PCurve(); + Standard_Boolean IsPeriodic = pc->IsPeriodic(); + Standard_Real aPeriod = RealLast(); + if(IsPeriodic) + { + aPeriod = pc->Period(); + } + Standard_Real fp = pc->FirstParameter(), lp = pc->LastParameter(); + if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) + { + const Handle(Geom2d_Curve)& aC = Handle(Geom2d_TrimmedCurve)::DownCast (pc)->BasisCurve(); + fp = aC->FirstParameter(); + lp = aC->LastParameter(); + IsPeriodic = aC->IsPeriodic(); + if(IsPeriodic) + { + aPeriod = aC->Period(); + } + } + if(IsPeriodic && (l - f > aPeriod + eps)) + { + BRepCheck::Add(lst,BRepCheck_InvalidRange); + return; + } + else if(!IsPeriodic && (f < fp - eps || l > lp + eps)) + { + BRepCheck::Add(lst,BRepCheck_InvalidRange); + return; + } + if (myGctrl) { Handle(Geom_Surface) Sb = cr->Surface(); Sb = Handle(Geom_Surface)::DownCast diff --git a/src/BRepTest/BRepTest_BasicCommands.cxx b/src/BRepTest/BRepTest_BasicCommands.cxx index 19e93bb34a..87417ef84b 100644 --- a/src/BRepTest/BRepTest_BasicCommands.cxx +++ b/src/BRepTest/BRepTest_BasicCommands.cxx @@ -115,6 +115,13 @@ static Standard_Integer transform(Draw_Interpretor& ,Standard_Integer n,const ch const char* aName = a[0]; Standard_Boolean isBasic = Standard_False; + Standard_Boolean isCopy = Standard_False; + + // Check "copy" flag. + if (!strcmp(a[n-1], "-copy")) { + isCopy = Standard_True; + last = --n; + } if (!strcmp(aName,"reset")) { } @@ -176,7 +183,7 @@ static Standard_Integer transform(Draw_Interpretor& ,Standard_Integer n,const ch return 1; } else { - trf.Perform(S); + trf.Perform(S, isCopy); if (!trf.IsDone()) return 1; DBRep::Set(a[i],trf.Shape()); @@ -1418,27 +1425,27 @@ void BRepTest::BasicCommands(Draw_Interpretor& theCommands) transform,g); theCommands.Add("tmove", - "tmove name1 name2 ... name, set location from name", + "tmove name1 name2 ... name, set location from name [-copy]", __FILE__, transform,g); theCommands.Add("ttranslate", - "ttranslate name1 name2 ... dx dy dz", + "ttranslate name1 name2 ... dx dy dz [-copy]", __FILE__, transform,g); theCommands.Add("trotate", - "trotate name1 name2 ... x y z dx dy dz angle", + "trotate name1 name2 ... x y z dx dy dz angle [-copy]", __FILE__, transform,g); theCommands.Add("tmirror", - "tmirror name x y z dx dy dz", + "tmirror name x y z dx dy dz [-copy]", __FILE__, transform,g); theCommands.Add("tscale", - "tscale name x y z scale", + "tscale name x y z scale [-copy]", __FILE__, transform,g); diff --git a/src/BRepTest/BRepTest_SurfaceCommands.cxx b/src/BRepTest/BRepTest_SurfaceCommands.cxx index 2cfd440451..454e3c0c0d 100644 --- a/src/BRepTest/BRepTest_SurfaceCommands.cxx +++ b/src/BRepTest/BRepTest_SurfaceCommands.cxx @@ -261,7 +261,24 @@ static Standard_Integer pcurve(Draw_Interpretor& , Standard_Integer n, const cha DrawTrSurf_CurveColor(col); Sprintf(name,"%s_%d",a[1],i); - DrawTrSurf::Set(name,new Geom2d_TrimmedCurve(c,f,l)); + Standard_Real fr = c->FirstParameter(), lr = c->LastParameter(); + Standard_Boolean IsPeriodic = c->IsPeriodic(); + if (c->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) + { + const Handle(Geom2d_Curve)& aC = Handle(Geom2d_TrimmedCurve)::DownCast (c)->BasisCurve(); + IsPeriodic = aC->IsPeriodic(); + fr = aC->FirstParameter(); + lr = aC->LastParameter(); + } + if(!IsPeriodic && + ((fr - f > Precision::PConfusion()) || (l - lr > Precision::PConfusion()))) + { + DrawTrSurf::Set(name, c); + } + else + { + DrawTrSurf::Set(name,new Geom2d_TrimmedCurve(c,f,l)); + } } DrawTrSurf_CurveColor(savecol); @@ -276,10 +293,27 @@ static Standard_Integer pcurve(Draw_Interpretor& , Standard_Integer n, const cha Standard_Real f,l; const Handle(Geom2d_Curve) c = BRep_Tool::CurveOnSurface (TopoDS::Edge(SE),TopoDS::Face(SF),f,l); + Standard_Real fr = c->FirstParameter(), lr = c->LastParameter(); + Standard_Boolean IsPeriodic = c->IsPeriodic(); + if (c->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) + { + const Handle(Geom2d_Curve)& aC = Handle(Geom2d_TrimmedCurve)::DownCast (c)->BasisCurve(); + IsPeriodic = aC->IsPeriodic(); + fr = aC->FirstParameter(); + lr = aC->LastParameter(); + } col = DBRep_ColorOrientation(SE.Orientation()); DrawTrSurf_CurveColor(col); - DrawTrSurf::Set(a[1],new Geom2d_TrimmedCurve(c,f,l)); + if(!IsPeriodic && + ((fr - f > Precision::PConfusion()) || (l - lr > Precision::PConfusion()))) + { + DrawTrSurf::Set(a[1], c); + } + else + { + DrawTrSurf::Set(a[1],new Geom2d_TrimmedCurve(c,f,l)); + } DrawTrSurf_CurveColor(savecol); } else { diff --git a/src/BRepTools/BRepTools_TrsfModification.cxx b/src/BRepTools/BRepTools_TrsfModification.cxx index 698aa71c75..6bc92499cd 100644 --- a/src/BRepTools/BRepTools_TrsfModification.cxx +++ b/src/BRepTools/BRepTools_TrsfModification.cxx @@ -180,6 +180,17 @@ Standard_Boolean BRepTools_TrsfModification::NewCurve2d if(!NewC->IsPeriodic()) { if(fc - f > Precision::PConfusion()) f = fc; if(l - lc > Precision::PConfusion()) l = lc; + if(Abs(l - f) < Precision::PConfusion()) + { + if(Abs(f - fc) < Precision::PConfusion()) + { + l = lc; + } + else + { + f = fc; + } + } } newf = f; diff --git a/src/GeomLib/GeomLib.cxx b/src/GeomLib/GeomLib.cxx index da9ae9a9b4..4d004faca3 100644 --- a/src/GeomLib/GeomLib.cxx +++ b/src/GeomLib/GeomLib.cxx @@ -971,14 +971,27 @@ void GeomLib::SameRange(const Standard_Real Tolerance, if(aCCheck->IsPeriodic()) { - TC = new Geom2d_TrimmedCurve( CurvePtr, FirstOnCurve, LastOnCurve ); + if(Abs(LastOnCurve - FirstOnCurve) > Precision::PConfusion()) + { + TC = new Geom2d_TrimmedCurve( CurvePtr, FirstOnCurve, LastOnCurve ); + } + else + { + TC = new Geom2d_TrimmedCurve( CurvePtr, CurvePtr->FirstParameter(), CurvePtr->LastParameter() ); + } } else { const Standard_Real Udeb = Max(CurvePtr->FirstParameter(), FirstOnCurve); const Standard_Real Ufin = Min(CurvePtr->LastParameter(), LastOnCurve); - - TC = new Geom2d_TrimmedCurve( CurvePtr, Udeb, Ufin ); + if(Abs(Ufin - Udeb) > Precision::PConfusion()) + { + TC = new Geom2d_TrimmedCurve( CurvePtr, Udeb, Ufin ); + } + else + { + TC = new Geom2d_TrimmedCurve( CurvePtr, CurvePtr->FirstParameter(), CurvePtr->LastParameter()); + } } // diff --git a/src/ShapeAnalysis/ShapeAnalysis_Edge.cxx b/src/ShapeAnalysis/ShapeAnalysis_Edge.cxx index 333a3c80f5..f1bc7821c4 100644 --- a/src/ShapeAnalysis/ShapeAnalysis_Edge.cxx +++ b/src/ShapeAnalysis/ShapeAnalysis_Edge.cxx @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -1028,3 +1029,44 @@ Standard_Boolean ShapeAnalysis_Edge::CheckOverlapping(const TopoDS_Edge& theEdge theTolOverlap = aresTol; return isOverlap; } + +//======================================================================= +//function : CheckPCurveRange +//purpose : +//======================================================================= + +Standard_Boolean ShapeAnalysis_Edge::CheckPCurveRange (const Standard_Real theFirst, + const Standard_Real theLast, + const Handle(Geom2d_Curve)& thePC) +{ + const Standard_Real eps = Precision::PConfusion(); + Standard_Boolean isValid = Standard_True; + Standard_Boolean IsPeriodic = thePC->IsPeriodic(); + Standard_Real aPeriod = RealLast(); + if(IsPeriodic) + { + aPeriod = thePC->Period(); + } + Standard_Real fp = thePC->FirstParameter(), lp = thePC->LastParameter(); + if (thePC->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve)) + { + const Handle(Geom2d_Curve)& aC = Handle(Geom2d_TrimmedCurve)::DownCast (thePC)->BasisCurve(); + fp = aC->FirstParameter(); + lp = aC->LastParameter(); + IsPeriodic = aC->IsPeriodic(); + if(IsPeriodic) + { + aPeriod = aC->Period(); + } + } + if(IsPeriodic && (theLast - theFirst > aPeriod + eps)) + { + isValid = Standard_False; + } + else if(!IsPeriodic && (theFirst < fp - eps || theLast > lp + eps)) + { + isValid = Standard_False; + } + + return isValid; +} diff --git a/src/ShapeAnalysis/ShapeAnalysis_Edge.hxx b/src/ShapeAnalysis/ShapeAnalysis_Edge.hxx index e7e42f46f1..d39aca0aa2 100644 --- a/src/ShapeAnalysis/ShapeAnalysis_Edge.hxx +++ b/src/ShapeAnalysis/ShapeAnalysis_Edge.hxx @@ -170,7 +170,12 @@ public: //! If deviation is greater than tolerance of the edge (i.e. //! incorrect flag) returns False, else returns True. Standard_EXPORT Standard_Boolean CheckSameParameter (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace, Standard_Real& theMaxdev, const Standard_Integer theNbControl = 23); - + + //! Checks possibility for pcurve thePC to have range [theFirst, theLast] (edge range) + //! having respect to real first, last parameters of thePC + Standard_EXPORT Standard_Boolean CheckPCurveRange (const Standard_Real theFirst, const Standard_Real theLast, + const Handle(Geom2d_Curve)& thePC); + //! Computes the maximal deviation between the two curve //! representations. //! dev is an input/output parameter and contains the computed diff --git a/src/ShapeFix/ShapeFix_Wire.cxx b/src/ShapeFix/ShapeFix_Wire.cxx index 59334cb7fb..e5b273da3e 100644 --- a/src/ShapeFix/ShapeFix_Wire.cxx +++ b/src/ShapeFix/ShapeFix_Wire.cxx @@ -794,12 +794,26 @@ Standard_Boolean ShapeFix_Wire::FixEdgeCurves() if(sae.HasPCurve(sbwd->Edge(i),face)) { Handle(Geom2d_Curve) C2d; Standard_Real fp2d,lp2d; - if(sae.PCurve(sbwd->Edge(i),face,C2d,fp2d,lp2d)) { + if(sae.PCurve(sbwd->Edge(i),face,C2d,fp2d,lp2d, Standard_False)) { if( fabs(First-fp2d)>Precision::PConfusion() || - fabs(Last-lp2d)>Precision::PConfusion() ) { + fabs(Last-lp2d)>Precision::PConfusion() ) + { BRep_Builder B; B.SameRange(sbwd->Edge(i),Standard_False); } + else if(!sae.CheckPCurveRange(First, Last, C2d)) + { + //Replace pcurve + TopLoc_Location L; + const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L); + ShapeBuild_Edge().RemovePCurve (sbwd->Edge(i), S, L); + myFixEdge->FixAddPCurve ( sbwd->Edge(i), face, sbwd->IsSeam(i), + myAnalyzer->Surface(), Precision() ); + if ( myFixEdge->Status ( ShapeExtend_DONE ) ) + myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_DONE3 ); + if ( myFixEdge->Status ( ShapeExtend_FAIL ) ) + myStatusEdgeCurves |= ShapeExtend::EncodeStatus ( ShapeExtend_FAIL3 ); + } } } myFixEdge->FixSameParameter ( sbwd->Edge(i), Face()); diff --git a/tests/bugs/modalg_4/bug697_1 b/tests/bugs/modalg_4/bug697_1 index 8e1dd065c6..54e4fe3a57 100755 --- a/tests/bugs/modalg_4/bug697_1 +++ b/tests/bugs/modalg_4/bug697_1 @@ -1,3 +1,4 @@ +puts "TODO OCC29351 ALL: Faulty shapes in variables faulty_1 to faulty_2 " puts "============" puts "OCC697" puts "============" diff --git a/tests/bugs/modalg_4/bug697_5 b/tests/bugs/modalg_4/bug697_5 index 49c6f55261..614820758e 100755 --- a/tests/bugs/modalg_4/bug697_5 +++ b/tests/bugs/modalg_4/bug697_5 @@ -1,3 +1,4 @@ +puts "TODO OCC29351 ALL: Faulty shapes in variables faulty_1 to faulty_2 " puts "============" puts "OCC697" puts "============" diff --git a/tests/bugs/modalg_4/bug919 b/tests/bugs/modalg_4/bug919 index 973f8b8f8f..62bba7c9ce 100755 --- a/tests/bugs/modalg_4/bug919 +++ b/tests/bugs/modalg_4/bug919 @@ -15,7 +15,7 @@ explode a # See comment in CR23244: restore [locate_data_file OCC919-PROC.brep] a_1 # - +fixshape a_1 a_1 checkshape a_1 checkshape a_2 diff --git a/tests/bugs/modalg_7/bug24251 b/tests/bugs/modalg_7/bug24251 index d679cdfb81..2ace69d9f6 100644 --- a/tests/bugs/modalg_7/bug24251 +++ b/tests/bugs/modalg_7/bug24251 @@ -1,6 +1,6 @@ puts "REQUIRED All: Faulty shapes in variables faulty_1 to faulty_" -puts "TODO OCC24251 ALL: ERROR: OCC24251 is reproduced." +#puts "TODO OCC24251 ALL: ERROR: OCC24251 is reproduced." puts "========" puts "OCC24251" diff --git a/tests/bugs/modalg_7/bug26570 b/tests/bugs/modalg_7/bug26570 new file mode 100644 index 0000000000..7b142cb400 --- /dev/null +++ b/tests/bugs/modalg_7/bug26570 @@ -0,0 +1,15 @@ +puts "========" +puts "OCC26570" +puts "========" +puts "" +##################################### +# Crash on attempt to rotate a shape +##################################### + +restore [locate_data_file bug26570.brep] s + +fixshape result s +trotate result 0 0 0 500 0 0 180 -copy +checkshape result + +