Mantis issue 0021432: EDF GEOM: Faces with huge tolerance can be built in GEOM.

This commit is contained in:
jfa 2012-01-27 10:58:36 +00:00
parent d394961f4a
commit 0c1af31f54
4 changed files with 200 additions and 164 deletions

View File

@ -627,7 +627,8 @@ Please, select face, shell or solid and try again</translation>
</message> </message>
<message> <message>
<source>MAKE_FACE_TOLERANCE_TOO_BIG</source> <source>MAKE_FACE_TOLERANCE_TOO_BIG</source>
<translation>Tolerance of resulting face is too big</translation> <translation>Cannot build a planar face: required tolerance is
too big. Non-planar face is built.</translation>
</message> </message>
<message> <message>
<source>GEOM_FACE_OR_LCS</source> <source>GEOM_FACE_OR_LCS</source>

View File

@ -1202,16 +1202,25 @@ TCollection_AsciiString GEOMImpl_Block6Explorer::MakeFace (const TopoDS_Wire&
const Standard_Boolean isPlanarWanted, const Standard_Boolean isPlanarWanted,
TopoDS_Shape& theResult) 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; TCollection_AsciiString aWarning;
// Workaround for Mantis issue 0020956 // Workaround for Mantis issue 0020956
if (isPlanarWanted) {
// Count the number of points in the wire. // Count the number of points in the wire.
// Collect the first three points. // Collect the first three points.
gp_Pnt p1, p2, p3; gp_Pnt p1, p2, p3;
bool is3Pnts(false); bool is3Pnts (false);
bool p1set(false), p2set(false), p3set(false); bool p1set(false), p2set(false), p3set(false);
BRepTools_WireExplorer wexpl(theWire); BRepTools_WireExplorer wexpl (theWire);
for (; wexpl.More(); wexpl.Next()) { for (; wexpl.More(); wexpl.Next()) {
if (!p1set) { if (!p1set) {
p1set = true; p1set = true;
@ -1235,7 +1244,7 @@ TCollection_AsciiString GEOMImpl_Block6Explorer::MakeFace (const TopoDS_Wire&
// Construct a plane for the case of three points in the wire. // Construct a plane for the case of three points in the wire.
gp_Pln plane; gp_Pln plane;
if (is3Pnts) { if (is3Pnts) {
gce_MakePln mkPln(p1, p2, p3); gce_MakePln mkPln (p1, p2, p3);
if (mkPln.IsDone()) { if (mkPln.IsDone()) {
plane = mkPln.Value(); plane = mkPln.Value();
} }
@ -1260,17 +1269,75 @@ TCollection_AsciiString GEOMImpl_Block6Explorer::MakeFace (const TopoDS_Wire&
return aWarning; return aWarning;
} }
} }
// try to update wire tolerances to build a planar face
// 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 aWarning;
aToleranceReached = aFS.ToleranceReached();
aTol = aFS.Tolerance();
} }
else { aTol = Max(1.2 * aToleranceReached, aTol);
// try to build face on plane or on any surface under the edges of the wire
BRepBuilderAPI_MakeFace MK (theWire, isPlanarWanted); // 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 <aTol>
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()) { if (MK.IsDone()) {
theResult = MK.Shape(); theResult = MK.Shape();
return aWarning; return aWarning;
} }
}
if (!isPlanarWanted) {
// try to construct filling surface // try to construct filling surface
BRepOffsetAPI_MakeFilling MF; BRepOffsetAPI_MakeFilling MF;
@ -1281,7 +1348,11 @@ TCollection_AsciiString GEOMImpl_Block6Explorer::MakeFace (const TopoDS_Wire&
} }
MF.Build(); MF.Build();
if (MF.IsDone()) { if (!MF.IsDone()) {
aWarning = "BRepOffsetAPI_MakeFilling failed";
return aWarning;
}
// Result of filling // Result of filling
TopoDS_Shape aFace = MF.Shape(); TopoDS_Shape aFace = MF.Shape();
@ -1335,59 +1406,6 @@ TCollection_AsciiString GEOMImpl_Block6Explorer::MakeFace (const TopoDS_Wire&
} }
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 aWarning;
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 aWarning;
TopoDS_Wire aWire = TopoDS::Wire(aMC.Shape());
// Update tolerances to <aTol>
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
}
return aWarning; return aWarning;
} }

View File

@ -214,10 +214,26 @@ class GEOMImpl_Block6Explorer
const Standard_Boolean findAll = Standard_False); const Standard_Boolean findAll = Standard_False);
// returns number of found faces // 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, static TCollection_AsciiString MakeFace (const TopoDS_Wire& theWire,
const Standard_Boolean isPlanarWanted, const Standard_Boolean isPlanarWanted,
TopoDS_Shape& theResult); 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:
// ---------- PRIVATE FIELDS ---------- // ---------- PRIVATE FIELDS ----------

View File

@ -1732,7 +1732,8 @@ class geompyDC(GEOM._objref_GEOM_Gen):
# Example: see GEOM_TestAll.py # Example: see GEOM_TestAll.py
anObj = self.ShapesOp.MakeFace(theWire, isPlanarWanted) anObj = self.ShapesOp.MakeFace(theWire, isPlanarWanted)
if anObj is not None and self.ShapesOp.GetErrorCode() == "MAKE_FACE_TOLERANCE_TOO_BIG": 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: else:
RaiseIfFailed("MakeFace", self.ShapesOp) RaiseIfFailed("MakeFace", self.ShapesOp)
return anObj return anObj