mirror of
https://git.salome-platform.org/gitpub/modules/geom.git
synced 2025-01-22 14:50:33 +05:00
Mantis issue 0021432: EDF GEOM: Faces with huge tolerance can be built in GEOM.
This commit is contained in:
parent
d394961f4a
commit
0c1af31f54
@ -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>
|
||||||
|
@ -1202,67 +1202,67 @@ 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.
|
|
||||||
// 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.
|
// Count the number of points in the wire.
|
||||||
gp_Pln plane;
|
// Collect the first three points.
|
||||||
if (is3Pnts) {
|
gp_Pnt p1, p2, p3;
|
||||||
gce_MakePln mkPln(p1, p2, p3);
|
bool is3Pnts (false);
|
||||||
if (mkPln.IsDone()) {
|
bool p1set(false), p2set(false), p3set(false);
|
||||||
plane = mkPln.Value();
|
BRepTools_WireExplorer wexpl (theWire);
|
||||||
}
|
for (; wexpl.More(); wexpl.Next()) {
|
||||||
else {
|
if (!p1set) {
|
||||||
is3Pnts = false;
|
p1set = true;
|
||||||
}
|
p1 = BRep_Tool::Pnt(wexpl.CurrentVertex());
|
||||||
}
|
}
|
||||||
|
else if (!p2set) {
|
||||||
// Construct a face based on the plane (in case of three points in the wire) or
|
p2set = true;
|
||||||
// allow MakeFace to build the plane itself (in case of the number of points is greater than 3).
|
p2 = BRep_Tool::Pnt(wexpl.CurrentVertex());
|
||||||
if (is3Pnts) {
|
}
|
||||||
BRepBuilderAPI_MakeFace MK (plane, theWire, isPlanarWanted);
|
else if (!p3set) {
|
||||||
if (MK.IsDone()) {
|
p3set = true;
|
||||||
theResult = MK.Shape();
|
is3Pnts = true;
|
||||||
return aWarning;
|
p3 = BRep_Tool::Pnt(wexpl.CurrentVertex());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BRepBuilderAPI_MakeFace MK (theWire, isPlanarWanted);
|
is3Pnts = false;
|
||||||
if (MK.IsDone()) {
|
break;
|
||||||
theResult = MK.Shape();
|
}
|
||||||
return aWarning;
|
}
|
||||||
}
|
|
||||||
|
// 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 {
|
else {
|
||||||
// try to build face on plane or on any surface under the edges of the wire
|
|
||||||
BRepBuilderAPI_MakeFace MK (theWire, isPlanarWanted);
|
BRepBuilderAPI_MakeFace MK (theWire, isPlanarWanted);
|
||||||
if (MK.IsDone()) {
|
if (MK.IsDone()) {
|
||||||
theResult = MK.Shape();
|
theResult = MK.Shape();
|
||||||
@ -1270,123 +1270,141 @@ TCollection_AsciiString GEOMImpl_Block6Explorer::MakeFace (const TopoDS_Wire&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isPlanarWanted) {
|
// try to update wire tolerances to build a planar face
|
||||||
// try to construct filling surface
|
|
||||||
BRepOffsetAPI_MakeFilling MF;
|
|
||||||
|
|
||||||
Standard_Integer nbEdges = 0;
|
// Find a deviation
|
||||||
BRepTools_WireExplorer aWE (theWire);
|
Standard_Real aToleranceReached, aTol;
|
||||||
for (; aWE.More(); aWE.Next(), nbEdges++) {
|
BRepLib_FindSurface aFS;
|
||||||
MF.Add(TopoDS::Edge(aWE.Current()), GeomAbs_C0);
|
aFS.Init(theWire, -1., isPlanarWanted);
|
||||||
}
|
aToleranceReached = aFS.ToleranceReached();
|
||||||
|
aTol = aFS.Tolerance();
|
||||||
|
|
||||||
MF.Build();
|
if (!aFS.Found()) {
|
||||||
if (MF.IsDone()) {
|
aFS.Init(theWire, aToleranceReached, isPlanarWanted);
|
||||||
// Result of filling
|
if (!aFS.Found()) return aWarning;
|
||||||
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);
|
|
||||||
aToleranceReached = aFS.ToleranceReached();
|
aToleranceReached = aFS.ToleranceReached();
|
||||||
aTol = aFS.Tolerance();
|
aTol = aFS.Tolerance();
|
||||||
|
}
|
||||||
|
aTol = Max(1.2 * aToleranceReached, aTol);
|
||||||
|
|
||||||
if (!aFS.Found()) {
|
// Mantis issue 0021432: EDF GEOM: Faces with huge tolerance can be built in GEOM
|
||||||
aFS.Init(theWire, aToleranceReached, isPlanarWanted);
|
if (aTol > PLANAR_FACE_MAX_TOLERANCE) {
|
||||||
if (!aFS.Found()) return aWarning;
|
aWarning = MakeAnyFace(theWire, theResult);
|
||||||
aToleranceReached = aFS.ToleranceReached();
|
if (aWarning.IsEmpty() && !theResult.IsNull())
|
||||||
aTol = aFS.Tolerance();
|
aWarning = "MAKE_FACE_TOLERANCE_TOO_BIG";
|
||||||
}
|
return aWarning;
|
||||||
aTol = Max(1.2 * aToleranceReached, aTol);
|
}
|
||||||
|
|
||||||
// Copy the wire, bacause it can be updated with very-very big tolerance here
|
// Copy the wire, bacause it can be updated with very-very big tolerance here
|
||||||
BRepBuilderAPI_Copy aMC (theWire);
|
BRepBuilderAPI_Copy aMC (theWire);
|
||||||
if (!aMC.IsDone()) return aWarning;
|
if (!aMC.IsDone()) return aWarning;
|
||||||
TopoDS_Wire aWire = TopoDS::Wire(aMC.Shape());
|
TopoDS_Wire aWire = TopoDS::Wire(aMC.Shape());
|
||||||
// Update tolerances to <aTol>
|
// Update tolerances to <aTol>
|
||||||
BRep_Builder B;
|
BRep_Builder B;
|
||||||
for (TopExp_Explorer expE (aWire, TopAbs_EDGE); expE.More(); expE.Next()) {
|
for (TopExp_Explorer expE (aWire, TopAbs_EDGE); expE.More(); expE.Next()) {
|
||||||
TopoDS_Edge anE = TopoDS::Edge(expE.Current());
|
TopoDS_Edge anE = TopoDS::Edge(expE.Current());
|
||||||
B.UpdateEdge(anE, aTol);
|
B.UpdateEdge(anE, aTol);
|
||||||
}
|
}
|
||||||
for (TopExp_Explorer expV (aWire, TopAbs_VERTEX); expV.More(); expV.Next()) {
|
for (TopExp_Explorer expV (aWire, TopAbs_VERTEX); expV.More(); expV.Next()) {
|
||||||
TopoDS_Vertex aV = TopoDS::Vertex(expV.Current());
|
TopoDS_Vertex aV = TopoDS::Vertex(expV.Current());
|
||||||
B.UpdateVertex(aV, aTol);
|
B.UpdateVertex(aV, aTol);
|
||||||
}
|
}
|
||||||
//BRepLib::UpdateTolerances(aWire);
|
//BRepLib::UpdateTolerances(aWire);
|
||||||
// Build face
|
// Build face
|
||||||
BRepBuilderAPI_MakeFace MK1 (aWire, isPlanarWanted);
|
BRepBuilderAPI_MakeFace MK1 (aWire, isPlanarWanted);
|
||||||
if (MK1.IsDone()) {
|
if (MK1.IsDone()) {
|
||||||
theResult = MK1.Shape();
|
theResult = MK1.Shape();
|
||||||
if (aTol > PLANAR_FACE_MAX_TOLERANCE)
|
// Mantis issue 0021432: EDF GEOM: Faces with huge tolerance can be built in GEOM
|
||||||
aWarning = "MAKE_FACE_TOLERANCE_TOO_BIG";
|
//if (aTol > PLANAR_FACE_MAX_TOLERANCE)
|
||||||
return aWarning;
|
// aWarning = "MAKE_FACE_TOLERANCE_TOO_BIG";
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // After migration on OCCT version, containing PKV's fix. See bug 8293
|
return aWarning;
|
||||||
BRepLib_MakeFace aBMF;
|
}
|
||||||
aBMF.Init(theWire, isPlanarWanted, Standard_True);
|
|
||||||
if (aBMF.Error() == BRepLib_FaceDone) {
|
//=======================================================================
|
||||||
theResult = aBMF.Shape();
|
//function : MakeAnyFace
|
||||||
return aWarning;
|
//purpose :
|
||||||
}
|
//=======================================================================
|
||||||
#endif
|
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;
|
return aWarning;
|
||||||
|
@ -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 ----------
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user