From 189062565fa9d0aee655eecbc3150d5ffff15257 Mon Sep 17 00:00:00 2001 From: ifv Date: Thu, 4 Sep 2014 14:07:04 +0400 Subject: [PATCH] 0025068: ShapeAnalysis_FreeBounds::ConnectEdgesToWires returns wires with not valid Closed flag Test case for issue CR25068 --- .../ShapeAnalysis_FreeBounds.cxx | 58 ++- src/ShapeBuild/ShapeBuild_Edge.cxx | 468 +++++++++--------- tests/bugs/heal/bug25068 | 19 + tests/heal/data/advanced/H5 | 2 +- 4 files changed, 304 insertions(+), 243 deletions(-) create mode 100755 tests/bugs/heal/bug25068 diff --git a/src/ShapeAnalysis/ShapeAnalysis_FreeBounds.cxx b/src/ShapeAnalysis/ShapeAnalysis_FreeBounds.cxx index 77385fa0fb..6ed060a616 100644 --- a/src/ShapeAnalysis/ShapeAnalysis_FreeBounds.cxx +++ b/src/ShapeAnalysis/ShapeAnalysis_FreeBounds.cxx @@ -199,6 +199,15 @@ ShapeAnalysis_FreeBounds::ShapeAnalysis_FreeBounds(const TopoDS_Shape& shape, Handle(ShapeExtend_WireData) sewd = new ShapeExtend_WireData (TopoDS::Wire (arrwires->Value (1))); + Standard_Boolean isUsedManifoldMode = Standard_True; + + if((sewd->NbEdges() < 1) && (sewd->NbNonManifoldEdges() > 0)) + { + isUsedManifoldMode = Standard_False; + sewd = new ShapeExtend_WireData (TopoDS::Wire (arrwires->Value (1)), Standard_True, + isUsedManifoldMode); + } + Handle(ShapeAnalysis_Wire) saw = new ShapeAnalysis_Wire; saw->Load (sewd); saw->SetPrecision (tolerance); @@ -227,12 +236,6 @@ ShapeAnalysis_FreeBounds::ShapeAnalysis_FreeBounds(const TopoDS_Shape& shape, ShapeAnalysis_Edge sae; //szv#4:S4163:12Mar99 moved Standard_Boolean done = Standard_False; - Standard_Boolean isUsedManifoldMode = Standard_True; - - if((sewd->NbEdges() < 1) && (sewd->NbNonManifoldEdges() > 0)) - { - isUsedManifoldMode = Standard_False; - } while (!done) { @@ -241,10 +244,8 @@ ShapeAnalysis_FreeBounds::ShapeAnalysis_FreeBounds(const TopoDS_Shape& shape, aSel.SetStop(); Bnd_Box FVBox, LVBox; TopoDS_Vertex Vf, Vl; - Vf = isUsedManifoldMode ? sae.FirstVertex(sewd->Edge(1)) : - sae.FirstVertex(sewd->NonmanifoldEdge(1)); - Vl = isUsedManifoldMode ? sae.LastVertex(sewd->Edge(sewd->NbEdges())) : - sae.LastVertex(sewd->NonmanifoldEdge(sewd->NbNonManifoldEdges())); + Vf = sae.FirstVertex(sewd->Edge(1)); + Vl = sae.LastVertex(sewd->Edge(sewd->NbEdges())); gp_Pnt pf, pl; pf = BRep_Tool::Pnt(Vf); @@ -284,7 +285,7 @@ ShapeAnalysis_FreeBounds::ShapeAnalysis_FreeBounds(const TopoDS_Shape& shape, TopoDS_Wire aCurW = TopoDS::Wire (arrwires->Value (lwire)); Handle(ShapeExtend_WireData) acurwd = new - ShapeExtend_WireData ( TopoDS::Wire (arrwires->Value (lwire))); + ShapeExtend_WireData ( TopoDS::Wire (arrwires->Value (lwire)), Standard_True, isUsedManifoldMode); sewd->Add (acurwd, (tail ? 0 : 1)); } else @@ -328,11 +329,42 @@ ShapeAnalysis_FreeBounds::ShapeAnalysis_FreeBounds(const TopoDS_Shape& shape, //2.making wire TopoDS_Wire wire = sewd->Wire(); - if (!saw->CheckConnected (1) && saw->LastCheckStatus (ShapeExtend_OK)) - wire.Closed (Standard_True); + if(isUsedManifoldMode) + { + if (!saw->CheckConnected (1) && saw->LastCheckStatus (ShapeExtend_OK)) + wire.Closed (Standard_True); + } + else + { + //Try to check connection by number of free vertices + TopTools_MapOfShape vmap; + TopoDS_Iterator it(wire); + + for(; it.More(); it.Next()) + { + const TopoDS_Shape& E = it.Value(); + TopoDS_Iterator ite(E, Standard_False, Standard_True); + for(; ite.More(); ite.Next()) + { + const TopoDS_Shape& V = ite.Value(); + if (V.Orientation() == TopAbs_FORWARD || + V.Orientation() == TopAbs_REVERSED) + { + // add or remove in the vertex map + if (!vmap.Add(V)) vmap.Remove(V); + } + } + + } + if(vmap.IsEmpty()) + { + wire.Closed(Standard_True); + } + } owires->Append (wire); sewd->Clear(); + sewd->ManifoldMode() = isUsedManifoldMode; // Recherche de la premier edge non traitee pour un autre wire. //Searching for first edge for next wire diff --git a/src/ShapeBuild/ShapeBuild_Edge.cxx b/src/ShapeBuild/ShapeBuild_Edge.cxx index 6a334a63f1..197c1c0b2b 100644 --- a/src/ShapeBuild/ShapeBuild_Edge.cxx +++ b/src/ShapeBuild/ShapeBuild_Edge.cxx @@ -58,22 +58,32 @@ //======================================================================= TopoDS_Edge ShapeBuild_Edge::CopyReplaceVertices (const TopoDS_Edge& edge, - const TopoDS_Vertex& V1, - const TopoDS_Vertex& V2) const + const TopoDS_Vertex& V1, + const TopoDS_Vertex& V2) const { TopTools_SequenceOfShape aNMVertices; TopoDS_Vertex newV1 = V1, newV2 = V2; if ( newV1.IsNull() || newV2.IsNull() ) { - for ( TopoDS_Iterator it(edge); it.More(); it.Next() ) { + TopoDS_Iterator it; + if(edge.Orientation() == TopAbs_FORWARD || + edge.Orientation() == TopAbs_REVERSED) + { + it.Initialize(edge, Standard_True, Standard_True); + } + else + { + it.Initialize(edge, Standard_False, Standard_True); + } + for ( ; it.More(); it.Next() ) { TopoDS_Vertex V = TopoDS::Vertex ( it.Value() ); if ( V.Orientation() == TopAbs_FORWARD ) { - if ( newV1.IsNull() ) newV1 = V; + if ( newV1.IsNull() ) newV1 = V; } else if ( V.Orientation() == TopAbs_REVERSED ) { - if ( newV2.IsNull() ) newV2 = V; + if ( newV2.IsNull() ) newV2 = V; } else if(V1.IsNull() && V2.IsNull()) - aNMVertices.Append(V); + aNMVertices.Append(V); } } newV1.Orientation ( TopAbs_FORWARD ); @@ -82,7 +92,7 @@ TopoDS_Edge ShapeBuild_Edge::CopyReplaceVertices (const TopoDS_Edge& edge, //szv#4:S4163:12Mar99 SGI warns TopoDS_Shape sh = edge.EmptyCopied(); TopoDS_Edge E = TopoDS::Edge( sh ); - + BRep_Builder B; if ( ! newV1.IsNull() ) B.Add ( E, newV1 ); if ( ! newV2.IsNull() ) B.Add ( E, newV2 ); @@ -91,23 +101,23 @@ TopoDS_Edge ShapeBuild_Edge::CopyReplaceVertices (const TopoDS_Edge& edge, Standard_Integer i =1; for( ; i <= aNMVertices.Length(); i++) B.Add ( E,TopoDS::Vertex(aNMVertices.Value(i))); - + //S4054, rln 17.11.98 annie_surf.igs entity D77, 3D and pcurve have different //ranges, after B.Range all the ranges become as 3D CopyRanges ( E, edge ); -/* + /* for (BRep_ListIteratorOfListOfCurveRepresentation itcr - ((*((Handle(BRep_TEdge)*)&edge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) { - Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); - if ( GC.IsNull() ) continue; - Standard_Real first, last; - GC->Range ( first, last ); - if ( GC->IsCurve3D() ) - B.Range ( E, first, last ); - else if ( GC->IsCurveOnSurface() ) - B.Range (E, GC->Surface(), edge.Location().Multiplied (GC->Location()), first, last);//BUC50003 entity 132 edge 1 + ((*((Handle(BRep_TEdge)*)&edge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) { + Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); + if ( GC.IsNull() ) continue; + Standard_Real first, last; + GC->Range ( first, last ); + if ( GC->IsCurve3D() ) + B.Range ( E, first, last ); + else if ( GC->IsCurveOnSurface() ) + B.Range (E, GC->Surface(), edge.Location().Multiplied (GC->Location()), first, last);//BUC50003 entity 132 edge 1 } -*/ + */ return E; } @@ -118,8 +128,8 @@ TopoDS_Edge ShapeBuild_Edge::CopyReplaceVertices (const TopoDS_Edge& edge, // Added, cause invoke ShapeAnalysis leads to cyclic dependancy. static Standard_Real AdjustByPeriod(const Standard_Real Val, - const Standard_Real ToVal, - const Standard_Real Period) + const Standard_Real ToVal, + const Standard_Real Period) { Standard_Real diff = Val - ToVal; Standard_Real D = Abs ( diff ); @@ -136,11 +146,11 @@ static Standard_Boolean IsPeriodic(const Handle(Geom_Curve)& theCurve) // ask IsPeriodic on BasisCurve Handle(Geom_Curve) aTmpCurve = theCurve; while ( (aTmpCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) || - (aTmpCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) ) { - if (aTmpCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) - aTmpCurve = Handle(Geom_OffsetCurve)::DownCast(aTmpCurve)->BasisCurve(); - if (aTmpCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) - aTmpCurve = Handle(Geom_TrimmedCurve)::DownCast(aTmpCurve)->BasisCurve(); + (aTmpCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) ) { + if (aTmpCurve->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) + aTmpCurve = Handle(Geom_OffsetCurve)::DownCast(aTmpCurve)->BasisCurve(); + if (aTmpCurve->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) + aTmpCurve = Handle(Geom_TrimmedCurve)::DownCast(aTmpCurve)->BasisCurve(); } return aTmpCurve->IsPeriodic(); } @@ -152,103 +162,103 @@ Standard_Boolean IsPeriodic(const Handle(Geom2d_Curve)& theCurve) // ask IsPeriodic on BasisCurve Handle(Geom2d_Curve) aTmpCurve = theCurve; while ( (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) || - (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) ) { - if (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) - aTmpCurve = Handle(Geom2d_OffsetCurve)::DownCast(aTmpCurve)->BasisCurve(); - if (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) - aTmpCurve = Handle(Geom2d_TrimmedCurve)::DownCast(aTmpCurve)->BasisCurve(); + (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) ) { + if (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_OffsetCurve))) + aTmpCurve = Handle(Geom2d_OffsetCurve)::DownCast(aTmpCurve)->BasisCurve(); + if (aTmpCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) + aTmpCurve = Handle(Geom2d_TrimmedCurve)::DownCast(aTmpCurve)->BasisCurve(); } return aTmpCurve->IsPeriodic(); } void ShapeBuild_Edge::CopyRanges (const TopoDS_Edge& toedge, - const TopoDS_Edge& fromedge, - const Standard_Real alpha, - const Standard_Real beta) const + const TopoDS_Edge& fromedge, + const Standard_Real alpha, + const Standard_Real beta) const { -/* BRep_Builder B; - for (BRep_ListIteratorOfListOfCurveRepresentation itcr - ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) { - Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); - if ( GC.IsNull() ) continue; - Standard_Real first, last; - GC->Range ( first, last ); - if ( GC->IsCurve3D() ) - B.Range ( toedge, first, last ); - else if ( GC->IsCurveOnSurface() ) - B.Range ( toedge, GC->Surface(), fromedge.Location().Multiplied (GC->Location()), first, last); + /* BRep_Builder B; + for (BRep_ListIteratorOfListOfCurveRepresentation itcr + ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) { + Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); + if ( GC.IsNull() ) continue; + Standard_Real first, last; + GC->Range ( first, last ); + if ( GC->IsCurve3D() ) + B.Range ( toedge, first, last ); + else if ( GC->IsCurveOnSurface() ) + B.Range ( toedge, GC->Surface(), fromedge.Location().Multiplied (GC->Location()), first, last); } -*/ + */ for (BRep_ListIteratorOfListOfCurveRepresentation fromitcr - ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves()); fromitcr.More(); fromitcr.Next()) { - Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value()); - if ( fromGC.IsNull() ) continue; - Standard_Boolean isC3d = fromGC->IsCurve3D(); - if(isC3d) { - if(fromGC->Curve3D().IsNull()) continue; } - else { - if(fromGC->PCurve().IsNull()) continue; } - - if ( ! isC3d && ! fromGC->IsCurveOnSurface()) continue; // only 3d curves and pcurves are treated + ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves()); fromitcr.More(); fromitcr.Next()) { + Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value()); + if ( fromGC.IsNull() ) continue; + Standard_Boolean isC3d = fromGC->IsCurve3D(); + if(isC3d) { + if(fromGC->Curve3D().IsNull()) continue; } + else { + if(fromGC->PCurve().IsNull()) continue; } - Handle(Geom_Surface) surface; - TopLoc_Location L; - if ( ! isC3d ) { - surface = fromGC->Surface(); - L = fromGC->Location(); - } + if ( ! isC3d && ! fromGC->IsCurveOnSurface()) continue; // only 3d curves and pcurves are treated - BRep_ListOfCurveRepresentation& tolist = (*((Handle(BRep_TEdge)*)&toedge.TShape()))->ChangeCurves(); - Handle(BRep_GCurve) toGC; - for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More(); toitcr.Next()) { - toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value()); - if ( toGC.IsNull() ) continue; - if ( isC3d ) { - if ( ! toGC->IsCurve3D() ) continue; - } - else if ( ! toGC->IsCurveOnSurface() || - surface != toGC->Surface() || L != toGC->Location() ) continue; - Standard_Real first = fromGC->First(); - Standard_Real last = fromGC->Last(); - Standard_Real len = last - first; - Standard_Real newF = first+alpha*len; - Standard_Real newL = first+beta*len; + Handle(Geom_Surface) surface; + TopLoc_Location L; + if ( ! isC3d ) { + surface = fromGC->Surface(); + L = fromGC->Location(); + } - // PTV: 22.03.2002 fix for edge range. - // file test-m020306-v2.step Shell #665 (Faces #40110. #40239). - Standard_Real aPeriod=1., aCrvF=0., aCrvL=1.; - Standard_Boolean doCheck = Standard_False; - if (toGC->IsKind(STANDARD_TYPE(BRep_Curve3D))) { - Handle(Geom_Curve) aCrv3d = Handle(BRep_Curve3D)::DownCast(toGC)->Curve3D(); - // 15.11.2002 PTV OCC966 - if ( ! aCrv3d.IsNull() && IsPeriodic(aCrv3d) ) { - aPeriod = aCrv3d->Period(); - aCrvF = aCrv3d->FirstParameter(); - aCrvL = aCrv3d->LastParameter(); - doCheck = Standard_True; + BRep_ListOfCurveRepresentation& tolist = (*((Handle(BRep_TEdge)*)&toedge.TShape()))->ChangeCurves(); + Handle(BRep_GCurve) toGC; + for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More(); toitcr.Next()) { + toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value()); + if ( toGC.IsNull() ) continue; + if ( isC3d ) { + if ( ! toGC->IsCurve3D() ) continue; } - } - else if (toGC->IsKind(STANDARD_TYPE(BRep_CurveOnSurface))) { - Handle(Geom2d_Curve) aCrv2d = Handle(BRep_CurveOnSurface)::DownCast(toGC)->PCurve(); - // 15.11.2002 PTV OCC966 - if (!aCrv2d.IsNull() && IsPeriodic(aCrv2d)) { - aPeriod = aCrv2d->Period(); - aCrvF = aCrv2d->FirstParameter(); - aCrvL = aCrv2d->LastParameter(); - doCheck = Standard_True; + else if ( ! toGC->IsCurveOnSurface() || + surface != toGC->Surface() || L != toGC->Location() ) continue; + Standard_Real first = fromGC->First(); + Standard_Real last = fromGC->Last(); + Standard_Real len = last - first; + Standard_Real newF = first+alpha*len; + Standard_Real newL = first+beta*len; + + // PTV: 22.03.2002 fix for edge range. + // file test-m020306-v2.step Shell #665 (Faces #40110. #40239). + Standard_Real aPeriod=1., aCrvF=0., aCrvL=1.; + Standard_Boolean doCheck = Standard_False; + if (toGC->IsKind(STANDARD_TYPE(BRep_Curve3D))) { + Handle(Geom_Curve) aCrv3d = Handle(BRep_Curve3D)::DownCast(toGC)->Curve3D(); + // 15.11.2002 PTV OCC966 + if ( ! aCrv3d.IsNull() && IsPeriodic(aCrv3d) ) { + aPeriod = aCrv3d->Period(); + aCrvF = aCrv3d->FirstParameter(); + aCrvL = aCrv3d->LastParameter(); + doCheck = Standard_True; + } } + else if (toGC->IsKind(STANDARD_TYPE(BRep_CurveOnSurface))) { + Handle(Geom2d_Curve) aCrv2d = Handle(BRep_CurveOnSurface)::DownCast(toGC)->PCurve(); + // 15.11.2002 PTV OCC966 + if (!aCrv2d.IsNull() && IsPeriodic(aCrv2d)) { + aPeriod = aCrv2d->Period(); + aCrvF = aCrv2d->FirstParameter(); + aCrvL = aCrv2d->LastParameter(); + doCheck = Standard_True; + } + } + if ( doCheck && ( (fabs(newF -aCrvF ) > Precision::PConfusion() && newF < aCrvF) || newF >= aCrvL ) ) { + Standard_Real aShift = AdjustByPeriod(newF, 0.5*(aCrvF+aCrvL), aPeriod); + newF += aShift; + newL += aShift; + BRep_Builder().SameRange(toedge,Standard_False); + BRep_Builder().SameParameter(toedge,Standard_False); + } + + toGC->SetRange ( newF, newL ); + break; } - if ( doCheck && ( (fabs(newF -aCrvF ) > Precision::PConfusion() && newF < aCrvF) || newF >= aCrvL ) ) { - Standard_Real aShift = AdjustByPeriod(newF, 0.5*(aCrvF+aCrvL), aPeriod); - newF += aShift; - newL += aShift; - BRep_Builder().SameRange(toedge,Standard_False); - BRep_Builder().SameParameter(toedge,Standard_False); - } - - toGC->SetRange ( newF, newL ); - break; - } } } @@ -258,16 +268,16 @@ void ShapeBuild_Edge::CopyRanges (const TopoDS_Edge& toedge, //======================================================================= void ShapeBuild_Edge::SetRange3d (const TopoDS_Edge& edge, - const Standard_Real first, - const Standard_Real last) const + const Standard_Real first, + const Standard_Real last) const { for (BRep_ListIteratorOfListOfCurveRepresentation itcr - ((*((Handle(BRep_TEdge)*)&edge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) { - Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); - if ( GC.IsNull() || !GC->IsCurve3D() ) continue; - GC->SetRange ( first, last ); - break; + ((*((Handle(BRep_TEdge)*)&edge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) { + Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); + if ( GC.IsNull() || !GC->IsCurve3D() ) continue; + GC->SetRange ( first, last ); + break; } } @@ -282,36 +292,36 @@ void ShapeBuild_Edge::CopyPCurves (const TopoDS_Edge& toedge, const TopoDS_Edge& TopLoc_Location toLoc = toedge.Location(); for (BRep_ListIteratorOfListOfCurveRepresentation fromitcr ((*((Handle(BRep_TEdge)*)&fromedge.TShape()))->ChangeCurves()); fromitcr.More(); fromitcr.Next()) { - Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value()); - if ( fromGC.IsNull() ) continue; - if ( fromGC->IsCurveOnSurface() ) { - Handle(Geom_Surface) surface = fromGC->Surface(); - TopLoc_Location L = fromGC->Location(); - Standard_Boolean found = Standard_False; - BRep_ListOfCurveRepresentation& tolist = (*((Handle(BRep_TEdge)*)&toedge.TShape()))->ChangeCurves(); - Handle(BRep_GCurve) toGC; - for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More() && !found; toitcr.Next()) { - toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value()); - if ( toGC.IsNull() || !toGC->IsCurveOnSurface() || - surface != toGC->Surface() || L != toGC->Location() ) continue; - found = Standard_True; - break; + Handle(BRep_GCurve) fromGC = Handle(BRep_GCurve)::DownCast(fromitcr.Value()); + if ( fromGC.IsNull() ) continue; + if ( fromGC->IsCurveOnSurface() ) { + Handle(Geom_Surface) surface = fromGC->Surface(); + TopLoc_Location L = fromGC->Location(); + Standard_Boolean found = Standard_False; + BRep_ListOfCurveRepresentation& tolist = (*((Handle(BRep_TEdge)*)&toedge.TShape()))->ChangeCurves(); + Handle(BRep_GCurve) toGC; + for (BRep_ListIteratorOfListOfCurveRepresentation toitcr (tolist); toitcr.More() && !found; toitcr.Next()) { + toGC = Handle(BRep_GCurve)::DownCast(toitcr.Value()); + if ( toGC.IsNull() || !toGC->IsCurveOnSurface() || + surface != toGC->Surface() || L != toGC->Location() ) continue; + found = Standard_True; + break; + } + if (!found) { + toGC = Handle(BRep_GCurve)::DownCast(fromGC->Copy()); + tolist.Append (toGC); + } + Handle(Geom2d_Curve) pcurve = fromGC->PCurve(); + toGC->PCurve(Handle(Geom2d_Curve)::DownCast(pcurve->Copy())); + + //bug OCC209 invalid location of pcurve in the edge after copying + TopLoc_Location newLoc = (fromLoc*L).Predivided(toLoc);//(L * fromLoc).Predivided(toLoc); + toGC->Location(newLoc); + if ( fromGC->IsCurveOnClosedSurface() ) { + pcurve = fromGC->PCurve2(); + toGC->PCurve2(Handle(Geom2d_Curve)::DownCast(pcurve->Copy())); + } } - if (!found) { - toGC = Handle(BRep_GCurve)::DownCast(fromGC->Copy()); - tolist.Append (toGC); - } - Handle(Geom2d_Curve) pcurve = fromGC->PCurve(); - toGC->PCurve(Handle(Geom2d_Curve)::DownCast(pcurve->Copy())); - - //bug OCC209 invalid location of pcurve in the edge after copying - TopLoc_Location newLoc = (fromLoc*L).Predivided(toLoc);//(L * fromLoc).Predivided(toLoc); - toGC->Location(newLoc); - if ( fromGC->IsCurveOnClosedSurface() ) { - pcurve = fromGC->PCurve2(); - toGC->PCurve2(Handle(Geom2d_Curve)::DownCast(pcurve->Copy())); - } - } } } //======================================================================= @@ -320,27 +330,27 @@ void ShapeBuild_Edge::CopyPCurves (const TopoDS_Edge& toedge, const TopoDS_Edge& //======================================================================= TopoDS_Edge ShapeBuild_Edge::Copy (const TopoDS_Edge &edge, - const Standard_Boolean sharepcurves) const + const Standard_Boolean sharepcurves) const { TopoDS_Vertex dummy1, dummy2; TopoDS_Edge newedge = CopyReplaceVertices ( edge, dummy1, dummy2 ); if ( ! sharepcurves ) CopyPCurves ( newedge, edge ); return newedge; } - + //======================================================================= //function : RemovePCurve //purpose : //======================================================================= void ShapeBuild_Edge::RemovePCurve (const TopoDS_Edge& edge, - const TopoDS_Face& face) const + const TopoDS_Face& face) const { BRep_Builder B; Handle(Geom2d_Curve) c2dNull; -//:S4136 Standard_Real tol = BRep_Tool::Tolerance ( edge ); + //:S4136 Standard_Real tol = BRep_Tool::Tolerance ( edge ); if ( BRep_Tool::IsClosed ( edge, face ) ) - B.UpdateEdge ( edge, c2dNull, c2dNull, face, 0. ); //:S4136: tol + B.UpdateEdge ( edge, c2dNull, c2dNull, face, 0. ); //:S4136: tol else B.UpdateEdge ( edge, c2dNull, face, 0. ); //:S4136: tol } @@ -350,25 +360,25 @@ void ShapeBuild_Edge::RemovePCurve (const TopoDS_Edge& edge, //======================================================================= void ShapeBuild_Edge::RemovePCurve (const TopoDS_Edge& edge, - const Handle(Geom_Surface)& surf) const + const Handle(Geom_Surface)& surf) const { RemovePCurve ( edge, surf, TopLoc_Location() ); } - + //======================================================================= //function : RemovePCurve //purpose : //======================================================================= void ShapeBuild_Edge::RemovePCurve (const TopoDS_Edge& edge, - const Handle(Geom_Surface)& surf, - const TopLoc_Location &loc) const + const Handle(Geom_Surface)& surf, + const TopLoc_Location &loc) const { BRep_Builder B; Handle(Geom2d_Curve) c2dNull; -//:S4136 Standard_Real tol = BRep_Tool::Tolerance ( edge ); + //:S4136 Standard_Real tol = BRep_Tool::Tolerance ( edge ); if ( BRep_Tool::IsClosed ( edge, surf, loc ) ) - B.UpdateEdge ( edge, c2dNull, c2dNull, surf, loc, 0. ); //:S4136: tol + B.UpdateEdge ( edge, c2dNull, c2dNull, surf, loc, 0. ); //:S4136: tol else B.UpdateEdge ( edge, c2dNull, surf, loc, 0. ); //:S4136: tol } @@ -378,8 +388,8 @@ void ShapeBuild_Edge::RemovePCurve (const TopoDS_Edge& edge, //======================================================================= void ShapeBuild_Edge::ReplacePCurve (const TopoDS_Edge& edge, - const Handle(Geom2d_Curve)& pcurve, - const TopoDS_Face& face) const + const Handle(Geom2d_Curve)& pcurve, + const TopoDS_Face& face) const { BRep_Builder B; Standard_Real f,l; @@ -411,24 +421,24 @@ void ShapeBuild_Edge::ReplacePCurve (const TopoDS_Edge& edge, // This makes difference for faces based on plane surfaces where pcurves can be // not stored but returned by BRep_Tools::CurveOnSurface static Standard_Integer CountPCurves (const TopoDS_Edge &edge, - const TopoDS_Face &face) + const TopoDS_Face &face) { TopLoc_Location L; Handle(Geom_Surface) S = BRep_Tool::Surface ( face, L ); TopLoc_Location l = L.Predivided(edge.Location()); - + for (BRep_ListIteratorOfListOfCurveRepresentation itcr ((*((Handle(BRep_TEdge)*)&edge.TShape()))->ChangeCurves()); itcr.More(); itcr.Next()) { - Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); - if ( ! GC.IsNull() && GC->IsCurveOnSurface ( S, l ) ) - return ( GC->IsCurveOnClosedSurface() ? 2 : 1 ); + Handle(BRep_GCurve) GC = Handle(BRep_GCurve)::DownCast(itcr.Value()); + if ( ! GC.IsNull() && GC->IsCurveOnSurface ( S, l ) ) + return ( GC->IsCurveOnClosedSurface() ? 2 : 1 ); } return 0; } Standard_Boolean ShapeBuild_Edge::ReassignPCurve (const TopoDS_Edge& edge, - const TopoDS_Face& old, - const TopoDS_Face& sub) const + const TopoDS_Face& old, + const TopoDS_Face& sub) const { Standard_Integer npcurves = CountPCurves ( edge, old ); //if ( npcurves <1 ) return Standard_False; //gka @@ -438,8 +448,8 @@ Standard_Boolean ShapeBuild_Edge::ReassignPCurve (const TopoDS_Edge& edge, pc = BRep_Tool::CurveOnSurface ( edge, old, f, l ); if ( pc.IsNull() ) return Standard_False; else if( npcurves == 0) npcurves =1; //gka - - + + BRep_Builder B; // if the pcurve was only one, remove; else leave second one @@ -452,23 +462,23 @@ Standard_Boolean ShapeBuild_Edge::ReassignPCurve (const TopoDS_Edge& edge, B.Range ( edge, old, f, l ); } else RemovePCurve ( edge, old ); - + // if edge does not have yet pcurves on sub, just add; else add as first Standard_Integer npcs = CountPCurves ( edge, sub ); if ( npcs <1 ) B.UpdateEdge ( edge, pc, sub, 0. ); else { -//smh#8 Porting AIX + //smh#8 Porting AIX TopoDS_Shape tmpshape = edge.Reversed(); TopoDS_Edge erev = TopoDS::Edge (tmpshape); Standard_Real cf, cl; Handle(Geom2d_Curve) pcs = BRep_Tool::CurveOnSurface ( erev, sub, cf, cl ); if ( edge.Orientation() == TopAbs_REVERSED ) // because B.UpdateEdge does not check edge orientation - B.UpdateEdge ( edge, pcs, pc, sub, 0. ); + B.UpdateEdge ( edge, pcs, pc, sub, 0. ); else B.UpdateEdge ( edge, pc, pcs, sub, 0. ); } - + B.Range ( edge, sub, f, l ); - + return Standard_True; } @@ -478,10 +488,10 @@ Standard_Boolean ShapeBuild_Edge::ReassignPCurve (const TopoDS_Edge& edge, //======================================================================= Handle(Geom2d_Curve) ShapeBuild_Edge::TransformPCurve(const Handle(Geom2d_Curve)& pcurve, - const gp_Trsf2d& trans, - const Standard_Real uFact, - Standard_Real& aFirst, - Standard_Real& aLast) const + const gp_Trsf2d& trans, + const Standard_Real uFact, + Standard_Real& aFirst, + Standard_Real& aLast) const { Handle(Geom2d_Curve) result = Handle(Geom2d_Curve)::DownCast(pcurve->Copy()); if(trans.Form()!=gp_Identity) { @@ -496,11 +506,11 @@ Handle(Geom2d_Curve) ShapeBuild_Edge::TransformPCurve(const Handle(Geom2d_Curve) Handle(Geom2d_TrimmedCurve) thecurve = Handle(Geom2d_TrimmedCurve)::DownCast(result); result = thecurve->BasisCurve(); } - + gp_GTrsf2d tMatu; tMatu.SetAffinity(gp::OY2d(), uFact); gp_XY pXY; - + if (result->IsKind(STANDARD_TYPE(Geom2d_Line))) { Handle(Geom2d_Line) aLine2d = Handle(Geom2d_Line)::DownCast(result); gp_Pnt2d Pf, Pl; @@ -537,11 +547,11 @@ Handle(Geom2d_Curve) ShapeBuild_Edge::TransformPCurve(const Handle(Geom2d_Curve) //Handle(Geom_Curve) curve = GeomAPI::To3d(result,pln); Handle(Geom2d_TrimmedCurve) tcurve = new Geom2d_TrimmedCurve(result,aFirst,aLast); //protection agains parabols ets Geom2dConvert_ApproxCurve approx (tcurve, Precision::Approximation(), - GeomAbs_C1, 100, 6 ); + GeomAbs_C1, 100, 6 ); if ( approx.HasResult() ) - aBSpline2d = Handle(Geom2d_BSplineCurve)::DownCast(approx.Curve()); + aBSpline2d = Handle(Geom2d_BSplineCurve)::DownCast(approx.Curve()); else - aBSpline2d = Geom2dConvert::CurveToBSplineCurve(tcurve,Convert_QuasiAngular); + aBSpline2d = Geom2dConvert::CurveToBSplineCurve(tcurve,Convert_QuasiAngular); aFirst = aBSpline2d->FirstParameter(); aLast = aBSpline2d->LastParameter(); } @@ -550,7 +560,7 @@ Handle(Geom2d_Curve) ShapeBuild_Edge::TransformPCurve(const Handle(Geom2d_Curve) } else aBSpline2d = Handle(Geom2d_BSplineCurve)::DownCast(result); - + // transform the Poles of the BSplineCurve Standard_Integer nbPol = aBSpline2d->NbPoles(); gp_Pnt2d Pt1; @@ -573,7 +583,7 @@ void ShapeBuild_Edge::RemoveCurve3d (const TopoDS_Edge& edge) const { BRep_Builder B; Handle(Geom_Curve) c3dNull; -//:S4136 Standard_Real tol = BRep_Tool::Tolerance (edge); + //:S4136 Standard_Real tol = BRep_Tool::Tolerance (edge); B.UpdateEdge (edge, c3dNull, 0. ); //:S4136: tol } @@ -586,42 +596,42 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const { try { OCC_CATCH_SIGNALS - //#48 rln 10.12.98 S4054 UKI60107-5 entity 365 - //C0 surface (but curve 3d is required as C1) and tolerance is 1e-07 - //lets use maximum of tolerance and default parameter 1.e-5 - //Another solutions: use quite big Tolerance or require C0 curve on C0 surface - if ( BRepLib::BuildCurve3d (edge, Max (1.e-5, BRep_Tool::Tolerance(edge) ) ) ) { - //#50 S4054 rln 14.12.98 write cylinder in BRep mode into IGES and read back - //with 2DUse_Forced - pcurve and removed 3D curves have different ranges - if (BRep_Tool::SameRange (edge)) { - Standard_Real first, last; - BRep_Tool::Range (edge, first, last); - BRep_Builder().Range (edge, first, last);//explicit setting for all reps + //#48 rln 10.12.98 S4054 UKI60107-5 entity 365 + //C0 surface (but curve 3d is required as C1) and tolerance is 1e-07 + //lets use maximum of tolerance and default parameter 1.e-5 + //Another solutions: use quite big Tolerance or require C0 curve on C0 surface + if ( BRepLib::BuildCurve3d (edge, Max (1.e-5, BRep_Tool::Tolerance(edge) ) ) ) { + //#50 S4054 rln 14.12.98 write cylinder in BRep mode into IGES and read back + //with 2DUse_Forced - pcurve and removed 3D curves have different ranges + if (BRep_Tool::SameRange (edge)) { + Standard_Real first, last; + BRep_Tool::Range (edge, first, last); + BRep_Builder().Range (edge, first, last);//explicit setting for all reps + } + Handle(Geom_Curve) c3d; + Standard_Real f,l; + c3d = BRep_Tool::Curve(edge,f,l); + if (c3d.IsNull()) + return Standard_False; + // 15.11.2002 PTV OCC966 + if(!IsPeriodic(c3d)) { + Standard_Boolean isLess = Standard_False; + if(f < c3d->FirstParameter()) { + isLess = Standard_True; + f = c3d->FirstParameter(); + } + if(l > c3d->LastParameter()) { + isLess = Standard_True; + l = c3d->LastParameter(); + } + if(isLess) { + SetRange3d(edge,f,l); + BRep_Builder().SameRange(edge,Standard_False); + } + } + + return Standard_True; } - Handle(Geom_Curve) c3d; - Standard_Real f,l; - c3d = BRep_Tool::Curve(edge,f,l); - if (c3d.IsNull()) - return Standard_False; - // 15.11.2002 PTV OCC966 - if(!IsPeriodic(c3d)) { - Standard_Boolean isLess = Standard_False; - if(f < c3d->FirstParameter()) { - isLess = Standard_True; - f = c3d->FirstParameter(); - } - if(l > c3d->LastParameter()) { - isLess = Standard_True; - l = c3d->LastParameter(); - } - if(isLess) { - SetRange3d(edge,f,l); - BRep_Builder().SameRange(edge,Standard_False); - } - } - - return Standard_True; - } } catch(Standard_Failure) { #ifdef DEB @@ -638,7 +648,7 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const //purpose : //======================================================================= - void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom_Curve)& curve,const TopLoc_Location& L) const +void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom_Curve)& curve,const TopLoc_Location& L) const { MakeEdge (edge,curve, L, curve->FirstParameter(), curve->LastParameter()); } @@ -648,7 +658,7 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const //purpose : //======================================================================= - void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom_Curve)& curve,const TopLoc_Location& L,const Standard_Real p1,const Standard_Real p2) const +void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom_Curve)& curve,const TopLoc_Location& L,const Standard_Real p1,const Standard_Real p2) const { BRepBuilderAPI_MakeEdge ME (curve, p1, p2); if (!ME.IsDone()) { @@ -662,7 +672,7 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const BRep_Builder B; B.UpdateEdge (E, curve, L, 0.); B.Range (E, p1, p2); - + TopoDS_Vertex V1, V2; TopExp::Vertices (E, V1, V2); gp_Pnt P1 = BRep_Tool::Pnt (V1), P2 = BRep_Tool::Pnt (V2); @@ -678,7 +688,7 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const //purpose : //======================================================================= - void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,const TopoDS_Face& face) const +void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,const TopoDS_Face& face) const { MakeEdge (edge, pcurve, face, pcurve->FirstParameter(), pcurve->LastParameter()); } @@ -688,7 +698,7 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const //purpose : //======================================================================= - void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,const TopoDS_Face& face,const Standard_Real p1,const Standard_Real p2) const +void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve,const TopoDS_Face& face,const Standard_Real p1,const Standard_Real p2) const { TopLoc_Location L; const Handle(Geom_Surface)& S = BRep_Tool::Surface(face, L); @@ -700,8 +710,8 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const //purpose : //======================================================================= - void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve, - const Handle(Geom_Surface)& S,const TopLoc_Location& L) const +void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve, + const Handle(Geom_Surface)& S,const TopLoc_Location& L) const { MakeEdge(edge, pcurve, S, L, pcurve->FirstParameter(), pcurve->LastParameter()); } @@ -711,9 +721,9 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const //purpose : //======================================================================= - void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve, - const Handle(Geom_Surface)& S,const TopLoc_Location& L, - const Standard_Real p1,const Standard_Real p2) const +void ShapeBuild_Edge::MakeEdge(TopoDS_Edge& edge,const Handle(Geom2d_Curve)& pcurve, + const Handle(Geom_Surface)& S,const TopLoc_Location& L, + const Standard_Real p1,const Standard_Real p2) const { BRepBuilderAPI_MakeEdge ME (pcurve, S, p1, p2); if (!ME.IsDone()) { @@ -728,7 +738,7 @@ Standard_Boolean ShapeBuild_Edge::BuildCurve3d (const TopoDS_Edge& edge) const BRep_Builder B; B.UpdateEdge (E, pcurve, S, L, 0.); B.Range (E, S, L, p1, p2); - + TopoDS_Vertex V1, V2; TopExp::Vertices (E, V1, V2); gp_Pnt P1 = BRep_Tool::Pnt (V1), P2 = BRep_Tool::Pnt (V2); diff --git a/tests/bugs/heal/bug25068 b/tests/bugs/heal/bug25068 new file mode 100755 index 0000000000..5210b863d7 --- /dev/null +++ b/tests/bugs/heal/bug25068 @@ -0,0 +1,19 @@ +puts "============" +puts "OCC25068" +puts "============" +puts "" +################################################### +## ShapeAnalysis_FreeBounds::ConnectEdgesToWires returns wires with not valid Closed flag +################################################### + +restore [locate_data_file bug24807_Compound.brep] a +connectedges r a 1.e-7 0 +explode r + +set info [whatis r_1] + +if { [regexp "Closed" ${info}] == 1 } { + puts "Error: Closed flag is not valid" +} else { + puts "OK: Closed flag is valid" +} diff --git a/tests/heal/data/advanced/H5 b/tests/heal/data/advanced/H5 index 2e785c0094..ed63a3ac60 100644 --- a/tests/heal/data/advanced/H5 +++ b/tests/heal/data/advanced/H5 @@ -2,7 +2,7 @@ if {[string compare $command "ShapeConvertRev"] == 0 } { puts "TODO OCC23127 ALL: Error : The resulting shape is not correct" } if {[string compare $command "SplitAngle"] == 0 } { - puts "TODO OCC23127 ALL: Faulty shapes in variables faulty_1 to faulty_9 " + puts "TODO OCC23127 ALL: Faulty shapes in variables faulty_1 to faulty_" puts "TODO ?DEBUG_OCC24121 Debian60-64 Windows: Error: Exception in ShapeUpgrade_FaceDivide" } restore [locate_data_file CTO900_ger60598c.rle] a