diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts
index ac6f6b94f..14a87c7aa 100644
--- a/src/GEOMGUI/GEOM_msg_en.ts
+++ b/src/GEOMGUI/GEOM_msg_en.ts
@@ -627,7 +627,8 @@ Please, select face, shell or solid and try again
- Tolerance of resulting face is too big
+ Cannot build a planar face: required tolerance is
+ too big. Non-planar face is built.
diff --git a/src/GEOMImpl/GEOMImpl_Block6Explorer.cxx b/src/GEOMImpl/GEOMImpl_Block6Explorer.cxx
index 48f179cf8..6ec0ebf1d 100644
--- a/src/GEOMImpl/GEOMImpl_Block6Explorer.cxx
+++ b/src/GEOMImpl/GEOMImpl_Block6Explorer.cxx
@@ -1202,67 +1202,67 @@ TCollection_AsciiString GEOMImpl_Block6Explorer::MakeFace (const TopoDS_Wire&
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());
}
-
- // 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 if (!p2set) {
+ p2set = true;
+ p2 = BRep_Tool::Pnt(wexpl.CurrentVertex());
+ }
+ else if (!p3set) {
+ p3set = true;
+ is3Pnts = true;
+ p3 = BRep_Tool::Pnt(wexpl.CurrentVertex());
}
else {
- BRepBuilderAPI_MakeFace MK (theWire, isPlanarWanted);
- if (MK.IsDone()) {
- theResult = MK.Shape();
- return aWarning;
- }
+ 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 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();
@@ -1270,123 +1270,141 @@ TCollection_AsciiString GEOMImpl_Block6Explorer::MakeFace (const TopoDS_Wire&
}
}
- 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 (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()));
- }
-
- // 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);
- }
- }
-
- 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
-
-#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);
+ 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);
- 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;
+ }
- // 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();
- if (aTol > PLANAR_FACE_MAX_TOLERANCE)
- aWarning = "MAKE_FACE_TOLERANCE_TOO_BIG";
- return aWarning;
- }
-
-#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 aWarning;
- }
-#endif
+ // 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";
+ }
+
+ return aWarning;
+}
+
+//=======================================================================
+//function : MakeAnyFace
+//purpose :
+//=======================================================================
+TCollection_AsciiString GEOMImpl_Block6Explorer::MakeAnyFace (const TopoDS_Wire& theWire,
+ TopoDS_Shape& theResult)
+{
+ TCollection_AsciiString aWarning;
+
+ // 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;
+ }
+
+ // try to construct filling surface
+ BRepOffsetAPI_MakeFilling MF;
+
+ 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;
+ }
+ }
+ // 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()));
+ }
+
+ // 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);
+ }
+ }
+
+ if ((*((Handle(BRep_TFace)*)&aFace.TShape()))->Tolerance() < aTol) {
+ (*((Handle(BRep_TFace)*)&aFace.TShape()))->Tolerance(aTol);
+ }
+ theResult = aFace;
}
return aWarning;
diff --git a/src/GEOMImpl/GEOMImpl_Block6Explorer.hxx b/src/GEOMImpl/GEOMImpl_Block6Explorer.hxx
index ea47dfe37..4e1395a70 100644
--- a/src/GEOMImpl/GEOMImpl_Block6Explorer.hxx
+++ b/src/GEOMImpl/GEOMImpl_Block6Explorer.hxx
@@ -214,10 +214,26 @@ class GEOMImpl_Block6Explorer
const Standard_Boolean findAll = Standard_False);
// returns number of found faces
+ /*!
+ * Build a face, bound by the given wire.
+ * \param theWire The initial wire to build the face on.
+ * \param isPlanarWanted. If true, try to build a planar face.
+ * \note If isPlanarWanted is true, but planar face cannot be built
+ * with acceptable tolerance, any face will be built.
+ * \return Error or warning description. Empty string in case of success.
+ */
static TCollection_AsciiString MakeFace (const TopoDS_Wire& theWire,
const Standard_Boolean isPlanarWanted,
TopoDS_Shape& theResult);
+ /*!
+ * Build a face, bound by the given wire.
+ * \param theWire The initial wire to build the face on.
+ * \return Error or warning description. Empty string in case of success.
+ */
+ static TCollection_AsciiString MakeAnyFace (const TopoDS_Wire& theWire,
+ TopoDS_Shape& theResult);
+
private:
// ---------- PRIVATE FIELDS ----------
diff --git a/src/GEOM_SWIG/geompyDC.py b/src/GEOM_SWIG/geompyDC.py
index cc02d2bc6..502b9f219 100644
--- a/src/GEOM_SWIG/geompyDC.py
+++ b/src/GEOM_SWIG/geompyDC.py
@@ -1732,7 +1732,8 @@ class geompyDC(GEOM._objref_GEOM_Gen):
# Example: see GEOM_TestAll.py
anObj = self.ShapesOp.MakeFace(theWire, isPlanarWanted)
if anObj is not None and self.ShapesOp.GetErrorCode() == "MAKE_FACE_TOLERANCE_TOO_BIG":
- print "WARNING: Tolerance of resulting face is too big."
+ #print "WARNING: Tolerance of resulting face is too big."
+ print "WARNING: Cannot build a planar face: required tolerance is too big. Non-planar face is built."
else:
RaiseIfFailed("MakeFace", self.ShapesOp)
return anObj