X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGEOMImpl%2FGEOMImpl_Block6Explorer.cxx;h=6ec0ebf1d18126adbd1f622a9b7c89207323bf01;hb=426cef8148b6ba6d12b2fe09ea636ccc4840308b;hp=5086d53c05eeddd85753778263af4020ac2561fc;hpb=7f46e5fa52cfe13e206ab10e628556e7e393aaf5;p=modules%2Fgeom.git diff --git a/src/GEOMImpl/GEOMImpl_Block6Explorer.cxx b/src/GEOMImpl/GEOMImpl_Block6Explorer.cxx index 5086d53c0..6ec0ebf1d 100644 --- a/src/GEOMImpl/GEOMImpl_Block6Explorer.cxx +++ b/src/GEOMImpl/GEOMImpl_Block6Explorer.cxx @@ -18,7 +18,6 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// #include @@ -79,6 +78,8 @@ #define NBEDGES 12 #define NBVERTS 8 +#define PLANAR_FACE_MAX_TOLERANCE 1e-06 + static Standard_Integer mod4 (Standard_Integer nb) { if (nb <= 0) return nb + 4; @@ -1197,190 +1198,214 @@ Standard_Integer GEOMImpl_Block6Explorer::FindFace //function : MakeFace //purpose : //======================================================================= -void GEOMImpl_Block6Explorer::MakeFace (const TopoDS_Wire& theWire, - const Standard_Boolean isPlanarWanted, - TopoDS_Shape& theResult) +TCollection_AsciiString GEOMImpl_Block6Explorer::MakeFace (const TopoDS_Wire& theWire, + const Standard_Boolean isPlanarWanted, + TopoDS_Shape& theResult) { + if (!isPlanarWanted) + return MakeAnyFace(theWire, theResult); + + // Try to build a planar face. + + // If required tolerance increase will be + // higher than PLANAR_FACE_MAX_TOLERANCE, + // we will try to build a non-planar face. + + TCollection_AsciiString aWarning; + // Workaround for Mantis issue 0020956 - if (isPlanarWanted) { - // Count the number of points in the wire. - // Collect the first three points. - gp_Pnt p1, p2, p3; - bool is3Pnts(false); - bool p1set(false), p2set(false), p3set(false); - BRepTools_WireExplorer wexpl(theWire); - for (; wexpl.More(); wexpl.Next()) { - if (!p1set) { - p1set = true; - p1 = BRep_Tool::Pnt(wexpl.CurrentVertex()); - } - else if (!p2set) { - p2set = true; - p2 = BRep_Tool::Pnt(wexpl.CurrentVertex()); - } - else if (!p3set) { - p3set = true; - is3Pnts = true; - p3 = BRep_Tool::Pnt(wexpl.CurrentVertex()); - } - else { - is3Pnts = false; - break; - } - } - // Construct a plane for the case of three points in the wire. - gp_Pln plane; - if (is3Pnts) { - gce_MakePln mkPln(p1, p2, p3); - if (mkPln.IsDone()) { - plane = mkPln.Value(); - } - else { - is3Pnts = false; - } + // Count the number of points in the wire. + // Collect the first three points. + gp_Pnt p1, p2, p3; + bool is3Pnts (false); + bool p1set(false), p2set(false), p3set(false); + BRepTools_WireExplorer wexpl (theWire); + for (; wexpl.More(); wexpl.Next()) { + if (!p1set) { + p1set = true; + p1 = BRep_Tool::Pnt(wexpl.CurrentVertex()); + } + else if (!p2set) { + p2set = true; + p2 = BRep_Tool::Pnt(wexpl.CurrentVertex()); + } + else if (!p3set) { + p3set = true; + is3Pnts = true; + p3 = BRep_Tool::Pnt(wexpl.CurrentVertex()); + } + else { + is3Pnts = false; + break; } + } - // Construct a face based on the plane (in case of three points in the wire) or - // allow MakeFace to build the plane itself (in case of the number of points is greater than 3). - if (is3Pnts) { - BRepBuilderAPI_MakeFace MK (plane, theWire, isPlanarWanted); - if (MK.IsDone()) { - theResult = MK.Shape(); - return; - } + // Construct a plane for the case of three points in the wire. + gp_Pln plane; + if (is3Pnts) { + gce_MakePln mkPln (p1, p2, p3); + if (mkPln.IsDone()) { + plane = mkPln.Value(); } else { - BRepBuilderAPI_MakeFace MK (theWire, isPlanarWanted); - if (MK.IsDone()) { - theResult = MK.Shape(); - return; - } + is3Pnts = false; + } + } + + // Construct a face based on the plane (in case of three points in the wire) or + // allow MakeFace to build the plane itself (in case of the number of points is greater than 3). + if (is3Pnts) { + BRepBuilderAPI_MakeFace MK (plane, theWire, isPlanarWanted); + if (MK.IsDone()) { + theResult = MK.Shape(); + return aWarning; } } else { - // try to build face on plane or on any surface under the edges of the wire BRepBuilderAPI_MakeFace MK (theWire, isPlanarWanted); if (MK.IsDone()) { theResult = MK.Shape(); - return; + return aWarning; } } - if (!isPlanarWanted) { - // try to construct filling surface - BRepOffsetAPI_MakeFilling MF; + // try to update wire tolerances to build a planar face - Standard_Integer nbEdges = 0; - BRepTools_WireExplorer aWE (theWire); - for (; aWE.More(); aWE.Next(), nbEdges++) { - MF.Add(TopoDS::Edge(aWE.Current()), GeomAbs_C0); - } + // Find a deviation + Standard_Real aToleranceReached, aTol; + BRepLib_FindSurface aFS; + aFS.Init(theWire, -1., isPlanarWanted); + aToleranceReached = aFS.ToleranceReached(); + aTol = aFS.Tolerance(); - MF.Build(); - if (MF.IsDone()) { - // Result of filling - TopoDS_Shape aFace = MF.Shape(); - - // 12.04.2006 for PAL12149 begin - Handle(Geom_Surface) aGS = BRep_Tool::Surface(TopoDS::Face(aFace)); - BRepBuilderAPI_MakeFace MK1 (aGS, theWire); - if (MK1.IsDone()) { - TopoDS_Shape aFace1 = MK1.Shape(); - - BRepCheck_Analyzer ana (aFace1, false); - if (!ana.IsValid()) { - TopoDS_Shape aFace2; - ShHealOper_ShapeProcess aHealer; - aHealer.Perform(aFace1, aFace2); - if (aHealer.isDone()) - theResult = aFace2; - } - } - // 12.04.2006 for PAL12149 end + if (!aFS.Found()) { + aFS.Init(theWire, aToleranceReached, isPlanarWanted); + if (!aFS.Found()) return aWarning; + aToleranceReached = aFS.ToleranceReached(); + aTol = aFS.Tolerance(); + } + aTol = Max(1.2 * aToleranceReached, aTol); + + // Mantis issue 0021432: EDF GEOM: Faces with huge tolerance can be built in GEOM + if (aTol > PLANAR_FACE_MAX_TOLERANCE) { + aWarning = MakeAnyFace(theWire, theResult); + if (aWarning.IsEmpty() && !theResult.IsNull()) + aWarning = "MAKE_FACE_TOLERANCE_TOO_BIG"; + return aWarning; + } - if (theResult.IsNull()) { // try to deal with pure result of filling - // Update tolerance - Standard_Real aTol = MF.G0Error(); + // Copy the wire, bacause it can be updated with very-very big tolerance here + BRepBuilderAPI_Copy aMC (theWire); + if (!aMC.IsDone()) return aWarning; + TopoDS_Wire aWire = TopoDS::Wire(aMC.Shape()); + // Update tolerances to + BRep_Builder B; + for (TopExp_Explorer expE (aWire, TopAbs_EDGE); expE.More(); expE.Next()) { + TopoDS_Edge anE = TopoDS::Edge(expE.Current()); + B.UpdateEdge(anE, aTol); + } + for (TopExp_Explorer expV (aWire, TopAbs_VERTEX); expV.More(); expV.Next()) { + TopoDS_Vertex aV = TopoDS::Vertex(expV.Current()); + B.UpdateVertex(aV, aTol); + } + //BRepLib::UpdateTolerances(aWire); + // Build face + BRepBuilderAPI_MakeFace MK1 (aWire, isPlanarWanted); + if (MK1.IsDone()) { + theResult = MK1.Shape(); + // Mantis issue 0021432: EDF GEOM: Faces with huge tolerance can be built in GEOM + //if (aTol > PLANAR_FACE_MAX_TOLERANCE) + // aWarning = "MAKE_FACE_TOLERANCE_TOO_BIG"; + } - TColgp_Array1OfPnt aPnts (1,nbEdges); // points of the given wire - BRepTools_WireExplorer aWE1 (theWire); - Standard_Integer vi = 1; - for (; aWE1.More() && vi <= nbEdges; aWE1.Next(), vi++) { - aPnts(vi) = BRep_Tool::Pnt(TopoDS::Vertex(aWE1.CurrentVertex())); - } + return aWarning; +} - // Find maximum deviation in vertices - TopExp_Explorer exp (aFace, TopAbs_VERTEX); - TopTools_MapOfShape mapShape; - for (; exp.More(); exp.Next()) { - if (mapShape.Add(exp.Current())) { - TopoDS_Vertex aV = TopoDS::Vertex(exp.Current()); - Standard_Real aTolV = BRep_Tool::Tolerance(aV); - gp_Pnt aP = BRep_Tool::Pnt(aV); - Standard_Real min_dist = aP.Distance(aPnts(1)); - for (vi = 2; vi <= nbEdges; vi++) { - min_dist = Min(min_dist, aP.Distance(aPnts(vi))); - } - aTol = Max(aTol, aTolV); - aTol = Max(aTol, min_dist); - } - } +//======================================================================= +//function : MakeAnyFace +//purpose : +//======================================================================= +TCollection_AsciiString GEOMImpl_Block6Explorer::MakeAnyFace (const TopoDS_Wire& theWire, + TopoDS_Shape& theResult) +{ + TCollection_AsciiString aWarning; - if ((*((Handle(BRep_TFace)*)&aFace.TShape()))->Tolerance() < aTol) { - (*((Handle(BRep_TFace)*)&aFace.TShape()))->Tolerance(aTol); - } - theResult = aFace; - } - } - } else { - // try to update wire tolerances to build a planar face + // try to build a face on any surface under the edges of the wire + BRepBuilderAPI_MakeFace MK (theWire, Standard_False); + if (MK.IsDone()) { + theResult = MK.Shape(); + return aWarning; + } -#if 1 //(OCC_VERSION_MAJOR < 6) || (OCC_VERSION_MAJOR == 6 && OCC_VERSION_MINOR <= 1) - // Find a deviation - Standard_Real aToleranceReached, aTol; - BRepLib_FindSurface aFS; - aFS.Init(theWire, -1., isPlanarWanted); - aToleranceReached = aFS.ToleranceReached(); - aTol = aFS.Tolerance(); + // try to construct filling surface + BRepOffsetAPI_MakeFilling MF; - if (!aFS.Found()) { - aFS.Init(theWire, aToleranceReached, isPlanarWanted); - if (!aFS.Found()) return; - aToleranceReached = aFS.ToleranceReached(); - aTol = aFS.Tolerance(); - } - aTol = Max(1.2 * aToleranceReached, aTol); - - // Copy the wire, bacause it can be updated with very-very big tolerance here - BRepBuilderAPI_Copy aMC (theWire); - if (!aMC.IsDone()) return; - TopoDS_Wire aWire = TopoDS::Wire(aMC.Shape()); - // Update tolerances to - BRep_Builder B; - for (TopExp_Explorer expE (aWire, TopAbs_EDGE); expE.More(); expE.Next()) { - TopoDS_Edge anE = TopoDS::Edge(expE.Current()); - B.UpdateEdge(anE, aTol); + Standard_Integer nbEdges = 0; + BRepTools_WireExplorer aWE (theWire); + for (; aWE.More(); aWE.Next(), nbEdges++) { + MF.Add(TopoDS::Edge(aWE.Current()), GeomAbs_C0); + } + + MF.Build(); + if (!MF.IsDone()) { + aWarning = "BRepOffsetAPI_MakeFilling failed"; + return aWarning; + } + + // Result of filling + TopoDS_Shape aFace = MF.Shape(); + + // 12.04.2006 for PAL12149 begin + Handle(Geom_Surface) aGS = BRep_Tool::Surface(TopoDS::Face(aFace)); + BRepBuilderAPI_MakeFace MK1 (aGS, theWire); + if (MK1.IsDone()) { + TopoDS_Shape aFace1 = MK1.Shape(); + + BRepCheck_Analyzer ana (aFace1, false); + if (!ana.IsValid()) { + TopoDS_Shape aFace2; + ShHealOper_ShapeProcess aHealer; + aHealer.Perform(aFace1, aFace2); + if (aHealer.isDone()) + theResult = aFace2; } - for (TopExp_Explorer expV (aWire, TopAbs_VERTEX); expV.More(); expV.Next()) { - TopoDS_Vertex aV = TopoDS::Vertex(expV.Current()); - B.UpdateVertex(aV, aTol); + } + // 12.04.2006 for PAL12149 end + + if (theResult.IsNull()) { // try to deal with pure result of filling + // Update tolerance + Standard_Real aTol = MF.G0Error(); + + TColgp_Array1OfPnt aPnts (1,nbEdges); // points of the given wire + BRepTools_WireExplorer aWE1 (theWire); + Standard_Integer vi = 1; + for (; aWE1.More() && vi <= nbEdges; aWE1.Next(), vi++) { + aPnts(vi) = BRep_Tool::Pnt(TopoDS::Vertex(aWE1.CurrentVertex())); } - //BRepLib::UpdateTolerances(aWire); - // Build face - BRepBuilderAPI_MakeFace MK1 (aWire, isPlanarWanted); - if (MK1.IsDone()) { - theResult = MK1.Shape(); - return; + + // Find maximum deviation in vertices + TopExp_Explorer exp (aFace, TopAbs_VERTEX); + TopTools_MapOfShape mapShape; + for (; exp.More(); exp.Next()) { + if (mapShape.Add(exp.Current())) { + TopoDS_Vertex aV = TopoDS::Vertex(exp.Current()); + Standard_Real aTolV = BRep_Tool::Tolerance(aV); + gp_Pnt aP = BRep_Tool::Pnt(aV); + Standard_Real min_dist = aP.Distance(aPnts(1)); + for (vi = 2; vi <= nbEdges; vi++) { + min_dist = Min(min_dist, aP.Distance(aPnts(vi))); + } + aTol = Max(aTol, aTolV); + aTol = Max(aTol, min_dist); + } } -#else // After migration on OCCT version, containing PKV's fix. See bug 8293 - BRepLib_MakeFace aBMF; - aBMF.Init(theWire, isPlanarWanted, Standard_True); - if (aBMF.Error() == BRepLib_FaceDone) { - theResult = aBMF.Shape(); - return; + if ((*((Handle(BRep_TFace)*)&aFace.TShape()))->Tolerance() < aTol) { + (*((Handle(BRep_TFace)*)&aFace.TShape()))->Tolerance(aTol); } -#endif + theResult = aFace; } + + return aWarning; }