diff --git a/src/LocOpe/LocOpe.cdl b/src/LocOpe/LocOpe.cdl index d894a9819f..0848579fb2 100644 --- a/src/LocOpe/LocOpe.cdl +++ b/src/LocOpe/LocOpe.cdl @@ -41,7 +41,7 @@ is class SplitShape; - deferred class ProjectedWires; -- inherits TShared from MMgt + --deferred class ProjectedWires; -- inherits TShared from MMgt class WiresOnShape; -- inherits ProjectedWires from LocOpe diff --git a/src/LocOpe/LocOpe_BuildWires.cdl b/src/LocOpe/LocOpe_BuildWires.cdl index eaee3cbcda..83143d4ba8 100644 --- a/src/LocOpe/LocOpe_BuildWires.cdl +++ b/src/LocOpe/LocOpe_BuildWires.cdl @@ -23,7 +23,7 @@ private class BuildWires from LocOpe -- Modified by skv - Mon May 31 12:53:04 2004 OCC5865 Begin uses ListOfShape from TopTools, - ProjectedWires from LocOpe + WiresOnShape from LocOpe -- Modified by skv - Mon May 31 12:53:05 2004 OCC5865 End raises NotDone from StdFail @@ -37,7 +37,7 @@ is -- Modified by skv - Mon May 31 12:54:10 2004 OCC5865 Begin Create(Ledges: ListOfShape from TopTools; - PW : ProjectedWires from LocOpe) + PW : WiresOnShape from LocOpe) -- Modified by skv - Mon May 31 12:54:11 2004 OCC5865 End returns BuildWires from LocOpe; @@ -45,7 +45,7 @@ is -- Modified by skv - Mon May 31 12:54:10 2004 OCC5865 Begin Perform(me: in out; Ledges: ListOfShape from TopTools; - PW : ProjectedWires from LocOpe) + PW : WiresOnShape from LocOpe) -- Modified by skv - Mon May 31 12:54:11 2004 OCC5865 End is static; diff --git a/src/LocOpe/LocOpe_BuildWires.cxx b/src/LocOpe/LocOpe_BuildWires.cxx index 1b03d87d8a..52da359559 100644 --- a/src/LocOpe/LocOpe_BuildWires.cxx +++ b/src/LocOpe/LocOpe_BuildWires.cxx @@ -60,7 +60,7 @@ LocOpe_BuildWires::LocOpe_BuildWires () : myDone(Standard_False) // Modified by skv - Mon May 31 12:58:27 2004 OCC5865 Begin LocOpe_BuildWires::LocOpe_BuildWires (const TopTools_ListOfShape& L, - const Handle(LocOpe_ProjectedWires)& PW) + const Handle(LocOpe_WiresOnShape)& PW) { Perform(L, PW); } @@ -74,7 +74,7 @@ LocOpe_BuildWires::LocOpe_BuildWires (const TopTools_ListOfShape& L, // Modified by skv - Mon May 31 12:59:09 2004 OCC5865 Begin void LocOpe_BuildWires::Perform(const TopTools_ListOfShape& L, - const Handle(LocOpe_ProjectedWires)& PW) + const Handle(LocOpe_WiresOnShape)& PW) { // Modified by skv - Mon May 31 12:59:10 2004 OCC5865 End myDone = Standard_False; diff --git a/src/LocOpe/LocOpe_ProjectedWires.cdl b/src/LocOpe/LocOpe_ProjectedWires.cdl deleted file mode 100644 index 69d054bc4c..0000000000 --- a/src/LocOpe/LocOpe_ProjectedWires.cdl +++ /dev/null @@ -1,87 +0,0 @@ --- Created on: 1996-01-08 --- Created by: Jacques GOUSSARD --- Copyright (c) 1996-1999 Matra Datavision --- Copyright (c) 1999-2014 OPEN CASCADE SAS --- --- This file is part of Open CASCADE Technology software library. --- --- This library is free software; you can redistribute it and/or modify it under --- the terms of the GNU Lesser General Public License version 2.1 as published --- by the Free Software Foundation, with special exception defined in the file --- OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT --- distribution for complete text of the license and disclaimer of any warranty. --- --- Alternatively, this file may be used under the terms of Open CASCADE --- commercial license or contractual agreement. - -deferred class ProjectedWires from LocOpe inherits TShared from MMgt - - ---Purpose: - -uses Face from TopoDS, - Wire from TopoDS, - Edge from TopoDS, - Vertex from TopoDS, - Shape from TopoDS - -is - - InitEdgeIterator(me: mutable) - - is deferred; - - - MoreEdge(me: mutable) - returns Boolean from Standard - is deferred; - - - Edge(me: mutable) - returns Edge from TopoDS - is deferred; - - - OnFace(me: mutable) - ---Purpose: Returns the face of the shape on which the current - -- edge is projected. - returns Face from TopoDS - is deferred; - - - OnEdge(me: mutable; E: out Edge from TopoDS) - ---Purpose: If the current edge is projected on an edge, - -- returns and sets the value of . - -- Otherwise, returns . - returns Boolean from Standard - is deferred; - - - NextEdge(me: mutable) - - is deferred; - - - OnVertex(me: mutable; Vwire : Vertex from TopoDS; - Vshape: out Vertex from TopoDS) - - returns Boolean from Standard - is deferred; - - - OnEdge(me: mutable; V: Vertex from TopoDS; - E: out Edge from TopoDS; - P: out Real from Standard) - ---Purpose: If the vertex lies on an edge of the original - -- shape, returns and sets the - -- concerned edge in , and the parameter on the - -- edge in

