From c8ea5b8e3fcee6ebc76eae767cd37b372c518ee7 Mon Sep 17 00:00:00 2001 From: jgv Date: Thu, 16 Jan 2014 12:20:12 +0400 Subject: [PATCH] 0024204: The algorithm BRepOffsetAPI_MakePipeShell produces resulting shape with unwarrantably big tolerance Added test case bugs/modalg_5/bug24204 Modified following test cases: bugs modalg_3 bug605 - case with bad input data, command "settolerance w1 1.e-7" was added; bugs modalg_4 bug629 - wrong case, now the algorithm can not build pipes on such profiles, test case was removed; bugs modalg_4 bug13595_1, bug13595_1 - number of subshapes was has changed; bugs modalg_5 bug23706_2 - square of resulting face was changed; bugs modalg_5 bug23870_1, bug23870_2, bug23870_3, bug23870_4, bug23870_5 - the number of subshapes was changed. --- src/BRepFill/BRepFill.cdl | 6 + src/BRepFill/BRepFill_Draft.cxx | 6 +- src/BRepFill/BRepFill_Evolved.cxx | 5 +- src/BRepFill/BRepFill_LocationLaw.cxx | 8 +- src/BRepFill/BRepFill_Pipe.cdl | 14 +- src/BRepFill/BRepFill_Pipe.cxx | 397 +++++----------- src/BRepFill/BRepFill_PipeShell.cxx | 17 +- src/BRepFill/BRepFill_ShapeLaw.cxx | 43 +- src/BRepFill/BRepFill_Sweep.cdl | 19 +- src/BRepFill/BRepFill_Sweep.cxx | 466 ++++++++++++++----- src/BRepTools/BRepTools_TrsfModification.cxx | 4 + src/GeomFill/GeomFill_SectionPlacement.cxx | 4 +- tests/bugs/modalg_3/bug605 | 2 + tests/bugs/modalg_4/bug13595_1 | 6 +- tests/bugs/modalg_4/bug13595_2 | 6 +- tests/bugs/modalg_4/bug629 | 25 - tests/bugs/modalg_5/bug23706_2 | 2 +- tests/bugs/modalg_5/bug23870_1 | 6 +- tests/bugs/modalg_5/bug23870_2 | 6 +- tests/bugs/modalg_5/bug23870_3 | 6 +- tests/bugs/modalg_5/bug23870_4 | 6 +- tests/bugs/modalg_5/bug23870_5 | 6 +- tests/bugs/modalg_5/bug24204 | 57 +++ 23 files changed, 648 insertions(+), 469 deletions(-) delete mode 100755 tests/bugs/modalg_4/bug629 create mode 100644 tests/bugs/modalg_5/bug24204 diff --git a/src/BRepFill/BRepFill.cdl b/src/BRepFill/BRepFill.cdl index df96e385e2..14104cc9ef 100644 --- a/src/BRepFill/BRepFill.cdl +++ b/src/BRepFill/BRepFill.cdl @@ -189,6 +189,12 @@ is ListOfShape from TopTools, OrientedShapeMapHasher from TopTools); + class DataMapOfShapeHArray2OfShape instantiates + DataMap from TCollection (Shape from TopoDS, + HArray2OfShape from TopTools, + ShapeMapHasher from TopTools); + + class CurveConstraint ; ---Purpose: same as CurveConstraint from GeomPlate -- with BRepAdaptor_Surface instead of diff --git a/src/BRepFill/BRepFill_Draft.cxx b/src/BRepFill/BRepFill_Draft.cxx index e8b7887afb..1607747a30 100644 --- a/src/BRepFill/BRepFill_Draft.cxx +++ b/src/BRepFill/BRepFill_Draft.cxx @@ -14,11 +14,13 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. + #include #include #include #include +#include #include #include @@ -519,7 +521,9 @@ static Standard_Boolean GoodOrientation(const Bnd_Box& B, BRepFill_Sweep Sweep(mySec, myLoc, Standard_True); Sweep.SetTolerance(myTol); Sweep.SetAngularControl(angmin, angmax); - Sweep.Build(myStyle, myCont); + TopTools_MapOfShape Dummy; + BRepFill_DataMapOfShapeHArray2OfShape Dummy2; + Sweep.Build(Dummy, Dummy2, myStyle, myCont); if (Sweep.IsDone()) { myShape = Sweep.Shape(); myShell = TopoDS::Shell(myShape); diff --git a/src/BRepFill/BRepFill_Evolved.cxx b/src/BRepFill/BRepFill_Evolved.cxx index 9dad6d397c..5699d256e1 100644 --- a/src/BRepFill/BRepFill_Evolved.cxx +++ b/src/BRepFill/BRepFill_Evolved.cxx @@ -14,6 +14,7 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. + #include @@ -2220,8 +2221,8 @@ void BRepFill_Evolved::MakePipe(const TopoDS_Edge& SE, } #endif -// BRepFill_Pipe Pipe(BRepLib_MakeWire(SE),GenProf); - BRepFill_Pipe Pipe = BRepFill_Pipe(BRepLib_MakeWire(SE),GenProf); + BRepFill_Pipe Pipe(BRepLib_MakeWire(SE), GenProf); + //BRepFill_Pipe Pipe = BRepFill_Pipe(BRepLib_MakeWire(SE),GenProf); #ifdef DRAW if (AffichGeom) { diff --git a/src/BRepFill/BRepFill_LocationLaw.cxx b/src/BRepFill/BRepFill_LocationLaw.cxx index c86fec3c79..35352f577d 100644 --- a/src/BRepFill/BRepFill_LocationLaw.cxx +++ b/src/BRepFill/BRepFill_LocationLaw.cxx @@ -14,6 +14,7 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. + #include #include @@ -36,6 +37,7 @@ #include #include #include +#include //======================================================================= @@ -608,8 +610,10 @@ void BRepFill_LocationLaw::CurvilinearBounds(const Standard_Integer Index, M(2,1), M(2,2), M(2,3), V.Y(), M(3,1), M(3,2), M(3,3), V.Z(), 1.e-12, 1.e-14); - TopLoc_Location Loc(fila); - W.Location(Loc.Multiplied(W.Location())); + //TopLoc_Location Loc(fila); + //W.Location(Loc.Multiplied(W.Location())); + W = BRepBuilderAPI_Transform(W, fila, Standard_True); //copy + /////////////////////////////////////////// } else { W.Nullify(); diff --git a/src/BRepFill/BRepFill_Pipe.cdl b/src/BRepFill/BRepFill_Pipe.cdl index e8319b393c..170f06016f 100644 --- a/src/BRepFill/BRepFill_Pipe.cdl +++ b/src/BRepFill/BRepFill_Pipe.cdl @@ -14,6 +14,7 @@ -- Alternatively, this file may be used under the terms of Open CASCADE -- commercial license or contractual agreement. + class Pipe from BRepFill ---Purpose: Create a shape by sweeping a shape (the profile) @@ -26,6 +27,8 @@ class Pipe from BRepFill uses HArray2OfShape from TopTools, + MapOfShape from TopTools, + DataMapOfShapeHArray2OfShape from BRepFill, LocationLaw from BRepFill, Shape from TopoDS, Face from TopoDS, @@ -108,7 +111,7 @@ is is static; - PipeLine(me; Point : Pnt from gp) + PipeLine(me : in out; Point : Pnt from gp) ---Purpose: Create a Wire by sweeping the Point along the returns Wire from TopoDS raises @@ -145,6 +148,10 @@ is DefineRealSegmax(me : in out) is static private; + RebuildTopOrBottomFace(me; aFace: Shape from TopoDS; + IsTop: Boolean from Standard) + is static private; + ShareFaces(me: in out; theShape: Shape from TopoDS; theInitialFacesLen: Integer; theInitialEdgesLen: Integer; @@ -164,7 +171,10 @@ fields myLoc : LocationLaw from BRepFill; mySections: HArray2OfShape from TopTools; myFaces : HArray2OfShape from TopTools; - myEdges : HArray2OfShape from TopTools; + myEdges : HArray2OfShape from TopTools; + myReversedEdges : MapOfShape from TopTools; + myTapes : DataMapOfShapeHArray2OfShape from BRepFill; + myCurIndexOfSectionEdge : Integer from Standard; myFirst : Shape from TopoDS; myLast : Shape from TopoDS; diff --git a/src/BRepFill/BRepFill_Pipe.cxx b/src/BRepFill/BRepFill_Pipe.cxx index 5c4f57944d..034fcf247a 100644 --- a/src/BRepFill/BRepFill_Pipe.cxx +++ b/src/BRepFill/BRepFill_Pipe.cxx @@ -52,12 +52,65 @@ #include #include #include +#include +#include +#include + +#include +#include +#include #ifdef DRAW #include static Standard_Boolean Affich = 0; #endif + +static void UpdateTolFromTopOrBottomPCurve(const TopoDS_Face& aFace, + TopoDS_Edge& anEdge) +{ + Standard_Real fpar, lpar; + Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(anEdge, aFace, fpar, lpar); + if (aPCurve.IsNull()) + return; + + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar); + if (aCurve.IsNull()) + return; + + Handle(Geom2dAdaptor_HCurve) GAHC2d = new Geom2dAdaptor_HCurve(aPCurve, fpar, lpar); + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); + Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(aSurf); + Adaptor3d_CurveOnSurface ConS(GAHC2d, GAHS); + + Standard_Real Tol = BRep_Tool::Tolerance(anEdge); + Standard_Real InitTol = Tol; + Standard_Real TolTol = Tol*Tol; + const Standard_Integer NCONTROL = 22; + Standard_Real delta = (lpar - fpar)/NCONTROL; + for (Standard_Integer i = 0; i <= NCONTROL; i++) + { + Standard_Real par = fpar + i*delta; + gp_Pnt pnt = aCurve->Value(par); + gp_Pnt prj = ConS.Value(par); + Standard_Real sqdist = pnt.SquareDistance(prj); + if (sqdist > TolTol) + TolTol = sqdist; + } + Tol = 1.00005 * Sqrt(TolTol); + if (Tol >= InitTol) + { + BRep_Builder BB; + BB.UpdateEdge(anEdge, Tol); + TopoDS_Iterator itv(anEdge); + for (; itv.More(); itv.Next()) + { + TopoDS_Vertex aVertex = TopoDS::Vertex(itv.Value()); + BB.UpdateVertex(aVertex, Tol); + } + } +} + //======================================================================= //function : BRepFill_Pipe //purpose : @@ -70,6 +123,8 @@ BRepFill_Pipe::BRepFill_Pipe() myContinuity = GeomAbs_C2; myMode = GeomFill_IsCorrectedFrenet; myForceApproxC1 = Standard_False; + + myCurIndexOfSectionEdge = 1; } @@ -99,6 +154,9 @@ BRepFill_Pipe::BRepFill_Pipe(const TopoDS_Wire& Spine, myContinuity = GeomAbs_C0; myForceApproxC1 = ForceApproxC1; + + myCurIndexOfSectionEdge = 1; + Perform(Spine, Profile, KPart); } @@ -175,7 +233,8 @@ void BRepFill_Pipe::Perform(const TopoDS_Wire& Spine, TopLoc_Location LocFirst(fila); myFirst = myProfile; if ( ! LocFirst.IsIdentity()) { - myFirst.Location( LocFirst.Multiplied(myProfile.Location()) ); + //myFirst.Location( LocFirst.Multiplied(myProfile.Location()) ); + myFirst = BRepBuilderAPI_Transform(myProfile, fila, Standard_True); //copy } myLoc->Law(myLoc->NbLaw())->GetDomain(first, last); @@ -190,7 +249,8 @@ void BRepFill_Pipe::Perform(const TopoDS_Wire& Spine, if (! myLoc->IsClosed() || LocFirst != LocLast) { myLast = myProfile; if ( ! LocLast.IsIdentity()) { - myLast.Location(LocLast.Multiplied(myProfile.Location()) ); + //myLast.Location(LocLast.Multiplied(myProfile.Location()) ); + myLast = BRepBuilderAPI_Transform(myProfile, fila, Standard_True); //copy } } else { @@ -379,7 +439,7 @@ TopoDS_Shape BRepFill_Pipe::Section(const TopoDS_Vertex& VSpine) const //purpose : Construct a wire by sweeping of a point //======================================================================= -TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) const +TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) { // Postioning gp_Pnt P; @@ -393,7 +453,8 @@ TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) const // Sweeping BRepFill_Sweep MkSw(Section, myLoc, Standard_True); MkSw.SetForceApproxC1(myForceApproxC1); - MkSw.Build( BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax ); + MkSw.Build( myReversedEdges, myTapes, + BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax ); TopoDS_Shape aLocalShape = MkSw.Shape(); return TopoDS::Wire(aLocalShape); // return TopoDS::Wire(MkSw.Shape()); @@ -480,7 +541,7 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S, case TopAbs_SOLID : case TopAbs_COMPSOLID : - Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID"); + Standard_DomainError::Raise("BRepFill_Pipe::profile contains solids"); break; case TopAbs_COMPOUND : @@ -519,7 +580,8 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S, new (BRepFill_ShapeLaw) (TopoDS::Vertex(TheS)); BRepFill_Sweep MkSw(Section, myLoc, Standard_True); MkSw.SetForceApproxC1(myForceApproxC1); - MkSw.Build( BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax ); + MkSw.Build( myReversedEdges, myTapes, + BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax ); result = MkSw.Shape(); } @@ -530,7 +592,8 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S, MkSw.SetBounds(TopoDS::Wire(TheFirst), TopoDS::Wire(TheLast)); MkSw.SetForceApproxC1(myForceApproxC1); - MkSw.Build( BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax ); + MkSw.Build( myReversedEdges, myTapes, + BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax ); result = MkSw.Shape(); // Labeling of elements @@ -543,9 +606,6 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S, Handle(TopTools_HArray2OfShape) Aux, Somme; Standard_Integer length; Standard_Integer ii, jj, kk; - const Standard_Integer aNbFaces = myFaces->ColLength(); - const Standard_Integer aNbEdges = myEdges->ColLength(); - const Standard_Integer aNbSections = mySections->ColLength(); Aux = MkSw.SubShape(); length = Aux->ColLength() + myFaces->ColLength(); @@ -568,7 +628,9 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S, for (jj=1; jj<=mySections->RowLength(); jj++) { for (ii=1; ii<=mySections->ColLength(); ii++) Somme->SetValue(ii, jj, mySections->Value(ii, jj)); - + + myCurIndexOfSectionEdge = mySections->ColLength()+1; + for (kk=1, ii=mySections->ColLength()+1; kk <=Aux->ColLength(); kk++, ii++) Somme->SetValue(ii, jj, Aux->Value(kk, jj)); @@ -589,15 +651,20 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S, } myEdges = Somme; - - // Perform sharing faces - result = ShareFaces(result, aNbFaces, aNbEdges, aNbSections); } } } if ( TheS.ShapeType() == TopAbs_FACE ) { Standard_Integer ii, jj; + //jgv + TopExp_Explorer Explo(result, TopAbs_FACE); + for (; Explo.More(); Explo.Next()) + { + TopoDS_Shape aFace = Explo.Current(); + RebuildTopOrBottomFace(aFace.Reversed(), Standard_True); //top face was reversed + } + ///// TopoDS_Face F; for (ii=InitialLength+1; ii<=myFaces->ColLength(); ii++) { for (jj=1; jj<=myFaces->RowLength(); jj++) { @@ -609,6 +676,10 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S, if ( !mySpine.Closed()) { // if Spine is not closed // add the last face of the solid + + //jgv + RebuildTopOrBottomFace(TheLast, Standard_False); //bottom face + ///// B.Add(result, TopoDS::Face(TheLast)); } @@ -805,280 +876,46 @@ void BRepFill_Pipe::DefineRealSegmax() } //======================================================================= -//function : ShareFaces -//purpose : +//function : RebuildTopOrBottomFace +//purpose : Correct orientation of v-iso edges +// according to new 3d and 2d curves taken from swept surfaces //======================================================================= -TopoDS_Shape BRepFill_Pipe::ShareFaces - (const TopoDS_Shape &theShape, - const Standard_Integer theInitialFacesLen, - const Standard_Integer theInitialEdgesLen, - const Standard_Integer theInitialSectionsLen) +void BRepFill_Pipe::RebuildTopOrBottomFace(const TopoDS_Shape& aFace, + const Standard_Boolean IsTop) const { - TopoDS_Shape aResult = theShape; - // Check if there are shapes to be shared. - TopTools_DataMapOfShapeInteger aMapBndEdgeIndex; - TColStd_DataMapOfIntegerInteger aMapNewOldFIndex; - TColStd_DataMapOfIntegerInteger aMapNewOldEIndex; - TopTools_MapOfShape aMapUsedVtx; - TopExp_Explorer anExp; - Standard_Integer i; + Standard_Integer IndexOfSection = + (IsTop)? 1 : mySections->RowLength(); + Standard_Integer ii; - Standard_Integer jj; - BRep_Builder aBuilder; - - // Check the first and last J index of myFaces. - for (i = 1; i <= 2; i++) { - // Compute jj index of faces. - if (i == 1) { - jj = 1; - } else { - jj = myFaces->RowLength(); - - if (jj == 1) { - break; - } - } - - // Fill the map of boundary edges on initial faces. - for (ii = 1; ii <= theInitialFacesLen; ii++) { - anExp.Init(myFaces->Value(ii, jj), TopAbs_EDGE); - - for (; anExp.More(); anExp.Next()) { - aMapBndEdgeIndex.Bind(anExp.Current(), ii); - } - } - - // Check if edges of newly created faces are shared with old ones. - for (ii = theInitialFacesLen + 1; ii <= myFaces->ColLength(); ii++) { - anExp.Init(myFaces->Value(ii, jj), TopAbs_EDGE); - - for (; anExp.More(); anExp.Next()) { - if (aMapBndEdgeIndex.IsBound(anExp.Current())) { - // This row should be replaced. - Standard_Integer anOldIndex = aMapBndEdgeIndex.Find(anExp.Current()); - - aMapNewOldFIndex.Bind(ii, anOldIndex); - - // Find corresponding new and old edges indices. - TopoDS_Vertex aV[2]; - TopExp::Vertices(TopoDS::Edge(anExp.Current()), aV[0], aV[1]); - Standard_Integer ie; - - // Compute jj index of edges. - Standard_Integer je = (i == 1 ? 1 : myEdges->RowLength()); - - for (Standard_Integer j = 0; j < 2; j++) { - if (aMapUsedVtx.Contains(aV[j])) { - // This vertex is treated. - continue; - } - - // Find old index. - Standard_Integer iEOld = -1; - TopoDS_Vertex aVE[2]; - - for (ie = 1; ie <= theInitialEdgesLen; ie++) { - const TopoDS_Shape &anEdge = myEdges->Value(ie, je); - - TopExp::Vertices(TopoDS::Edge(anEdge), aVE[0], aVE[1]); - - if (aV[j].IsSame(aVE[0]) || aV[j].IsSame(aVE[1])) { - iEOld = ie; - break; - } - } - - if (iEOld > 0) { - // Find new index. - for (ie = theInitialEdgesLen+1; ie <= myEdges->ColLength(); ie++) { - const TopoDS_Shape &anEdge = myEdges->Value(ie, je); - - TopExp::Vertices(TopoDS::Edge(anEdge), aVE[0], aVE[1]); - - if (aV[j].IsSame(aVE[0]) || aV[j].IsSame(aVE[1])) { - // This row should be replaced. - aMapNewOldEIndex.Bind(ie, iEOld); - aMapUsedVtx.Add(aV[j]); - break; - } - } - } - } - + BRep_Builder BB; + TopoDS_Iterator itf(aFace); + for (; itf.More(); itf.Next()) + { + TopoDS_Shape aWire = itf.Value(); + TopTools_SequenceOfShape InitEdges; + TopTools_SequenceOfShape ResEdges; + TopoDS_Iterator itw(aWire); + for (; itw.More(); itw.Next()) + { + TopoDS_Shape anEdge = itw.Value(); + for (ii = myCurIndexOfSectionEdge; ii <= mySections->ColLength(); ii++) + { + TopoDS_Shape aVisoEdge = mySections->Value(ii, IndexOfSection); + if (anEdge.IsSame(aVisoEdge)) + { + InitEdges.Append(anEdge); + ResEdges.Append(aVisoEdge); break; } } } - } - - if (!aMapNewOldFIndex.IsEmpty()) { - TColStd_DataMapIteratorOfDataMapOfIntegerInteger anIter(aMapNewOldFIndex); - TopTools_ListOfShape aListShape; - BRepTools_Substitution aSubstitute; - - for (; anIter.More(); anIter.Next()) { - const Standard_Integer aNewIndex = anIter.Key(); - const Standard_Integer anOldIndex = anIter.Value(); - - // Change new faces by old ones. - for (jj = 1; jj <= myFaces->RowLength(); jj++) { - const TopoDS_Shape &aNewFace = myFaces->Value(aNewIndex, jj); - const TopoDS_Shape &anOldFace = myFaces->Value(anOldIndex, jj); - - if (!aSubstitute.IsCopied(aNewFace)) { - aListShape.Append(anOldFace.Oriented(TopAbs_REVERSED)); - aSubstitute.Substitute(aNewFace, aListShape); - aListShape.Clear(); - } - } - } - - // Change new edges by old ones. - for (anIter.Initialize(aMapNewOldEIndex); anIter.More(); anIter.Next()) { - const Standard_Integer aNewIndex = anIter.Key(); - const Standard_Integer anOldIndex = anIter.Value(); - - for (jj = 1; jj <= myEdges->RowLength(); jj++) { - const TopoDS_Shape &aNewEdge = myEdges->Value(aNewIndex, jj); - const TopoDS_Shape &anOldEdge = myEdges->Value(anOldIndex, jj); - - if (!aSubstitute.IsCopied(aNewEdge)) { - aListShape.Append(anOldEdge.Oriented(TopAbs_FORWARD)); - aSubstitute.Substitute(aNewEdge, aListShape); - aListShape.Clear(); - - // Change new vertices by old ones. - TopoDS_Iterator aNewIt(aNewEdge); - TopoDS_Iterator anOldIt(anOldEdge); - - for (; aNewIt.More() && anOldIt.More(); - aNewIt.Next(), anOldIt.Next()) { - if (!aNewIt.Value().IsSame(anOldIt.Value())) { - if (!aSubstitute.IsCopied(aNewIt.Value())) { - aListShape.Append(anOldIt.Value().Oriented(TopAbs_FORWARD)); - aSubstitute.Substitute(aNewIt.Value(), aListShape); - aListShape.Clear(); - } - } - } - } - } - } - - // Perform substitution. - aSubstitute.Build(aResult); - - if (aSubstitute.IsCopied(aResult)) { - // Get copied shape. - const TopTools_ListOfShape& listSh = aSubstitute.Copy(aResult); - - aResult = listSh.First(); - - // Update original faces with copied ones. - for (ii = theInitialFacesLen + 1; ii <= myFaces->ColLength(); ii++) { - for (jj = 1; jj <= myFaces->RowLength(); jj++) { - TopoDS_Shape anOldFace = myFaces->Value(ii, jj); // Copy - - if (aSubstitute.IsCopied(anOldFace)) { - const TopTools_ListOfShape& aList = aSubstitute.Copy(anOldFace); - - if(!aList.IsEmpty()) { - // Store copied face. - const TopoDS_Shape &aCopyFace = aList.First(); - TopAbs_Orientation anOri = anOldFace.Orientation(); - const Standard_Boolean isShared = aMapNewOldFIndex.IsBound(ii); - - if (isShared) { - // Reverse the orientation for shared face. - anOri = TopAbs::Reverse(anOri); - } - - myFaces->SetValue(ii, jj, aCopyFace.Oriented(anOri)); - - // Check if it is necessary to update PCurves on this face. - if (!isShared) { - TopoDS_Face anOldF = TopoDS::Face(anOldFace); - TopoDS_Face aCopyF = TopoDS::Face(aCopyFace); - - anOldF.Orientation(TopAbs_FORWARD); - anExp.Init(anOldF, TopAbs_EDGE); - - for (; anExp.More(); anExp.Next()) { - const TopoDS_Shape &anOldEdge = anExp.Current(); - - if (aSubstitute.IsCopied(anOldEdge)) { - const TopTools_ListOfShape& aListE = - aSubstitute.Copy(anOldEdge); - - if(!aListE.IsEmpty()) { - // This edge is copied. Check if there is a PCurve - // on the face. - TopoDS_Edge aCopyE = TopoDS::Edge(aListE.First()); - Standard_Real aFirst; - Standard_Real aLast; - Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface - (aCopyE, aCopyF, aFirst, aLast); - - if (aPCurve.IsNull()) { - // There is no pcurve copy it from the old edge. - TopoDS_Edge anOldE = TopoDS::Edge(anOldEdge); - - aPCurve = BRep_Tool::CurveOnSurface - (anOldE, anOldF, aFirst, aLast); - - if (aPCurve.IsNull() == Standard_False) { - // Update the shared edge with PCurve from new Face. - Standard_Real aTol = Max(BRep_Tool::Tolerance(anOldE), - BRep_Tool::Tolerance(aCopyE)); - - aBuilder.UpdateEdge(aCopyE, aPCurve, aCopyF, aTol); - } - } - } - } - } - } - } - } - } - } - - // Update new edges with shared ones. - for (ii = theInitialEdgesLen + 1; ii <= myEdges->ColLength(); ii++) { - for (jj = 1; jj <= myEdges->RowLength(); jj++) { - const TopoDS_Shape &aLocalShape = myEdges->Value(ii, jj); - - if (aSubstitute.IsCopied(aLocalShape)) { - const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape); - - if(!aList.IsEmpty()) { - const TopAbs_Orientation anOri = TopAbs_FORWARD; - - myEdges->SetValue(ii, jj, aList.First().Oriented(anOri)); - } - } - } - } - - // Update new sections with shared ones. - for (ii = theInitialSectionsLen+1; ii <= mySections->ColLength(); ii++) { - for (jj = 1; jj <= mySections->RowLength(); jj++) { - const TopoDS_Shape &aLocalShape = mySections->Value(ii, jj); - - if (aSubstitute.IsCopied(aLocalShape)) { - const TopTools_ListOfShape& aList = aSubstitute.Copy(aLocalShape); - - if(!aList.IsEmpty()) { - const TopAbs_Orientation anOri = TopAbs_FORWARD; - - mySections->SetValue(ii, jj, aList.First().Oriented(anOri)); - } - } - } - } + aWire.Free(Standard_True); + for (ii = 1; ii <= InitEdges.Length(); ii++) + { + BB.Remove(aWire, InitEdges(ii)); + UpdateTolFromTopOrBottomPCurve(TopoDS::Face(aFace), TopoDS::Edge(ResEdges(ii))); + BB.Add(aWire, ResEdges(ii)); } } - - return aResult; } diff --git a/src/BRepFill/BRepFill_PipeShell.cxx b/src/BRepFill/BRepFill_PipeShell.cxx index 3b48a9c153..19a8501903 100644 --- a/src/BRepFill/BRepFill_PipeShell.cxx +++ b/src/BRepFill/BRepFill_PipeShell.cxx @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -69,6 +70,7 @@ #include #include +#include #include #include @@ -738,7 +740,9 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1) GeomAbs_Shape theContinuity = GeomAbs_C2; if (myTrihedron == GeomFill_IsDiscreteTrihedron) theContinuity = GeomAbs_C0; - MkSw.Build(myTransition, theContinuity); + TopTools_MapOfShape Dummy; + BRepFill_DataMapOfShapeHArray2OfShape Dummy2; + MkSw.Build(Dummy, Dummy2, myTransition, theContinuity); myStatus = myLocation->GetStatus(); Ok = (MkSw.IsDone() && (myStatus == GeomFill_PipeOk)); @@ -1118,11 +1122,14 @@ void BRepFill_PipeShell::Place(const BRepFill_Section& Sec, Sec.Vertex(), Sec.WithContact(), Sec.WithCorrection()); - W = Sec.Wire(); + TopoDS_Wire TmpWire = Sec.Wire(); aTrsf = Place.Transformation(); - TopLoc_Location Loc2(Place.Transformation()), Loc1; - Loc1 = W.Location(); - W.Location(Loc2.Multiplied(Loc1)); + //TopLoc_Location Loc2(Place.Transformation()), Loc1; + //Loc1 = TmpWire.Location(); + //W.Location(Loc2.Multiplied(Loc1)); + //Transform the copy + W = TopoDS::Wire(BRepBuilderAPI_Transform(TmpWire, aTrsf, Standard_True)); + //////////////////////////////////// param = Place.AbscissaOnPath(); } diff --git a/src/BRepFill/BRepFill_ShapeLaw.cxx b/src/BRepFill/BRepFill_ShapeLaw.cxx index b4ae7dcd12..1b964a4809 100644 --- a/src/BRepFill/BRepFill_ShapeLaw.cxx +++ b/src/BRepFill/BRepFill_ShapeLaw.cxx @@ -37,8 +37,8 @@ #include #include - #include +#include //======================================================================= @@ -264,8 +264,9 @@ void BRepFill_ShapeLaw::Init(const Standard_Boolean Build) if (!TheLaw.IsNull()) { gp_Trsf T; T.SetScale(gp_Pnt(0, 0, 0), TheLaw->Value(Param)); - TopLoc_Location L(T); - V.Move(L); + //TopLoc_Location L(T); + //V.Move(L); + V = TopoDS::Vertex(BRepBuilderAPI_Transform(V, T)); } return V; } @@ -396,10 +397,10 @@ void BRepFill_ShapeLaw::Init(const Standard_Boolean Build) const Standard_Real TolAngular) const { - TopoDS_Edge Edge1, Edge2; + TopoDS_Edge Edge1, Edge2; if ( (Index==0) || (Index==myEdges->Length()) ) { if (!uclosed) return GeomAbs_C0; //The least possible error - + Edge1 = TopoDS::Edge (myEdges->Value(myEdges->Length())); Edge2 = TopoDS::Edge (myEdges->Value(1)); } @@ -407,20 +408,19 @@ void BRepFill_ShapeLaw::Init(const Standard_Boolean Build) Edge1 = TopoDS::Edge (myEdges->Value(Index)); Edge2 = TopoDS::Edge (myEdges->Value(Index+1)); } - - TopoDS_Vertex V1,V2; - if ( Edge1.Orientation() == TopAbs_REVERSED) { - V1 = TopExp::FirstVertex(Edge1); - } - else { - V1 = TopExp::LastVertex(Edge1); - } - if ( Edge2.Orientation() == TopAbs_REVERSED) { - V2 = TopExp::LastVertex(Edge2); - } - else { - V2 = TopExp::FirstVertex(Edge2); - } + + TopoDS_Vertex V1,V2; //common vertex + TopoDS_Vertex vv1, vv2, vv3, vv4; + TopExp::Vertices(Edge1, vv1, vv2); + TopExp::Vertices(Edge2, vv3, vv4); + if (vv1.IsSame(vv3)) + { V1 = vv1; V2 = vv3; } + else if (vv1.IsSame(vv4)) + { V1 = vv1; V2 = vv4; } + else if (vv2.IsSame(vv3)) + { V1 = vv2; V2 = vv3; } + else + { V1 = vv2; V2 = vv4; } Standard_Real U1 = BRep_Tool::Parameter(V1,Edge1); Standard_Real U2 = BRep_Tool::Parameter(V2,Edge2); @@ -444,7 +444,8 @@ void BRepFill_ShapeLaw::Init(const Standard_Boolean Build) if (!TheLaw.IsNull()) { gp_Trsf T; T.SetScale(gp_Pnt(0, 0, 0), TheLaw->Value(U)); - TopLoc_Location L(T); - S.Move(L); + //TopLoc_Location L(T); + //S.Move(L); + S = BRepBuilderAPI_Transform(S, T); } } diff --git a/src/BRepFill/BRepFill_Sweep.cdl b/src/BRepFill/BRepFill_Sweep.cdl index a38e957c04..f5ece71bef 100644 --- a/src/BRepFill/BRepFill_Sweep.cdl +++ b/src/BRepFill/BRepFill_Sweep.cdl @@ -14,6 +14,7 @@ -- Alternatively, this file may be used under the terms of Open CASCADE -- commercial license or contractual agreement. + class Sweep from BRepFill ---Purpose: Topological Sweep Algorithm @@ -28,8 +29,11 @@ uses Shape from GeomAbs, HArray2OfShape from TopTools, ListOfShape from TopTools, - DataMapOfShapeShape from TopTools, + DataMapOfShapeShape from TopTools, + MapOfShape from TopTools, + DataMapOfShapeHArray2OfShape from BRepFill, Wire from TopoDS, + Edge from TopoDS, Shape from TopoDS, Trsf from gp @@ -81,7 +85,9 @@ is -- to be C0. - Build(me : in out; + Build(me : in out; + ReversedEdges : in out MapOfShape from TopTools; + Tapes : in out DataMapOfShapeHArray2OfShape from BRepFill; Transition : TransitionStyle = BRepFill_Modified; Continuity : Shape from GeomAbs = GeomAbs_C2; Approx : ApproxStyle = GeomFill_Location; @@ -112,7 +118,9 @@ is BuildShell(me : in out; Transition : TransitionStyle; - Vf, Vl : Integer; + Vf, Vl : Integer; + ReversedEdges : in out MapOfShape from TopTools; + Tapes : in out DataMapOfShapeHArray2OfShape from BRepFill; ExtendFirst : Real = 0.0; ExtendLast : Real = 0.0) returns Boolean is private; @@ -158,6 +166,11 @@ is V : in out Shape from TopoDS) is private; + RebuildTopOrBottomEdge(me; aNewEdge: Edge from TopoDS; + anEdge: in out Edge from TopoDS; + ReversedEdges: in out MapOfShape from TopTools) + is private; + fields isDone : Boolean; KPart : Boolean; diff --git a/src/BRepFill/BRepFill_Sweep.cxx b/src/BRepFill/BRepFill_Sweep.cxx index b16ba2c440..09907ffc48 100644 --- a/src/BRepFill/BRepFill_Sweep.cxx +++ b/src/BRepFill/BRepFill_Sweep.cxx @@ -91,6 +91,7 @@ #include #include #include +#include #include #include @@ -99,6 +100,7 @@ #include #include #include +#include #include #include @@ -1935,6 +1937,8 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, BuildShell(const BRepFill_TransitionStyle /*Transition*/, const Standard_Integer IFirst, const Standard_Integer ILast, + TopTools_MapOfShape& ReversedEdges, + BRepFill_DataMapOfShapeHArray2OfShape& Tapes, const Standard_Real ExtendFirst, const Standard_Real ExtendLast) { @@ -2062,8 +2066,31 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, Standard_Boolean exuv, singu, singv; Handle(Geom_Surface) S; + // Preprocessing: correct if the profile is shell + if (!ReversedEdges.IsEmpty()) + { + TopTools_SequenceOfShape EdgesToReverse; + TopoDS_Iterator itw(FirstShape); + for (; itw.More(); itw.Next()) + { + const TopoDS_Shape& anEdge = itw.Value(); + if (ReversedEdges.Contains(anEdge)) + EdgesToReverse.Append(anEdge); + } + FirstShape.Free(Standard_True); + for (Standard_Integer i = 1; i <= EdgesToReverse.Length(); i++) + { + B.Remove(FirstShape, EdgesToReverse(i)); + EdgesToReverse(i).Reverse(); + B.Add(FirstShape, EdgesToReverse(i)); + } + } + // (2.0) return preexisting Edges and vertices TopoDS_Edge E; + TColStd_Array1OfBoolean IsBuilt(1, NbLaw); + IsBuilt.Init(Standard_False); + TopTools_Array1OfShape StartEdges(1, NbLaw); if (! FirstShape.IsNull() && (IFirst==1)) { mySec->Init(FirstShape); for (isec=1; isec<=NbLaw; isec++) { @@ -2075,7 +2102,53 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, Vertex(isec+1, 1) = TopExp::LastVertex(E); UpdateVertex(IFirst-1, isec+1, TabErr(isec, 1), Vi(1), Vertex(isec+1, 1)); + + StartEdges(isec) = E; + if (Tapes.IsBound(E)) + { + IsBuilt(isec) = Standard_True; + + //Initialize VEdge, UEdge, Vertex and myFaces + Standard_Integer j; + for (j = 1; j <= NbPath+1; j++) + { + VEdge(isec, j) = Tapes(E)->Value(1, j); + VEdge(isec, j).Reverse(); //direction of round is reversed + } + Standard_Integer ifirst = isec+1, ilast = isec; //direction of round is reversed + for (j = 1; j <= NbPath; j++) + UEdge(ifirst, j) = Tapes(E)->Value(2, j); + for (j = 1; j <= NbPath; j++) + UEdge(ilast, j) = Tapes(E)->Value(3, j); + for (j = 1; j <= NbPath+1; j++) + Vertex(ifirst, j) = Tapes(E)->Value(4, j); + for (j = 1; j <= NbPath+1; j++) + Vertex(ilast, j) = Tapes(E)->Value(5, j); + for (j = 1; j <= NbPath; j++) + myFaces->SetValue(isec, j, Tapes(E)->Value(6, j)); + + if (uclose && isec == 1) + { + for (j = 1; j <= NbPath; j++) + UEdge(NbLaw+1, j) = UEdge(1, j); + for (j = 1; j <= NbPath+1; j++) + Vertex(NbLaw+1, j) = Vertex(1, j); + } + if (uclose && isec == NbLaw) + { + for (j = 1; j <= NbPath; j++) + UEdge(1, j) = UEdge(NbLaw+1, j); + for (j = 1; j <= NbPath+1; j++) + Vertex(1, j) = Vertex(NbLaw+1, j); + } + } + else + { + Handle(TopTools_HArray2OfShape) EmptyArray = new TopTools_HArray2OfShape(1, 6, 1, NbPath+1); + Tapes.Bind(E, EmptyArray); + } } + if (VEdge(1, 1).Orientation() == TopAbs_REVERSED) Vertex(1, 1) = TopExp::LastVertex(TopoDS::Edge(VEdge(1, 1))); else @@ -2083,128 +2156,152 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, UpdateVertex(IFirst-1, 1, TabErr(1, 1), Vi(1), Vertex(1, 1)); } - else { // Otherwise construct vertices - Standard_Real u, v, aux; - Standard_Boolean ureverse; - for (isec=1; isec<=NbLaw+1; isec++) { - // Return data - if (isec >NbLaw) { - S = TabS(NbLaw, 1); - ureverse = UReverse(NbLaw, 1); - exuv = ExchUV(NbLaw, 1); + + Standard_Real u, v, aux; + Standard_Boolean ureverse; + for (isec=1; isec<=NbLaw+1; isec++) { + // Return data + if (isec >NbLaw) { + S = TabS(NbLaw, 1); + ureverse = UReverse(NbLaw, 1); + exuv = ExchUV(NbLaw, 1); + } + else { + S = TabS(isec, 1); + ureverse = UReverse(isec, 1); + exuv = ExchUV(isec, 1); + } + S->Bounds(UFirst, ULast, VFirst, VLast); + + // Choice of parameters + if (ureverse) { + if (exuv) { + aux = VFirst; VFirst = VLast; VLast = aux; } else { - S = TabS(isec, 1); - ureverse = UReverse(isec, 1); - exuv = ExchUV(isec, 1); + aux = UFirst; UFirst = ULast; ULast = aux; } - S->Bounds(UFirst, ULast, VFirst, VLast); - - // Choice of parameters - if (ureverse) { - if (exuv) { - aux = VFirst; VFirst = VLast; VLast = aux; - } - else { - aux = UFirst; UFirst = ULast; ULast = aux; - } - } - if (isec!= NbLaw+1) { + } + if (isec!= NbLaw+1) { + u = UFirst; + v = VFirst; + } + else { + if (exuv) { u = UFirst; + v = VLast; + } + else { + u = ULast; v = VFirst; } - else { - if (exuv) { - u = UFirst; - v = VLast; - } - else { - u = ULast; - v = VFirst; - } - } - - // construction of vertices + } + + // construction of vertices + if (Vertex(isec, 1).IsNull()) B.MakeVertex(TopoDS::Vertex(Vertex(isec, 1)), S->Value(u,v), mySec->VertexTol(isec-1,Vi(1))); + else + { + TopLoc_Location Identity; + Vertex(isec, 1).Location(Identity); + B.UpdateVertex(TopoDS::Vertex(Vertex(isec, 1)), + S->Value(u,v), + mySec->VertexTol(isec-1,Vi(1))); } - } - + } //end of for (isec=1; isec<=NbLaw+1; isec++) + if (! LastShape.IsNull() && (ILast==myLoc->NbLaw()+1) ) { mySec->Init(LastShape); for (isec=1; isec<=NbLaw; isec++) { E = mySec->CurrentEdge(); - VEdge(isec, NbPath+1) = E; - if (E.Orientation() == TopAbs_REVERSED) - Vertex(isec+1, NbPath+1) = TopExp::FirstVertex(E); - else - Vertex(isec+1, NbPath+1) = TopExp::LastVertex(E); + if (VEdge(isec, NbPath+1).IsNull()) + VEdge(isec, NbPath+1) = E; + + if (Vertex(isec+1, NbPath+1).IsNull()) + { + if (VEdge(isec, NbPath+1).Orientation() == TopAbs_REVERSED) + Vertex(isec+1, NbPath+1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(isec, NbPath+1))); + else + Vertex(isec+1, NbPath+1) = TopExp::LastVertex(TopoDS::Edge(VEdge(isec, NbPath+1))); + } UpdateVertex(ILast-1, isec+1, TabErr(isec, NbPath), Vi(NbPath+1), Vertex(isec+1, NbPath+1)); } - if (VEdge(1, NbPath+1).Orientation() == TopAbs_REVERSED) - Vertex(1, NbPath+1) = - TopExp::LastVertex(TopoDS::Edge(VEdge(1, NbPath+1))); - else - Vertex(1, NbPath+1) = - TopExp::FirstVertex(TopoDS::Edge(VEdge(1, NbPath+1))); + + if (Vertex(1, NbPath+1).IsNull()) + { + if (VEdge(1, NbPath+1).Orientation() == TopAbs_REVERSED) + Vertex(1, NbPath+1) = TopExp::LastVertex(TopoDS::Edge(VEdge(1, NbPath+1))); + else + Vertex(1, NbPath+1) = TopExp::FirstVertex(TopoDS::Edge(VEdge(1, NbPath+1))); + } UpdateVertex(ILast-1, 1, TabErr(1, NbPath), Vi(NbPath+1), Vertex(1, NbPath+1 )); - } - else { - Standard_Real u, v, aux; - Standard_Boolean ureverse; - for (isec=1; isec<=NbLaw+1; isec++) { - // Return data - if (isec >NbLaw) { + } + + for (isec=1; isec<=NbLaw+1; isec++) { + // Return data + if (isec >NbLaw) { S = TabS(NbLaw, NbPath); ureverse = UReverse(NbLaw, NbPath); exuv = ExchUV(NbLaw, NbPath); + } + else { + S = TabS(isec, NbPath); + ureverse = UReverse(isec, NbPath); + exuv = ExchUV(isec, NbPath); + } + S->Bounds(UFirst, ULast, VFirst, VLast); + + // Choice of parametres + if (ureverse) { + if (exuv) { + aux = VFirst; VFirst = VLast; VLast = aux; } else { - S = TabS(isec, NbPath); - ureverse = UReverse(isec, NbPath); - exuv = ExchUV(isec, NbPath); + aux = UFirst; UFirst = ULast; ULast = aux; } - S->Bounds(UFirst, ULast, VFirst, VLast); - - // Choice of parametres - if (ureverse) { - if (exuv) { - aux = VFirst; VFirst = VLast; VLast = aux; - } - else { - aux = UFirst; UFirst = ULast; ULast = aux; - } - } - if (isec == NbLaw+1) { + } + if (isec == NbLaw+1) { + u = ULast; + v = VLast; + } + else { + if (exuv) { u = ULast; + v = VFirst; + } + else { + u = UFirst; v = VLast; } - else { - if (exuv) { - u = ULast; - v = VFirst; - } - else { - u = UFirst; - v = VLast; - } - } - - // construction of vertex + } + + // construction of vertex + if (Vertex(isec, NbPath+1).IsNull()) B.MakeVertex(TopoDS::Vertex(Vertex(isec, NbPath+1)), S->Value(u,v), mySec->VertexTol(isec-1, Vi(NbPath+1))); - } - } + else + { + TopLoc_Location Identity; + Vertex(isec, NbPath+1).Location(Identity); + B.UpdateVertex(TopoDS::Vertex(Vertex(isec, NbPath+1)), + S->Value(u,v), + mySec->VertexTol(isec-1, Vi(NbPath+1))); + } + } //end of for (isec=1; isec<=NbLaw+1; isec++) // ---------- Creation of Vertex and edge ------------ for (ipath=1, IPath=IFirst; ipath<=NbPath; ipath++, IPath++) { for (isec=1; isec <=NbLaw; isec++) { + if (IsBuilt(isec)) + continue; + S = TabS(isec, ipath); exuv = ExchUV(isec, ipath); S->Bounds(UFirst, ULast, VFirst, VLast); @@ -2272,6 +2369,7 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, TabErr(isec,1) + mySec->VertexTol(isec,Vi(1)), TopoDS::Vertex(Vertex(isec+1, 1)) ); + if (MergeVertex(Vertex(isec,1), Vertex(isec+1,1))) { VEdge(isec, 1) = NullEdge(Vertex(isec, 1)); } @@ -2341,7 +2439,7 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, } // (2.2) Iso-u - if (isec == 1) { + if (isec == 1 && UEdge(1, ipath).IsNull()) { if (!Vertex(1,ipath).IsSame(Vertex(1,ipath+1))) { gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(Vertex(1,ipath))); gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(Vertex(1,ipath+1))); @@ -2362,18 +2460,29 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, UEdge(isec+1, ipath) = UEdge(1, ipath); } else { - UEdge(isec+1, ipath) = BuildEdge(S, !exuv, ULast, - Vertex(isec+1, ipath), - Vertex(isec+1, ipath+1), - myTol3d); + if (UEdge(isec+1, ipath).IsNull()) + UEdge(isec+1, ipath) = BuildEdge(S, !exuv, ULast, + Vertex(isec+1, ipath), + Vertex(isec+1, ipath+1), + myTol3d); + else + UpdateEdge(TopoDS::Edge(UEdge(isec+1, ipath)), S, !exuv, ULast); } // (2.3) Iso-v - if (ipath == 1 && VEdge(isec, ipath).IsNull()) - VEdge(isec, ipath) = BuildEdge(S, exuv, VFirst, - Vertex(isec , 1), - Vertex(isec+1, 1), - myTol3d); + if (ipath == 1) + { + TopoDS_Edge aNewFirstEdge = BuildEdge(S, exuv, VFirst, + Vertex(isec , 1), + Vertex(isec+1, 1), + myTol3d); + if (VEdge(isec, ipath).IsNull()) + VEdge(isec, ipath) = aNewFirstEdge; + else //rebuild first edge + RebuildTopOrBottomEdge(aNewFirstEdge, + TopoDS::Edge(VEdge(isec, ipath)), + ReversedEdges); + } else UpdateEdge(TopoDS::Edge(VEdge(isec, ipath)), S, exuv, VFirst); @@ -2388,9 +2497,22 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, Vertex(isec , ipath+1), Vertex(isec+1, ipath+1), myTol3d); - else UpdateEdge(TopoDS::Edge(VEdge(isec, ipath+1)), - S, exuv, VLast); - + else + { + if (ipath != NbPath || vclose) + UpdateEdge(TopoDS::Edge(VEdge(isec, ipath+1)), + S, exuv, VLast); + else //ipath == NbPath && !vclose => rebuild last edge + { + TopoDS_Edge aNewLastEdge = BuildEdge(S, exuv, VLast, + Vertex(isec , ipath+1), + Vertex(isec+1, ipath+1), + myTol3d); + RebuildTopOrBottomEdge(aNewLastEdge, + TopoDS::Edge(VEdge(isec, ipath+1)), + ReversedEdges); + } + } } }// End of construction of edges } @@ -2429,7 +2551,7 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, else myFaces->SetValue(isec, IPath, VEdge(isec, ipath)); } - else { + else if (myFaces->Value(isec, IPath).IsNull()) { BuildFace(TabS(isec,ipath), TopoDS::Edge(UEdge(isec, ipath)), TopoDS::Edge(VEdge(isec, ipath)), @@ -2444,6 +2566,12 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, } } + // (3.1) Reverse the faces that have been built ealier + for (ipath = 1; ipath <= NbPath; ipath++) + for (isec = 1; isec <= NbLaw; isec++) + if (IsBuilt(isec)) + myFaces->ChangeValue(isec, ipath).Reverse(); + // (4) History and Continuity @@ -2502,6 +2630,28 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, } } } + + // (5) Update Tapes + Standard_Integer j; + if (IFirst == 1 && !Tapes.IsEmpty()) //works only in case of single shell + { + for (isec = 1; isec <= NbLaw; isec++) + { + for (j = 1; j <= NbPath+1; j++) + Tapes(StartEdges(isec))->SetValue(1, j, myVEdges->Value(isec, j)); + for (j = 1; j <= NbPath; j++) + Tapes(StartEdges(isec))->SetValue(2, j, myUEdges->Value(isec, j)); + for (j = 1; j <= NbPath; j++) + Tapes(StartEdges(isec))->SetValue(3, j, myUEdges->Value(isec+1, j)); + for (j = 1; j <= NbPath+1; j++) + Tapes(StartEdges(isec))->SetValue(4, j, Vertex(isec, j)); + for (j = 1; j <= NbPath+1; j++) + Tapes(StartEdges(isec))->SetValue(5, j, Vertex(isec+1, j)); + for (j = 1; j <= NbPath; j++) + Tapes(StartEdges(isec))->SetValue(6, j, myFaces->Value(isec, j)); + } + } + return Standard_True; } @@ -2509,11 +2659,13 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, //function : Build //purpose : Construt the result of sweeping //====================================================================== - void BRepFill_Sweep::Build(const BRepFill_TransitionStyle Transition, - const GeomAbs_Shape Continuity, - const GeomFill_ApproxStyle Approx, - const Standard_Integer Degmax, - const Standard_Integer Segmax) +void BRepFill_Sweep::Build(TopTools_MapOfShape& ReversedEdges, + BRepFill_DataMapOfShapeHArray2OfShape& Tapes, + const BRepFill_TransitionStyle Transition, + const GeomAbs_Shape Continuity, + const GeomFill_ApproxStyle Approx, + const Standard_Integer Degmax, + const Standard_Integer Segmax) { myContinuity = Continuity; myApproxStyle = Approx; @@ -2550,6 +2702,8 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, if (NbTrous==1) Extend = EvalExtrapol(1, Transition); isDone = BuildShell(Transition, 1, NbPath+1, + ReversedEdges, + Tapes, Extend, Extend); } else { // This is done piece by piece @@ -2560,6 +2714,8 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, else ILast = Trous->Value(ii); isDone = BuildShell(Transition, IFirst, ILast, + ReversedEdges, + Tapes, EvalExtrapol(IFirst, Transition), EvalExtrapol(ILast, Transition)); if (IFirst>1) { @@ -3102,3 +3258,105 @@ void BRepFill_Sweep::UpdateVertex(const Standard_Integer ipath, B.UpdateVertex(TheV, Tol); } } + +//======================================================================= +//function : RebuildTopOrBottomEdge +//purpose : Rebuild v-iso edge of top or bottom section +// inserting new 3d and 2d curves taken from swept surfaces +//====================================================================== +void BRepFill_Sweep::RebuildTopOrBottomEdge(const TopoDS_Edge& aNewEdge, + TopoDS_Edge& anEdge, + TopTools_MapOfShape& ReversedEdges) const +{ + Standard_Real fpar, lpar; + Handle(Geom_Curve) aNewCurve = BRep_Tool::Curve(aNewEdge, fpar, lpar); + TopLoc_Location Identity; + + Standard_Boolean ToReverse = Standard_False; + Standard_Boolean IsDegen = BRep_Tool::Degenerated(aNewEdge); + if (IsDegen) + BRep_Tool::Range(aNewEdge, fpar, lpar); + else + { + TopoDS_Vertex V1, V2, NewV1, NewV2; + TopExp::Vertices(anEdge, V1, V2); + if (!V1.IsSame(V2)) + { + TopExp::Vertices(aNewEdge, NewV1, NewV2); + V1.Location(Identity); + if (!V1.IsSame(NewV1)) + { + if (V1.IsSame(NewV2)) + ToReverse = Standard_True; + else + { + gp_Pnt Pnt1 = BRep_Tool::Pnt(V1); + gp_Pnt NewPnt1 = BRep_Tool::Pnt(NewV1); + Standard_Real TolSum = BRep_Tool::Tolerance(V1) + BRep_Tool::Tolerance(NewV1); + if (!Pnt1.IsEqual(NewPnt1, TolSum)) + ToReverse = Standard_True; + } + } + } + else + { + Standard_Real OldFirst, OldLast; + Handle(Geom_Curve) OldCurve = BRep_Tool::Curve(anEdge, OldFirst, OldLast); + gp_Vec OldD1, NewD1; + gp_Pnt MidPnt; + OldCurve->D1(0.5*(OldFirst + OldLast), MidPnt, OldD1); + aNewCurve->D1(0.5*(fpar + lpar), MidPnt, NewD1); + if (OldD1 * NewD1 < 0.) + ToReverse = Standard_True; + } + } + + anEdge.Location(Identity); + const Handle(BRep_TEdge)& TEdge = *((Handle(BRep_TEdge)*) &anEdge.TShape()); + TEdge->Tolerance(BRep_Tool::Tolerance(aNewEdge)); + BRep_Builder BB; + BB.Range(anEdge, fpar, lpar); + BB.UpdateEdge(anEdge, aNewCurve, Precision::Confusion()); + const Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*) &aNewEdge.TShape()); + const BRep_ListOfCurveRepresentation& lcr = TE->Curves(); + BRep_ListIteratorOfListOfCurveRepresentation itrep(lcr); + for (; itrep.More(); itrep.Next()) + { + const Handle(BRep_CurveRepresentation)& CurveRep = itrep.Value(); + if (CurveRep->IsCurveOnSurface()) + { + const Handle(BRep_GCurve)& GC = *((Handle(BRep_GCurve)*)&CurveRep); + Handle(Geom2d_Curve) aPCurve = GC->PCurve(); + Handle(Geom_Surface) aSurf = GC->Surface(); + TopLoc_Location aLoc = aNewEdge.Location() * GC->Location(); + BB.UpdateEdge(anEdge, aPCurve, aSurf, aLoc, Precision::Confusion()); + } + } + + anEdge.Free(Standard_True); + TopoDS_Vertex V1, V2; + TopExp::Vertices(anEdge, V1, V2); + + TopoDS_Shape anEdgeFORWARD = anEdge.Oriented(TopAbs_FORWARD); + + BB.Remove(anEdgeFORWARD, V1); + BB.Remove(anEdgeFORWARD, V2); + + V1.Location(Identity); + V2.Location(Identity); + if (ToReverse) + { + V2.Orientation(TopAbs_FORWARD); + V1.Orientation(TopAbs_REVERSED); + } + BB.Add(anEdgeFORWARD, V1); + BB.Add(anEdgeFORWARD, V2); + + if (ToReverse) + { + anEdge.Reverse(); + ReversedEdges.Add(anEdge); + } + + BB.Degenerated(anEdge, IsDegen); +} diff --git a/src/BRepTools/BRepTools_TrsfModification.cxx b/src/BRepTools/BRepTools_TrsfModification.cxx index 96aa8e40cc..9535326161 100644 --- a/src/BRepTools/BRepTools_TrsfModification.cxx +++ b/src/BRepTools/BRepTools_TrsfModification.cxx @@ -30,6 +30,7 @@ #include #include +#include //======================================================================= //function : BRepTools_TrsfModification @@ -147,6 +148,9 @@ Standard_Boolean BRepTools_TrsfModification::NewCurve2d Standard_Real scale = myTrsf.ScaleFactor(); Tol *= Abs(scale); const Handle(Geom_Surface)& S = BRep_Tool::Surface(F,loc); + GeomAdaptor_Surface GAsurf(S); + if (GAsurf.GetType() == GeomAbs_Plane) + return Standard_False; Standard_Real f,l; Handle(Geom2d_Curve) NewC = BRep_Tool::CurveOnSurface(E,F,f,l); diff --git a/src/GeomFill/GeomFill_SectionPlacement.cxx b/src/GeomFill/GeomFill_SectionPlacement.cxx index 91f4c103f5..fa41ecbe5a 100644 --- a/src/GeomFill/GeomFill_SectionPlacement.cxx +++ b/src/GeomFill/GeomFill_SectionPlacement.cxx @@ -317,8 +317,8 @@ GeomFill_SectionPlacement(const Handle(GeomFill_LocationLaw)& L, delta = (BC->Knot(i+1) - t) / NbLocalPnts; for (j = 0; j < NbLocalPnts; j++) { - t += delta; Pnts->SetValue( nb++, myAdpSection.Value(t) ); + t += delta; } } if (I3 != I4 && first < BC->Knot(I3)) @@ -327,8 +327,8 @@ GeomFill_SectionPlacement(const Handle(GeomFill_LocationLaw)& L, delta = (last - t) / NbLocalPnts; for (j = 0; j < NbLocalPnts; j++) { - t += delta; Pnts->SetValue( nb++, myAdpSection.Value(t) ); + t += delta; } } if (!myAdpSection.IsClosed()) diff --git a/tests/bugs/modalg_3/bug605 b/tests/bugs/modalg_3/bug605 index d6aa6f1934..91ca571e16 100755 --- a/tests/bugs/modalg_3/bug605 +++ b/tests/bugs/modalg_3/bug605 @@ -6,8 +6,10 @@ puts "" ############################## ## No any faces in result of pipe command. ############################## +pload ALL restore [locate_data_file OCC605a.brep] w1 +settolerance w1 1.e-7 checkshape w1 restore [locate_data_file OCC605b.brep] w2 checkshape w2 diff --git a/tests/bugs/modalg_4/bug13595_1 b/tests/bugs/modalg_4/bug13595_1 index e19f0a378e..f48d6dae98 100755 --- a/tests/bugs/modalg_4/bug13595_1 +++ b/tests/bugs/modalg_4/bug13595_1 @@ -17,15 +17,15 @@ if [catch { pipe result sp p1 } catch_result] { } else { set square 80 -set nb_v_good 4 -set nb_e_good 6 +set nb_v_good 6 +set nb_e_good 7 set nb_w_good 2 set nb_f_good 2 set nb_sh_good 1 set nb_sol_good 0 set nb_compsol_good 0 set nb_compound_good 1 -set nb_shape_good 16 +set nb_shape_good 19 } diff --git a/tests/bugs/modalg_4/bug13595_2 b/tests/bugs/modalg_4/bug13595_2 index 1b68f8102a..1a316e162d 100755 --- a/tests/bugs/modalg_4/bug13595_2 +++ b/tests/bugs/modalg_4/bug13595_2 @@ -16,15 +16,15 @@ if [catch { pipe result sp p2 } catch_result] { } else { set square 407.922 -set nb_v_good 4 -set nb_e_good 6 +set nb_v_good 6 +set nb_e_good 7 set nb_w_good 2 set nb_f_good 2 set nb_sh_good 1 set nb_sol_good 0 set nb_compsol_good 0 set nb_compound_good 1 -set nb_shape_good 16 +set nb_shape_good 19 } diff --git a/tests/bugs/modalg_4/bug629 b/tests/bugs/modalg_4/bug629 deleted file mode 100755 index 79ae742341..0000000000 --- a/tests/bugs/modalg_4/bug629 +++ /dev/null @@ -1,25 +0,0 @@ -puts "TODO OCC12345 ALL: Error : The square of result shape is" -puts "TODO OCC12345 ALL: Faulty shapes in variables faulty_1 to faulty_" - -puts "================" -puts "OCC629" -puts "================" -puts "" -########################################## -## Exception during attempt to create solid by command PIPE -########################################## - -restore [locate_data_file OCC629a.brep] a -checkshape a - -restore [locate_data_file OCC629b.brep] b -checkshape b - -if [catch {pipe result a b } catch_result] { - puts "Faulty OCC629: function PIPE works wrongly" -} else { - puts "OCC629 OK: function PIPE works properly" -} - -set square 0 -set 2dviewer 0 diff --git a/tests/bugs/modalg_5/bug23706_2 b/tests/bugs/modalg_5/bug23706_2 index 10cc9a1f43..e7c594bbfd 100755 --- a/tests/bugs/modalg_5/bug23706_2 +++ b/tests/bugs/modalg_5/bug23706_2 @@ -19,7 +19,7 @@ offset o1 ss 2 mkface res o1 set info [sprops res] regexp {Mass +: +([-0-9.+eE]+)} $info full sq -set sq_check 254.476 +set sq_check 248.667 if { [expr 1.*abs($sq_check - $sq)/$sq_check] > 0.01 } { puts "Error : The square of result shape is $sq" diff --git a/tests/bugs/modalg_5/bug23870_1 b/tests/bugs/modalg_5/bug23870_1 index 9f10cb28e9..8585151870 100755 --- a/tests/bugs/modalg_5/bug23870_1 +++ b/tests/bugs/modalg_5/bug23870_1 @@ -21,14 +21,14 @@ pipe result spine profile 2 approx set square 516.633 -set nb_v_good 4 -set nb_e_good 7 +set nb_v_good 8 +set nb_e_good 10 set nb_w_good 3 set nb_f_good 3 set nb_sh_good 1 set nb_sol_good 0 set nb_compsol_good 0 set nb_compound_good 0 -set nb_shape_good 18 +set nb_shape_good 25 set 2dviewer 1 diff --git a/tests/bugs/modalg_5/bug23870_2 b/tests/bugs/modalg_5/bug23870_2 index 5d29ff6bb5..8e042418b3 100755 --- a/tests/bugs/modalg_5/bug23870_2 +++ b/tests/bugs/modalg_5/bug23870_2 @@ -22,14 +22,14 @@ pipe result spine profile 2 approx set square 8997.97 -set nb_v_good 1 -set nb_e_good 2 +set nb_v_good 2 +set nb_e_good 3 set nb_w_good 1 set nb_f_good 1 set nb_sh_good 1 set nb_sol_good 0 set nb_compsol_good 0 set nb_compound_good 0 -set nb_shape_good 6 +set nb_shape_good 8 set 2dviewer 1 diff --git a/tests/bugs/modalg_5/bug23870_3 b/tests/bugs/modalg_5/bug23870_3 index ee48b92491..4b65af2399 100755 --- a/tests/bugs/modalg_5/bug23870_3 +++ b/tests/bugs/modalg_5/bug23870_3 @@ -18,14 +18,14 @@ pipe result spine profile 2 approx set square 848.989 -set nb_v_good 1 -set nb_e_good 2 +set nb_v_good 2 +set nb_e_good 3 set nb_w_good 1 set nb_f_good 1 set nb_sh_good 1 set nb_sol_good 0 set nb_compsol_good 0 set nb_compound_good 0 -set nb_shape_good 6 +set nb_shape_good 8 set 2dviewer 1 diff --git a/tests/bugs/modalg_5/bug23870_4 b/tests/bugs/modalg_5/bug23870_4 index 32df49f9c4..c0802834d0 100755 --- a/tests/bugs/modalg_5/bug23870_4 +++ b/tests/bugs/modalg_5/bug23870_4 @@ -23,14 +23,14 @@ pipe result spine profile 2 approx set square 38260.5 -set nb_v_good 1 -set nb_e_good 2 +set nb_v_good 2 +set nb_e_good 3 set nb_w_good 1 set nb_f_good 1 set nb_sh_good 1 set nb_sol_good 0 set nb_compsol_good 0 set nb_compound_good 0 -set nb_shape_good 6 +set nb_shape_good 8 set 2dviewer 1 diff --git a/tests/bugs/modalg_5/bug23870_5 b/tests/bugs/modalg_5/bug23870_5 index 8ed112e97c..3542fcb175 100755 --- a/tests/bugs/modalg_5/bug23870_5 +++ b/tests/bugs/modalg_5/bug23870_5 @@ -17,14 +17,14 @@ pipe result spine profile 1 set square 254837 -set nb_v_good 4 -set nb_e_good 8 +set nb_v_good 8 +set nb_e_good 12 set nb_w_good 4 set nb_f_good 4 set nb_sh_good 1 set nb_sol_good 0 set nb_compsol_good 0 set nb_compound_good 0 -set nb_shape_good 21 +set nb_shape_good 29 set 2dviewer 1 diff --git a/tests/bugs/modalg_5/bug24204 b/tests/bugs/modalg_5/bug24204 new file mode 100644 index 0000000000..7e8785a7a4 --- /dev/null +++ b/tests/bugs/modalg_5/bug24204 @@ -0,0 +1,57 @@ +puts "============" +puts "CR24204" +puts "============" +puts "" +################################################################################################################################ +# The algorithm BRepOffsetAPI_MakePipeShell produces resulting shape with unwarrantably big tolerance +################################################################################################################################ + +restore [locate_data_file bug24204_outerWire1.brep] w1 +restore [locate_data_file bug24204_outerWire2.brep] w2 +restore [locate_data_file bug24204_path.brep] sp + +wire w1 w1 +wire w2 w2 +wire sp sp + +mksweep sp +addsweep w1 +addsweep w2 + +buildsweep result + +set log_result [tolmax result] +regexp {max tol = ([-0-9.+eE]+)} ${log_result} full tolmax_result + +set log_w1 [tolmax w1] +regexp {max tol = ([-0-9.+eE]+)} ${log_w1} full tolmax_w1 +set log_w2 [tolmax w2] +regexp {max tol = ([-0-9.+eE]+)} ${log_w2} full tolmax_w2 +set log_sp [tolmax sp] +regexp {max tol = ([-0-9.+eE]+)} ${log_sp} full tolmax_sp + +set tolmax_s ${tolmax_w1} +if { ${tolmax_w2} > ${tolmax_s} } { + set tolmax_s ${tolmax_w2} +} +if { ${tolmax_sp} > ${tolmax_s} } { + set tolmax_s ${tolmax_sp} +} + +if { ${tolmax_result} > [expr 2 * ${tolmax_s}] } { + puts "Error : big tolerance of result" +} + +set square 3.44584 + +set nb_v_good 2 +set nb_e_good 3 +set nb_w_good 1 +set nb_f_good 1 +set nb_sh_good 1 +set nb_sol_good 0 +set nb_compsol_good 0 +set nb_compound_good 0 +set nb_shape_good 8 + +set 3dviewer 1