From: jgv Date: Thu, 24 Jul 2014 09:57:02 +0000 (+0400) Subject: 0025021: New option of BRepOffsetAPI_MakeOffset algorithm: open result for open wire X-Git-Tag: V6_8_0_beta~179 X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=6a442250c4a3d851251eac687fb16dad8acefeee;p=occt-copy.git 0025021: New option of BRepOffsetAPI_MakeOffset algorithm: open result for open wire Test cases for issue CR25021 --- diff --git a/src/BRepFill/BRepFill_OffsetWire.cdl b/src/BRepFill/BRepFill_OffsetWire.cdl index 5cea4f6d36..00bd8e63ac 100644 --- a/src/BRepFill/BRepFill_OffsetWire.cdl +++ b/src/BRepFill/BRepFill_OffsetWire.cdl @@ -39,12 +39,14 @@ is Create returns OffsetWire from BRepFill; Create ( Spine : Face from TopoDS; - Join : JoinType from GeomAbs = GeomAbs_Arc) + Join : JoinType from GeomAbs = GeomAbs_Arc; + IsOpenResult : Boolean from Standard = Standard_False) returns OffsetWire from BRepFill; Init ( me : in out; Spine : Face from TopoDS; - Join : JoinType from GeomAbs = GeomAbs_Arc) + Join : JoinType from GeomAbs = GeomAbs_Arc; + IsOpenResult : Boolean from Standard = Standard_False) ---Purpose: Initialize the evaluation of Offseting. raises ConstructionError from Standard @@ -127,6 +129,7 @@ fields mySpine : Face from TopoDS; myWorkSpine : Face from TopoDS; myOffset : Real from Standard; -- >0 ; + myIsOpenResult : Boolean from Standard; myShape : Shape from TopoDS; myIsDone : Boolean from Standard; myJoinType : JoinType from GeomAbs; diff --git a/src/BRepFill/BRepFill_OffsetWire.cxx b/src/BRepFill/BRepFill_OffsetWire.cxx index 97d06be376..8566b6c6fc 100644 --- a/src/BRepFill/BRepFill_OffsetWire.cxx +++ b/src/BRepFill/BRepFill_OffsetWire.cxx @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -189,10 +190,11 @@ static void StoreInMap (const TopoDS_Shape& V1, static void TrimEdge (const TopoDS_Edge& CurrentEdge, const TopTools_ListOfShape& D, - TopTools_SequenceOfShape& Sv, - TColStd_SequenceOfReal& MapverPar, - TopTools_SequenceOfShape& S, - TopTools_IndexedDataMapOfShapeShape& MapVV); + TopTools_SequenceOfShape& Sv, + TColStd_SequenceOfReal& MapverPar, + TopTools_SequenceOfShape& S, + TopTools_IndexedDataMapOfShapeShape& MapVV, + const Standard_Integer IndOfE); static Standard_Boolean DoubleOrNotInside (const TopTools_ListOfShape& EC, const TopoDS_Vertex& V); @@ -213,7 +215,9 @@ static void MakeOffset const TopoDS_Face& F, const Standard_Real Offset, BRepFill_IndexedDataMapOfOrientedShapeListOfShape& Map, - const Handle(Geom_Plane)& RefPlane); + const Handle(Geom_Plane)& RefPlane, + const Standard_Boolean IsOpenResult, + const TopoDS_Vertex * Ends); @@ -258,9 +262,6 @@ static Standard_Boolean KPartCircle E = TopoDS::Edge(exp.Current()); if (NbEdges > 1) return Standard_False; } - TopoDS_Vertex V1,V2; - TopExp::Vertices(E,V1,V2); - if (!V1.IsSame(V2)) return Standard_False; Standard_Real f,l; TopLoc_Location L; @@ -271,6 +272,49 @@ static Standard_Boolean KPartCircle C = Ct->BasisCurve(); } + TopoDS_Vertex V1,V2; + TopExp::Vertices(E,V1,V2); + if (!V1.IsSame(V2)) //may be case of line + { + if (!C->IsKind(STANDARD_TYPE(Geom_Line))) return Standard_False; + Handle(Geom_Line) LE = Handle(Geom_Line)::DownCast(C); + Standard_Real anOffset = myOffset; + if (E.Orientation() == TopAbs_REVERSED) anOffset *= -1; + + Handle(Geom2d_Curve) aPCurve; + Handle(Geom_Surface) aSurf; + TopLoc_Location aLoc; + BRep_Tool::CurveOnSurface(E, aPCurve, aSurf, aLoc, f, l); + Handle(Geom2dAdaptor_HCurve) AHC = new Geom2dAdaptor_HCurve(aPCurve, f, l); + Adaptor3d_OffsetCurve Off(AHC,anOffset); + Handle(Geom2d_Line) OLC = new Geom2d_Line(Off.Line()); + Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(aSurf); + myShape = BRepLib_MakeEdge(OLC, aPlane, f, l); + BRepLib::BuildCurve3d(TopoDS::Edge(myShape)); + + myShape.Orientation(E.Orientation()); + myShape.Location(L); + if (Alt != 0.) { + BRepAdaptor_Surface S(mySpine,0); + gp_Ax1 Nor = S.Plane().Axis(); + gp_Trsf T; + gp_Vec Trans(Nor.Direction()); + Trans = Alt*Trans; + T.SetTranslation(Trans); + myShape.Move(TopLoc_Location(T)); + } + + TopTools_ListOfShape LL; + LL.Append(myShape); + myMap.Add(E,LL); + + TopoDS_Edge myEdge = TopoDS::Edge(myShape); + myShape = BRepLib_MakeWire(myEdge); + + myIsDone = Standard_True; + return Standard_True; + } + if (!C->IsKind(STANDARD_TYPE(Geom_Circle))) return Standard_False; Handle(Geom_Circle) CE = Handle(Geom_Circle)::DownCast(C); Standard_Real anOffset = myOffset; @@ -306,7 +350,8 @@ static Standard_Boolean KPartCircle //======================================================================= BRepFill_OffsetWire::BRepFill_OffsetWire() -:myIsDone(Standard_False) + : myIsOpenResult(Standard_False), + myIsDone(Standard_False) { } @@ -317,9 +362,10 @@ BRepFill_OffsetWire::BRepFill_OffsetWire() //======================================================================= BRepFill_OffsetWire::BRepFill_OffsetWire(const TopoDS_Face& Spine, - const GeomAbs_JoinType Join ) + const GeomAbs_JoinType Join, + const Standard_Boolean IsOpenResult) { - Init(Spine,Join); + Init(Spine,Join,IsOpenResult); } //======================================================================= @@ -328,7 +374,8 @@ BRepFill_OffsetWire::BRepFill_OffsetWire(const TopoDS_Face& Spine, //======================================================================= void BRepFill_OffsetWire::Init(const TopoDS_Face& Spine, - const GeomAbs_JoinType Join ) + const GeomAbs_JoinType Join, + const Standard_Boolean IsOpenResult) { Standard_NotImplemented_Raise_if(Join > GeomAbs_Arc, "Only GeomAbs_Arc is implemented"); @@ -338,6 +385,7 @@ void BRepFill_OffsetWire::Init(const TopoDS_Face& Spine, mySpine = TopoDS::Face(aLocalShape); // mySpine = TopoDS::Face(Spine.Oriented(TopAbs_FORWARD)); myJoinType = Join; + myIsOpenResult = IsOpenResult; CheckFace(mySpine); @@ -372,7 +420,7 @@ void BRepFill_OffsetWire::Init(const TopoDS_Face& Spine, // static BRepMAT2d_Explorer Exp; // Modified by Sergey KHROMOV - Tue Nov 26 17:39:03 2002 End Exp.Perform(myWorkSpine); - myBilo.Compute(Exp,1,MAT_Left); + myBilo.Compute(Exp,1,MAT_Left,myIsOpenResult); myLink.Perform(Exp,myBilo); } @@ -600,7 +648,7 @@ void BRepFill_OffsetWire::Perform (const Standard_Real Offset, newExp.Perform(myWorkSpine); BRepMAT2d_BisectingLocus newBilo; BRepMAT2d_LinkTopoBilo newLink; - newBilo.Compute(newExp,1,MAT_Left); + newBilo.Compute(newExp,1,MAT_Left,myIsOpenResult); if(!newBilo.IsDone()) { @@ -635,15 +683,18 @@ void BRepFill_OffsetWire::Perform (const Standard_Real Offset, // Modified by skv - Fri Jul 8 11:21:38 2005 OCC9145 End // Modified by Sergey KHROMOV - Thu Mar 14 10:48:15 2002 Begin - TopExp_Explorer anExp(myShape, TopAbs_WIRE); - - for (; anExp.More(); anExp.Next()) { - const TopoDS_Shape &aWire = anExp.Current(); - - if (!aWire.Closed()) { - myShape.Nullify(); - myIsDone = Standard_False; - Standard_ConstructionError::Raise("Offset wire is not closed."); + if (!myIsOpenResult) + { + TopExp_Explorer anExp(myShape, TopAbs_WIRE); + + for (; anExp.More(); anExp.Next()) { + const TopoDS_Shape &aWire = anExp.Current(); + + if (!aWire.Closed()) { + myShape.Nullify(); + myIsDone = Standard_False; + Standard_ConstructionError::Raise("Offset wire is not closed."); + } } } // Modified by Sergey KHROMOV - Thu Mar 14 10:48:16 2002 End @@ -761,7 +812,16 @@ void BRepFill_OffsetWire::PerformWithBiLo //--------------------------------------------------------------- // Construction of Circles and OffsetCurves //--------------------------------------------------------------- - + + TopoDS_Vertex Ends [2]; + if (myIsOpenResult) + { + TopoDS_Wire theWire; + TopoDS_Iterator iter(mySpine); + theWire = TopoDS::Wire(iter.Value()); + TopExp::Vertices(theWire, Ends[0], Ends[1]); + } + for (Standard_Integer ic = 1; ic <= Locus.NumberOfContours(); ic++) { TopoDS_Shape PEE = Link.GeneratingShape(Locus.BasicElt(ic,Locus.NumberOfElts(ic))); TopoDS_Shape& PE = PEE ; @@ -772,7 +832,8 @@ void BRepFill_OffsetWire::PerformWithBiLo myWorkSpine,myOffset,myMap,RefPlane); } else { - MakeOffset (TopoDS::Edge(SE),myWorkSpine,myOffset,myMap,RefPlane); + MakeOffset (TopoDS::Edge(SE),myWorkSpine,myOffset,myMap,RefPlane, + myIsOpenResult, Ends); PE = SE; } } @@ -982,11 +1043,19 @@ void BRepFill_OffsetWire::PerformWithBiLo if (MapBis.IsBound(CurrentEdge)) { TopTools_SequenceOfShape S; if (!MapBis(CurrentEdge).IsEmpty()) { + Standard_Integer IndOfE = 0; + if (myIsOpenResult) + { + if (j == 1) + IndOfE = 1; + else if (j == myMap.Extent()) + IndOfE = -1; + } TrimEdge (CurrentEdge, Detromp (CurrentSpine), MapBis (CurrentEdge) , MapVerPar(CurrentEdge) , - S, MapVV); + S, MapVV, IndOfE); for ( k = 1; k <= S.Length(); k++) { myMap(j).Append(S.Value(k)); } @@ -1135,7 +1204,7 @@ void BRepFill_OffsetWire::PrepareSpine() TopExp::MapShapes(IteF.Value(), TopAbs_EDGE, EdgeMap); Standard_Integer nbEdges = EdgeMap.Extent(); - if (nbEdges == 1) + if (nbEdges == 1 && !myIsOpenResult) //in case of open wire there's no need to do it ForcedCut = 2; // Modified by Sergey KHROMOV - Thu Nov 16 17:29:48 2000 End @@ -1832,7 +1901,9 @@ void MakeOffset (const TopoDS_Edge& E, const TopoDS_Face& F, const Standard_Real Offset, BRepFill_IndexedDataMapOfOrientedShapeListOfShape& Map, - const Handle(Geom_Plane)& RefPlane) + const Handle(Geom_Plane)& RefPlane, + const Standard_Boolean IsOpenResult, + const TopoDS_Vertex * Ends) { Standard_Real f,l; Standard_Real anOffset = Offset; @@ -1842,6 +1913,20 @@ void MakeOffset (const TopoDS_Edge& E, Handle(Geom2d_Curve) G2d = BRep_Tool::CurveOnSurface(E,F,f,l); Handle(Geom2d_Curve) G2dOC; + Standard_Boolean ToExtendFirstPar = Standard_True; + Standard_Boolean ToExtendLastPar = Standard_True; + if (IsOpenResult) + { + TopoDS_Vertex V1, V2; + TopExp::Vertices(E, V1, V2); + if (V1.IsSame(Ends[0]) || + V1.IsSame(Ends[1])) + ToExtendFirstPar = Standard_False; + if (V2.IsSame(Ends[0]) || + V2.IsSame(Ends[1])) + ToExtendLastPar = Standard_False; + } + Geom2dAdaptor_Curve AC(G2d,f,l); if ( AC.GetType() == GeomAbs_Circle) { // if the offset is greater otr equal to the radius and the side of the @@ -1861,7 +1946,10 @@ void MakeOffset (const TopoDS_Edge& E, Handle(Geom2d_Circle) CC = new Geom2d_Circle(Off.Circle()); Standard_Real Delta = 2*M_PI - l + f; - f -= 0.2*Delta; l += 0.2*Delta; + if (ToExtendFirstPar) + f -= 0.2*Delta; + if (ToExtendLastPar) + l += 0.2*Delta; G2dOC = new Geom2d_TrimmedCurve(CC,f,l); } @@ -1872,7 +1960,10 @@ void MakeOffset (const TopoDS_Edge& E, Adaptor3d_OffsetCurve Off(AHC,anOffset); Handle(Geom2d_Line) CC = new Geom2d_Line(Off.Line()); Standard_Real Delta = (l - f); - f -= Delta; l += Delta; + if (ToExtendFirstPar) + f -= Delta; + if (ToExtendLastPar) + l += Delta; G2dOC = new Geom2d_TrimmedCurve(CC,f,l); } else { @@ -2043,10 +2134,11 @@ void StoreInMap (const TopoDS_Shape& V1, void TrimEdge (const TopoDS_Edge& E, const TopTools_ListOfShape& Detromp, - TopTools_SequenceOfShape& TheVer, - TColStd_SequenceOfReal& ThePar, - TopTools_SequenceOfShape& S, - TopTools_IndexedDataMapOfShapeShape& MapVV) + TopTools_SequenceOfShape& TheVer, + TColStd_SequenceOfReal& ThePar, + TopTools_SequenceOfShape& S, + TopTools_IndexedDataMapOfShapeShape& MapVV, + const Standard_Integer IndOfE) { Standard_Boolean Change = Standard_True; BRep_Builder TheBuilder; @@ -2117,46 +2209,93 @@ void TrimEdge (const TopoDS_Edge& E, // the number of vertices should be even. The created edges // go from a vertex with uneven index i to vertex i+1; //----------------------------------------------------------- - for (Standard_Integer k = 1; k < TheVer.Length(); k = k+2) { + if (IndOfE == 1 || IndOfE == -1) //open result and extreme edges of result + { TopoDS_Shape aLocalShape = E.EmptyCopied(); TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape); -// TopoDS_Edge NewEdge = TopoDS::Edge(E.EmptyCopied()); - - if (NewEdge.Orientation() == TopAbs_REVERSED) { - TheBuilder.Add (NewEdge,TheVer.Value(k) .Oriented(TopAbs_REVERSED)); - TheBuilder.Add (NewEdge,TheVer.Value(k+1).Oriented(TopAbs_FORWARD)); + TopoDS_Vertex V1, V2; + TopExp::Vertices(E, V1, V2); + Standard_Real fpar, lpar; + BRep_Tool::Range(E, fpar, lpar); + if (IndOfE == 1) //first edge of open wire + { + if (NewEdge.Orientation() == TopAbs_FORWARD) + { + TheBuilder.Add(NewEdge, V1.Oriented(TopAbs_FORWARD)); + TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_REVERSED)); + TheBuilder.Range(NewEdge, fpar, ThePar.First()); + } + else + { + //TheBuilder.Add(NewEdge, V1.Oriented(TopAbs_REVERSED)); + //TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_FORWARD)); + TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_REVERSED)); + TheBuilder.Add(NewEdge, V2.Oriented(TopAbs_FORWARD)); + TheBuilder.Range(NewEdge, ThePar.First(), lpar); + } } - else { - TheBuilder.Add (NewEdge,TheVer.Value(k) .Oriented(TopAbs_FORWARD)); - TheBuilder.Add (NewEdge,TheVer.Value(k+1).Oriented(TopAbs_REVERSED)); + else //last edge of open wire + { + if (NewEdge.Orientation() == TopAbs_FORWARD) + { + TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_FORWARD)); + TheBuilder.Add(NewEdge, V2.Oriented(TopAbs_REVERSED)); + TheBuilder.Range(NewEdge, ThePar.First(), lpar); + } + else + { + //TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_REVERSED)); + //TheBuilder.Add(NewEdge, V2.Oriented(TopAbs_FORWARD)); + TheBuilder.Add(NewEdge, V1.Oriented(TopAbs_REVERSED)); + TheBuilder.Add(NewEdge, TheVer.First().Oriented(TopAbs_FORWARD)); + TheBuilder.Range(NewEdge, fpar, ThePar.First()); + } } - - - TheBuilder.Range(NewEdge,ThePar.Value(k),ThePar.Value(k+1)); - + S.Append(NewEdge); + } + else + { + for (Standard_Integer k = 1; k < TheVer.Length(); k = k+2) { + TopoDS_Shape aLocalShape = E.EmptyCopied(); + TopoDS_Edge NewEdge = TopoDS::Edge(aLocalShape); + // TopoDS_Edge NewEdge = TopoDS::Edge(E.EmptyCopied()); + + if (NewEdge.Orientation() == TopAbs_REVERSED) { + TheBuilder.Add (NewEdge,TheVer.Value(k) .Oriented(TopAbs_REVERSED)); + TheBuilder.Add (NewEdge,TheVer.Value(k+1).Oriented(TopAbs_FORWARD)); + } + else { + TheBuilder.Add (NewEdge,TheVer.Value(k) .Oriented(TopAbs_FORWARD)); + TheBuilder.Add (NewEdge,TheVer.Value(k+1).Oriented(TopAbs_REVERSED)); + } + + + TheBuilder.Range(NewEdge,ThePar.Value(k),ThePar.Value(k+1)); + #ifdef DRAW - if ( AffichEdge) { - char name[256]; - sprintf(name,"TRIMEDGE_%d",NbTRIMEDGES); - DBRep::Set(name,NewEdge); - } - if (Affich2d) { - TopLoc_Location L; - Standard_Real f,l; - Handle(Geom_Surface) Surf; - Handle(Geom2d_Curve) C; - BRep_Tool::CurveOnSurface(NewEdge,C,Surf,L,f,l); - char name[256]; - sprintf(name,"OFFSET2d_%d",NbTRIMEDGES++); - Handle(Geom2d_TrimmedCurve) C2d = new Geom2d_TrimmedCurve(C,f,l); - Handle(DrawTrSurf_Curve2d) dr = - new DrawTrSurf_Curve2d(C2d,Standard_False); - dr->SetColor(Draw_bleu); - Draw::Set(name,dr); - } + if ( AffichEdge) { + char name[256]; + sprintf(name,"TRIMEDGE_%d",NbTRIMEDGES); + DBRep::Set(name,NewEdge); + } + if (Affich2d) { + TopLoc_Location L; + Standard_Real f,l; + Handle(Geom_Surface) Surf; + Handle(Geom2d_Curve) C; + BRep_Tool::CurveOnSurface(NewEdge,C,Surf,L,f,l); + char name[256]; + sprintf(name,"OFFSET2d_%d",NbTRIMEDGES++); + Handle(Geom2d_TrimmedCurve) C2d = new Geom2d_TrimmedCurve(C,f,l); + Handle(DrawTrSurf_Curve2d) dr = + new DrawTrSurf_Curve2d(C2d,Standard_False); + dr->SetColor(Draw_bleu); + Draw::Set(name,dr); + } #endif - - S.Append(NewEdge); + + S.Append(NewEdge); + } } } diff --git a/src/BRepMAT2d/BRepMAT2d_BisectingLocus.cdl b/src/BRepMAT2d/BRepMAT2d_BisectingLocus.cdl index a0f57fe989..85884e49b9 100644 --- a/src/BRepMAT2d/BRepMAT2d_BisectingLocus.cdl +++ b/src/BRepMAT2d/BRepMAT2d_BisectingLocus.cdl @@ -73,7 +73,8 @@ is Compute (me : in out ; anExplo : in out Explorer from BRepMAT2d; LineIndex : Integer = 1; - aSide : Side from MAT = MAT_Left ) + aSide : Side from MAT = MAT_Left; + IsOpenResult : Boolean = Standard_False) --- Purpose : Computation of the Bisector_Locus in a set of Lines -- defined in . -- The bisecting locus are computed on the side