. - -- Else returns . - returns Boolean from Standard - is deferred; - - IsFaceWithSection(me; aFace : Shape from TopoDS) - ---Purpose: tells is the face to be split by section or not - returns Boolean from Standard - is deferred; - -end ProjectedWires; diff --git a/src/LocOpe/LocOpe_ProjectedWires.cxx b/src/LocOpe/LocOpe_ProjectedWires.cxx deleted file mode 100644 index 941d9e5611..0000000000 --- a/src/LocOpe/LocOpe_ProjectedWires.cxx +++ /dev/null @@ -1,17 +0,0 @@ -// Created on: 1996-01-08 -// Created by: Jacques GOUSSARD -// Copyright (c) 1996-1999 Matra Datavision -// Copyright (c) 1999-2014 OPEN CASCADE SAS -// -// This file is part of Open CASCADE Technology software library. -// -// This library is free software; you can redistribute it and/or modify it under -// the terms of the GNU Lesser General Public License version 2.1 as published -// by the Free Software Foundation, with special exception defined in the file -// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT -// distribution for complete text of the license and disclaimer of any warranty. -// -// Alternatively, this file may be used under the terms of Open CASCADE -// commercial license or contractual agreement. - -#include diff --git a/src/LocOpe/LocOpe_Spliter.cdl b/src/LocOpe/LocOpe_Spliter.cdl index fad5a9b2b0..834cfa232f 100644 --- a/src/LocOpe/LocOpe_Spliter.cdl +++ b/src/LocOpe/LocOpe_Spliter.cdl @@ -20,7 +20,7 @@ class Spliter from LocOpe uses Shape from TopoDS, Face from TopoDS, - ProjectedWires from LocOpe, + WiresOnShape from LocOpe, ListOfShape from TopTools, DataMapOfShapeListOfShape from TopTools @@ -50,7 +50,7 @@ is is static; - Perform(me: in out; PW: ProjectedWires from LocOpe) + Perform(me: in out; PW: WiresOnShape from LocOpe) raises NullObject from Standard is static; diff --git a/src/LocOpe/LocOpe_Spliter.cxx b/src/LocOpe/LocOpe_Spliter.cxx index 4d1c87d087..002f7afaf6 100644 --- a/src/LocOpe/LocOpe_Spliter.cxx +++ b/src/LocOpe/LocOpe_Spliter.cxx @@ -18,11 +18,13 @@ #include -#include +//#include #include #include +#include #include +#include #include #include #include @@ -56,7 +58,7 @@ // Modified by skv - Mon May 31 13:00:30 2004 OCC5865 Begin // static void RebuildWires(TopTools_ListOfShape&); static void RebuildWires(TopTools_ListOfShape&, - const Handle(LocOpe_ProjectedWires)&); + const Handle(LocOpe_WiresOnShape)&); // Modified by skv - Mon May 31 13:00:31 2004 OCC5865 End static void Put(const TopoDS_Shape&, @@ -71,7 +73,7 @@ static void Select(const TopoDS_Edge&, //purpose : //======================================================================= -void LocOpe_Spliter::Perform(const Handle(LocOpe_ProjectedWires)& PW) +void LocOpe_Spliter::Perform(const Handle(LocOpe_WiresOnShape)& PW) { if (myShape.IsNull()) { Standard_NullObject::Raise(); @@ -150,7 +152,7 @@ void LocOpe_Spliter::Perform(const Handle(LocOpe_ProjectedWires)& PW) const TopoDS_Vertex& vtx = TopoDS::Vertex(exp.Current()); if (!mapV.Contains(vtx)) { mapV.Add(vtx); - if (PW->OnEdge(vtx,Ed,prm)) { + if (PW->OnEdge(vtx,edg,Ed,prm)) { // on devrait verifier que le vtx n`existe pas deja sur l`edge if(!myMap.IsBound(Ed)) continue; Ed = TopoDS::Edge(myMap(Ed).First()); @@ -323,6 +325,69 @@ void LocOpe_Spliter::Perform(const Handle(LocOpe_ProjectedWires)& PW) myRes = theSubs.Copy(myRes).First(); } + ////remove superfluous vertices on degenerated edges + theSubs.Clear(); + TopTools_IndexedMapOfShape Emap; + TopExp::MapShapes(myRes, TopAbs_EDGE, Emap); + TopTools_SequenceOfShape DegEdges; + Standard_Integer i, j; + for (i = 1; i <= Emap.Extent(); i++) + { + const TopoDS_Edge& anEdge = TopoDS::Edge(Emap(i)); + if (BRep_Tool::Degenerated(anEdge)) + DegEdges.Append(anEdge); + } + + TopTools_SequenceOfShape DegWires; + for (;;) + { + if (DegEdges.IsEmpty()) + break; + TopoDS_Wire aDegWire; + BB.MakeWire(aDegWire); + BB.Add(aDegWire, DegEdges(1)); + DegEdges.Remove(1); + TopoDS_Vertex Vfirst, Vlast; + for (;;) + { + TopExp::Vertices(aDegWire, Vfirst, Vlast); + Standard_Boolean found = Standard_False; + for (i = 1; i <= DegEdges.Length(); i++) + { + const TopoDS_Edge& anEdge = TopoDS::Edge(DegEdges(i)); + TopoDS_Vertex V1, V2; + TopExp::Vertices(anEdge, V1, V2); + if (V1.IsSame(Vfirst) || V1.IsSame(Vlast) || V2.IsSame(Vfirst) || V2.IsSame(Vlast)) + { + BB.Add(aDegWire, anEdge); + DegEdges.Remove(i); + found = Standard_True; + break; + } + } + if (!found) + break; + } + DegWires.Append(aDegWire); + } + + for (i = 1; i <= DegWires.Length(); i++) + { + TopTools_IndexedMapOfShape Vmap; + TopExp::MapShapes(DegWires(i), TopAbs_VERTEX, Vmap); + TopTools_ListOfShape LV; + LV.Append(Vmap(1).Oriented(TopAbs_FORWARD)); + for (j = 2; j <= Vmap.Extent(); j++) + { + if (!Vmap(j).IsSame(Vmap(1))) + theSubs.Substitute(Vmap(j), LV); + } + } + theSubs.Build(myRes); + if (theSubs.IsCopied(myRes)) + myRes = theSubs.Copy(myRes).First(); + //// + myDLeft.Clear(); myLeft.Clear(); mapV.Clear(); @@ -483,7 +548,7 @@ const TopTools_ListOfShape& LocOpe_Spliter::Left() const // Modified by skv - Mon May 31 12:31:39 2004 OCC5865 Begin //static void RebuildWires(TopTools_ListOfShape& ledge) static void RebuildWires(TopTools_ListOfShape& ledge, - const Handle(LocOpe_ProjectedWires)& PW) + const Handle(LocOpe_WiresOnShape)& PW) { LocOpe_BuildWires theBuild(ledge, PW); // Modified by skv - Mon May 31 12:31:40 2004 OCC5865 End diff --git a/src/LocOpe/LocOpe_WiresOnShape.cdl b/src/LocOpe/LocOpe_WiresOnShape.cdl index a893a58e61..252777484e 100644 --- a/src/LocOpe/LocOpe_WiresOnShape.cdl +++ b/src/LocOpe/LocOpe_WiresOnShape.cdl @@ -14,7 +14,7 @@ -- Alternatively, this file may be used under the terms of Open CASCADE -- commercial license or contractual agreement. -class WiresOnShape from LocOpe inherits ProjectedWires from LocOpe +class WiresOnShape from LocOpe inherits TShared from MMgt ---Purpose: @@ -134,6 +134,18 @@ is returns Boolean from Standard ; + OnEdge(me: mutable; V: Vertex from TopoDS; + EdgeFrom: Edge from TopoDS; + E: out Edge from TopoDS; + P: out Real from Standard) + ---Purpose: If the vertex lies on an edge of the original + -- shape, returns and sets the + -- concerned edge in , and the parameter on the + -- edge in

