X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGEOMImpl%2FGEOMImpl_Block6Explorer.cxx;h=27056c52c354fce18c03978be2420b2a73f4de6a;hb=3059f9d5521dd7c91c35c50afbd6beb18b8826fd;hp=71987a990e9ed8aa34fe0496304fd7a2cc41251a;hpb=d3dd282390888d7dc091ba2c2ffe7923bd7458e6;p=modules%2Fgeom.git diff --git a/src/GEOMImpl/GEOMImpl_Block6Explorer.cxx b/src/GEOMImpl/GEOMImpl_Block6Explorer.cxx index 71987a990..27056c52c 100644 --- a/src/GEOMImpl/GEOMImpl_Block6Explorer.cxx +++ b/src/GEOMImpl/GEOMImpl_Block6Explorer.cxx @@ -1,16 +1,43 @@ -using namespace std; - -#include - -#include "GEOMImpl_Block6Explorer.hxx" +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// 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 + +#include + +#include #include "utilities.h" #include #include +#include +#include +#include #include #include #include +#include +#include +#include #include #include #include @@ -34,8 +61,11 @@ using namespace std; #include #include +#include + #include #include +#include #include #include @@ -720,7 +750,8 @@ void GEOMImpl_Block6Explorer::InitByBlockAndVertices (const TopoDS_Shape& theBlo TopTools_IndexedMapOfShape aFaceEdges; TopExp::MapShapes(myFaces(1), TopAbs_EDGE, aFaceEdges); - for (Standard_Integer i = 1; i <= 4; i++) { + Standard_Integer i = 1; + for (; i <= 4; i++) { // Get i-th vertex of the face 1 TopoDS_Shape Vi = myVertices(vertex_id(1, i)); if (!MB.Contains(Vi)) { @@ -757,7 +788,7 @@ void GEOMImpl_Block6Explorer::InitByBlockAndVertices (const TopoDS_Shape& theBlo } // 3. Store edges of the second (opposite to the first) face - for (Standard_Integer i = 1; i <= 4; i++) { + for (i = 1; i <= 4; i++) { // Get i-th and (i+1)-th vertices of the face 2 TopoDS_Shape Vi = myVertices(vertex_id(2, i)); TopoDS_Shape Vj = myVertices(vertex_id(2, mod4(i + 1))); @@ -792,7 +823,7 @@ void GEOMImpl_Block6Explorer::InitByBlockAndVertices (const TopoDS_Shape& theBlo Standard_TypeMismatch::Raise("Block has wrong number of edges"); } - for (Standard_Integer i = 2; i <= NBFACES; i++) { + for (i = 2; i <= NBFACES; i++) { TopoDS_Shape Ei1 = myEdges(edge_id(i, 1)); TopoDS_Shape Ei2 = myEdges(edge_id(i, 2)); const TopTools_ListOfShape& aFacesOfEi1 = MBE.FindFromKey(Ei1); @@ -915,7 +946,8 @@ void GEOMImpl_Block6Explorer::InitByTwoFaces (const TopoDS_Shape& theFace1, Standard_Real Dist_min = RealLast(); // try all possible locations to find the best (with minimum sum distance) - for (Standard_Integer i = 1; i <= 4; i++) { + Standard_Integer i = 1; + for (; i <= 4; i++) { // try direct orientation Standard_Real Dist_plus = aPnts1(1).Distance(aPnts2(i)) + aPnts1(2).Distance(aPnts2(mod4(i + 1))) + @@ -941,7 +973,7 @@ void GEOMImpl_Block6Explorer::InitByTwoFaces (const TopoDS_Shape& theFace1, // 3. Put vertices and edges of the second face to they // permanent location in and - for (Standard_Integer i = 1; i <= 4; i++) { + for (i = 1; i <= 4; i++) { Standard_Integer nb = mod4(i_min + s_min*(i - 1)); if (aPnts1(i).Distance(aPnts2(nb)) < Precision::Confusion()) { @@ -954,6 +986,19 @@ void GEOMImpl_Block6Explorer::InitByTwoFaces (const TopoDS_Shape& theFace1, myEdges(edge_id(2, i)) = anEdges2(nb); } + // check the wires closure + TopoDS_Wire wire1 = TopoDS::Wire(aWire1); + TopoDS_Wire wire2 = TopoDS::Wire(aWire2); + TopoDS_Vertex aV1, aV2; + + TopExp::Vertices(wire1, aV1, aV2); + if ( !aV1.IsNull() && !aV2.IsNull() && aV1.IsSame(aV2) ) + aWire1.Closed( true ); + + TopExp::Vertices(wire2, aV1, aV2); + if ( !aV1.IsNull() && !aV2.IsNull() && aV1.IsSame(aV2) ) + aWire2.Closed( true ); + // 4. Generate side surface if (!aWire1.Closed() || !aWire2.Closed()) { // BRepOffsetAPI_ThruSections is not applicable on not closed wires @@ -1155,15 +1200,74 @@ void GEOMImpl_Block6Explorer::MakeFace (const TopoDS_Wire& theWire, const Standard_Boolean isPlanarWanted, TopoDS_Shape& theResult) { - // 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; + // 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; + } + } + + // 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; + } + } + else { + BRepBuilderAPI_MakeFace MK (theWire, isPlanarWanted); + if (MK.IsDone()) { + theResult = MK.Shape(); + return; + } + } + } + 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; + } } - // try to construct filling surface if (!isPlanarWanted) { + // try to construct filling surface BRepOffsetAPI_MakeFilling MF; Standard_Integer nbEdges = 0; @@ -1177,37 +1281,105 @@ void GEOMImpl_Block6Explorer::MakeFace (const TopoDS_Wire& theWire, // Result of filling TopoDS_Shape aFace = MF.Shape(); - // Update tolerance - Standard_Real aTol = MF.G0Error(); - - TColgp_Array1OfPnt aPnts (1,nbEdges); // points of the given wire - aWE = BRepTools_WireExplorer(theWire); - Standard_Integer vi = 1; - for (; aWE.More() && vi <= nbEdges; aWE.Next(), vi++) { - aPnts(vi) = BRep_Tool::Pnt(TopoDS::Vertex(aWE.CurrentVertex())); + // 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 (theResult.IsNull()) { // try to deal with pure result of filling + // Update tolerance + Standard_Real aTol = MF.G0Error(); - // 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))); + 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())); + } + + // 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); } - aTol = Max(aTol, aTolV); - aTol = Max(aTol, min_dist); } - } - if ((*((Handle(BRep_TFace)*)&aFace.TShape()))->Tolerance() < aTol) { - (*((Handle(BRep_TFace)*)&aFace.TShape()))->Tolerance(aTol); + if ((*((Handle(BRep_TFace)*)&aFace.TShape()))->Tolerance() < aTol) { + (*((Handle(BRep_TFace)*)&aFace.TShape()))->Tolerance(aTol); + } + theResult = aFace; } - theResult = aFace; } + } else { + // try to update wire tolerances to build a planar face + +#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(); + + 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); + } + 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(); + return; + } + +#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; + } +#endif } }