. + -- Else returns . + returns Boolean from Standard + ; + IsFaceWithSection(me; aFace : Shape from TopoDS) ---Purpose: tells is the face to be split by section or not ---C++: inline diff --git a/src/LocOpe/LocOpe_WiresOnShape.cxx b/src/LocOpe/LocOpe_WiresOnShape.cxx index 712c1d4599..905d616289 100644 --- a/src/LocOpe/LocOpe_WiresOnShape.cxx +++ b/src/LocOpe/LocOpe_WiresOnShape.cxx @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -56,6 +57,7 @@ static Standard_Boolean Project(const TopoDS_Vertex&, + const gp_Pnt2d&, const TopoDS_Face&, TopoDS_Edge&, Standard_Real&); @@ -63,6 +65,11 @@ static Standard_Boolean Project(const TopoDS_Vertex&, static Standard_Real Project(const TopoDS_Vertex&, const TopoDS_Edge&); +static Standard_Real Project(const TopoDS_Vertex&, + const gp_Pnt2d&, + const TopoDS_Edge&, + const TopoDS_Face&); + static void PutPCurve(const TopoDS_Edge&, const TopoDS_Face&); @@ -274,9 +281,14 @@ void LocOpe_WiresOnShape::BindAll() if (theMap.Contains(vtx)) { continue; } + //// + Standard_Real vtx_param = BRep_Tool::Parameter(vtx, edg); + BRepAdaptor_Curve2d BAcurve2d(edg, fac); + gp_Pnt2d p2d = BAcurve2d.Value(vtx_param); + //// TopoDS_Edge Epro; - Standard_Real prm; - Standard_Boolean ok = Project(vtx,fac,Epro,prm); + Standard_Real prm = 0.; + Standard_Boolean ok = Project(vtx, p2d, fac, Epro, prm); if (ok) { for (exp2.Init(Epro,TopAbs_VERTEX); exp2.More(); exp2.Next()) { const TopoDS_Vertex& vtx2 = TopoDS::Vertex(exp2.Current()); @@ -284,8 +296,13 @@ void LocOpe_WiresOnShape::BindAll() break; } else if (BRepTools::Compare(vtx,vtx2)) { - myMap.Bind(vtx,vtx2); - break; + if (!BRep_Tool::Degenerated(Epro) || + Abs(prm-BAcurve2d.FirstParameter()) <= Precision::PConfusion() || + Abs(prm-BAcurve2d.LastParameter()) <= Precision::PConfusion()) + { + myMap.Bind(vtx,vtx2); + break; + } } } if (!exp2.More()) { @@ -408,8 +425,6 @@ Standard_Boolean LocOpe_WiresOnShape::OnVertex(const TopoDS_Vertex& Vw, } - - //======================================================================= //function : OnEdge //purpose : @@ -429,6 +444,32 @@ Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V, return Standard_True; } +//======================================================================= +//function : OnEdge +//purpose : +//======================================================================= + +Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V, + const TopoDS_Edge& EdgeFrom, + TopoDS_Edge& Ed, + Standard_Real& prm) +{ + if (!myMap.IsBound(V) || + myMap(V).ShapeType() == TopAbs_VERTEX) { + return Standard_False; + } + + Ed = TopoDS::Edge(myMap(V)); + TopoDS_Face theFace = TopoDS::Face(myMapEF.FindFromKey(EdgeFrom)); + //// + Standard_Real vtx_param = BRep_Tool::Parameter(V, EdgeFrom); + BRepAdaptor_Curve2d BAcurve2d(EdgeFrom, theFace); + gp_Pnt2d p2d = BAcurve2d.Value(vtx_param); + //// + prm = Project(V, p2d, Ed, theFace); + return Standard_True; +} + //======================================================================= //function : Project @@ -436,36 +477,32 @@ Standard_Boolean LocOpe_WiresOnShape::OnEdge(const TopoDS_Vertex& V, //======================================================================= Standard_Boolean Project(const TopoDS_Vertex& V, + const gp_Pnt2d& p2d, const TopoDS_Face& F, TopoDS_Edge& theEdge, Standard_Real& param) { - Handle(Geom_Curve) C; - TopLoc_Location Loc; + Handle(Geom2d_Curve) PC; + //TopLoc_Location Loc; Standard_Real f,l; Standard_Real dmin = RealLast(); - gp_Pnt toproj(BRep_Tool::Pnt(V)); + //gp_Pnt toproj(BRep_Tool::Pnt(V)); Standard_Boolean valret = Standard_False; - GeomAPI_ProjectPointOnCurve proj; + Geom2dAPI_ProjectPointOnCurve proj; for (TopExp_Explorer exp(F.Oriented(TopAbs_FORWARD),TopAbs_EDGE); exp.More(); exp.Next()) { const TopoDS_Edge& edg = TopoDS::Edge(exp.Current()); - if (!BRep_Tool::Degenerated(edg)) { - C = BRep_Tool::Curve(edg,Loc,f,l); - if (!Loc.IsIdentity()) { - Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation()); - C = *((Handle(Geom_Curve)*)&GG); - } - proj.Init(toproj,C,f,l); - if (proj.NbPoints() > 0) { - if (proj.LowerDistance() < dmin) { - theEdge = edg; - theEdge.Orientation(edg.Orientation()); - dmin = proj.LowerDistance(); - param = proj.LowerDistanceParameter(); - } + //C = BRep_Tool::Curve(edg,Loc,f,l); + PC = BRep_Tool::CurveOnSurface(edg, F, f, l); + proj.Init(p2d, PC, f, l); + if (proj.NbPoints() > 0) { + if (proj.LowerDistance() < dmin) { + theEdge = edg; + theEdge.Orientation(edg.Orientation()); + dmin = proj.LowerDistance(); + param = proj.LowerDistanceParameter(); } } } @@ -514,6 +551,35 @@ Standard_Real Project(const TopoDS_Vertex& V, return proj.LowerDistanceParameter(); } +//======================================================================= +//function : Project +//purpose : +//======================================================================= + +Standard_Real Project(const TopoDS_Vertex&, + const gp_Pnt2d& p2d, + const TopoDS_Edge& theEdge, + const TopoDS_Face& theFace) +{ + //Handle(Geom_Curve) C; + Handle(Geom2d_Curve) PC; + //TopLoc_Location Loc; + Standard_Real f,l; + + Geom2dAPI_ProjectPointOnCurve proj; + + PC = BRep_Tool::CurveOnSurface(theEdge, theFace, f, l); + /* + if (!Loc.IsIdentity()) { + Handle(Geom_Geometry) GG = C->Transformed(Loc.Transformation()); + C = *((Handle(Geom_Curve)*)&GG); + } + */ + proj.Init(p2d, PC, f, l); + + return proj.LowerDistanceParameter(); +} + //======================================================================= //function : PutPCurve @@ -944,7 +1010,13 @@ void PutPCurves(const TopoDS_Edge& Efrom, C->D1(f,pt,d1f); - Standard_Real prmproj = Project(TopExp::FirstVertex(Efrom),Eto); + //// + TopoDS_Vertex FirstVertex = TopExp::FirstVertex(Efrom); + Standard_Real vtx_param = BRep_Tool::Parameter(FirstVertex, Efrom); + BRepAdaptor_Curve2d BAcurve2d(Efrom, Fac); + gp_Pnt2d p2d = BAcurve2d.Value(vtx_param); + //// + Standard_Real prmproj = Project(TopExp::FirstVertex(Efrom),p2d,Eto,Fac); C = BRep_Tool::Curve(Eto,Loc,f,l); if (!Loc.IsIdentity()) { diff --git a/tests/bugs/modalg_5/bug25243 b/tests/bugs/modalg_5/bug25243 new file mode 100644 index 0000000000..3005c97894 --- /dev/null +++ b/tests/bugs/modalg_5/bug25243 @@ -0,0 +1,27 @@ +puts "========" +puts "OCC25243" +puts "========" +puts "" +################################################################################## +# BRepFeat_SplitShape algorithm processes incorrect faces with degenerated edges +################################################################################## + +restore [locate_data_file bug25243_Context.brep] a +restore [locate_data_file bug25243_splitterEdge_1_1.brep] e + +smallview + +explode a + +donly a_4 e +fit + +splitshape result a_4 a_4 e + +set bug_info [checkshape result] +if {[string compare $bug_info "This shape seems to be valid"] != 0} { + puts "ERROR: OCC25243 is reproduced" + puts " shape result is invalid" +} + +set only_screen_axo 1