mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
Temporary patch to produce empty result in case of any invalidity (spikes, self-intersections, faces inversion).
This commit is contained in:
@@ -1299,9 +1299,11 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
|
|||||||
//
|
//
|
||||||
// split the face by the edges
|
// split the face by the edges
|
||||||
if (!iCountE) {
|
if (!iCountE) {
|
||||||
aLFImages.Append(aF);
|
if (bLimited) {
|
||||||
theImage.Bind(aF, aLFImages);
|
aLFImages.Append(aF);
|
||||||
aBB.Add(aFaces, aF);
|
theImage.Bind(aF, aLFImages);
|
||||||
|
aBB.Add(aFaces, aF);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@@ -1404,7 +1406,7 @@ void BRepOffset_MakeOffset::BuildSplitsOfFaces
|
|||||||
//
|
//
|
||||||
UpdateOrigins(theOrigins, aGF);
|
UpdateOrigins(theOrigins, aGF);
|
||||||
//
|
//
|
||||||
if (aLFImages.Extent() > 1) {
|
if (aLFImages.Extent() >= 1) {
|
||||||
TopTools_ListOfShape aLFKeep;
|
TopTools_ListOfShape aLFKeep;
|
||||||
//
|
//
|
||||||
// check offset faces on the coincidence of the
|
// check offset faces on the coincidence of the
|
||||||
@@ -2954,123 +2956,146 @@ void BRepOffset_MakeOffset::MakeShells()
|
|||||||
aMV1.Perform();
|
aMV1.Perform();
|
||||||
bDone = (aMV1.ErrorStatus() == 0);
|
bDone = (aMV1.ErrorStatus() == 0);
|
||||||
if (bDone) {
|
if (bDone) {
|
||||||
|
//
|
||||||
|
TopoDS_Shape aResult = aMV1.Shape();
|
||||||
|
//
|
||||||
|
TopTools_IndexedMapOfShape aMFResult;
|
||||||
|
TopExp::MapShapes(aResult, TopAbs_FACE, aMFResult);
|
||||||
|
//
|
||||||
|
// check the result
|
||||||
|
Standard_Boolean bGood = Standard_True;
|
||||||
|
BOPCol_ListIteratorOfListOfShape aItLSF(aLSF);
|
||||||
|
for (; aItLSF.More(); aItLSF.Next()) {
|
||||||
|
const TopoDS_Shape& aFx = aItLSF.Value();
|
||||||
|
if (!aMFResult.Contains(aFx)) {
|
||||||
|
const TopTools_ListOfShape& aLFMx = aMV1.Modified(aFx);
|
||||||
|
if (aLFMx.IsEmpty()) {
|
||||||
|
bGood = Standard_False;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
TopoDS_Compound aShells;
|
TopoDS_Compound aShells;
|
||||||
//
|
//
|
||||||
aBB.MakeCompound(aShells);
|
aBB.MakeCompound(aShells);
|
||||||
//
|
//
|
||||||
TopoDS_Shape aResult = aMV1.Shape();
|
if (!bGood) {
|
||||||
//
|
myOffsetShape = aShells;
|
||||||
// collect images of the faces
|
|
||||||
TopTools_MapOfShape aMFaces;
|
|
||||||
aNb = myFaces.Extent();
|
|
||||||
for (i = 1; i <= aNb; ++i) {
|
|
||||||
const TopoDS_Shape& aFEx = myFaces(i);
|
|
||||||
const TopTools_ListOfShape& aLFEx = aMV1.Modified(aFEx);
|
|
||||||
if (!aLFEx.IsEmpty()) {
|
|
||||||
aItLS.Initialize(aLFEx);
|
|
||||||
for (; aItLS.More(); aItLS.Next()) {
|
|
||||||
const TopoDS_Face& aFExIm = *(TopoDS_Face*)&aItLS.Value();
|
|
||||||
aMFaces.Add(aFExIm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
aMFaces.Add(aFEx);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//
|
else {
|
||||||
if (aResult.ShapeType() == TopAbs_COMPOUND) {
|
// collect images of the faces
|
||||||
// collect faces attached to only one solid
|
TopTools_MapOfShape aMFaces;
|
||||||
BOPCol_IndexedDataMapOfShapeListOfShape aMFS;
|
aNb = myFaces.Extent();
|
||||||
BOPCol_ListOfShape aLSF2;
|
for (i = 1; i <= aNb; ++i) {
|
||||||
//
|
const TopoDS_Shape& aFEx = myFaces(i);
|
||||||
BOPTools::MapShapesAndAncestors(aResult, TopAbs_FACE, TopAbs_SOLID, aMFS);
|
const TopTools_ListOfShape& aLFEx = aMV1.Modified(aFEx);
|
||||||
aNb = aMFS.Extent();
|
if (!aLFEx.IsEmpty()) {
|
||||||
bDone = (aNb > 0);
|
aItLS.Initialize(aLFEx);
|
||||||
//
|
for (; aItLS.More(); aItLS.Next()) {
|
||||||
if (bDone) {
|
const TopoDS_Face& aFExIm = *(TopoDS_Face*)&aItLS.Value();
|
||||||
for (i = 1; i <= aNb; ++i) {
|
aMFaces.Add(aFExIm);
|
||||||
const BOPCol_ListOfShape& aLSx = aMFS(i);
|
|
||||||
if (aLSx.Extent() == 1) {
|
|
||||||
const TopoDS_Shape& aFx = aMFS.FindKey(i);
|
|
||||||
aLSF2.Append(aFx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
aMFaces.Add(aFEx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
if (aResult.ShapeType() == TopAbs_COMPOUND) {
|
||||||
|
// collect faces attached to only one solid
|
||||||
|
BOPCol_IndexedDataMapOfShapeListOfShape aMFS;
|
||||||
|
BOPCol_ListOfShape aLSF2;
|
||||||
//
|
//
|
||||||
// make solids from the new list
|
BOPTools::MapShapesAndAncestors(aResult, TopAbs_FACE, TopAbs_SOLID, aMFS);
|
||||||
BOPAlgo_MakerVolume aMV2;
|
aNb = aMFS.Extent();
|
||||||
|
bDone = (aNb > 0);
|
||||||
//
|
//
|
||||||
aMV2.SetArguments(aLSF2);
|
|
||||||
aMV2.SetIntersect(Standard_False);
|
|
||||||
//
|
|
||||||
aMV2.Perform();
|
|
||||||
bDone = (aMV2.ErrorStatus() == 0);
|
|
||||||
if (bDone) {
|
if (bDone) {
|
||||||
aResult = aMV2.Shape();
|
for (i = 1; i <= aNb; ++i) {
|
||||||
if (aResult.ShapeType() == TopAbs_COMPOUND) {
|
const BOPCol_ListOfShape& aLSx = aMFS(i);
|
||||||
BOPCol_ListOfShape aLSF3;
|
if (aLSx.Extent() == 1) {
|
||||||
//
|
const TopoDS_Shape& aFx = aMFS.FindKey(i);
|
||||||
aExp.Init(aResult, TopAbs_FACE);
|
aLSF2.Append(aFx);
|
||||||
for (; aExp.More(); aExp.Next()) {
|
}
|
||||||
const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
|
}
|
||||||
|
//
|
||||||
|
// make solids from the new list
|
||||||
|
BOPAlgo_MakerVolume aMV2;
|
||||||
|
//
|
||||||
|
aMV2.SetArguments(aLSF2);
|
||||||
|
aMV2.SetIntersect(Standard_False);
|
||||||
|
//
|
||||||
|
aMV2.Perform();
|
||||||
|
bDone = (aMV2.ErrorStatus() == 0);
|
||||||
|
if (bDone) {
|
||||||
|
aResult = aMV2.Shape();
|
||||||
|
if (aResult.ShapeType() == TopAbs_COMPOUND) {
|
||||||
|
BOPCol_ListOfShape aLSF3;
|
||||||
//
|
//
|
||||||
// check orientation
|
aExp.Init(aResult, TopAbs_FACE);
|
||||||
if (!anOrigins.Contains(aF)) {
|
for (; aExp.More(); aExp.Next()) {
|
||||||
aLSF3.Append(aF);
|
const TopoDS_Face& aF = *(TopoDS_Face*)&aExp.Current();
|
||||||
continue;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
const TopTools_ListOfShape& aLFOr = anOrigins.FindFromKey(aF);
|
|
||||||
aItLS.Initialize(aLFOr);
|
|
||||||
for (; aItLS.More(); aItLS.Next()) {
|
|
||||||
const TopoDS_Face& aFOr = *(TopoDS_Face*)&aItLS.Value();
|
|
||||||
//
|
//
|
||||||
if (CheckNormals(aF, aFOr)) {
|
// check orientation
|
||||||
|
if (!anOrigins.Contains(aF)) {
|
||||||
aLSF3.Append(aF);
|
aLSF3.Append(aF);
|
||||||
break;
|
continue;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
const TopTools_ListOfShape& aLFOr = anOrigins.FindFromKey(aF);
|
||||||
|
aItLS.Initialize(aLFOr);
|
||||||
|
for (; aItLS.More(); aItLS.Next()) {
|
||||||
|
const TopoDS_Face& aFOr = *(TopoDS_Face*)&aItLS.Value();
|
||||||
|
//
|
||||||
|
if (CheckNormals(aF, aFOr)) {
|
||||||
|
aLSF3.Append(aF);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
//
|
||||||
//
|
// make solid containing most outer faces
|
||||||
// make solid containing most outer faces
|
BOPAlgo_MakerVolume aMV3;
|
||||||
BOPAlgo_MakerVolume aMV3;
|
//
|
||||||
//
|
aMV3.SetArguments(aLSF3);
|
||||||
aMV3.SetArguments(aLSF3);
|
aMV3.SetIntersect(Standard_False);
|
||||||
aMV3.SetIntersect(Standard_False);
|
//
|
||||||
//
|
aMV3.Perform();
|
||||||
aMV3.Perform();
|
bDone = (aMV3.ErrorStatus() == 0);
|
||||||
bDone = (aMV3.ErrorStatus() == 0);
|
if (bDone) {
|
||||||
if (bDone) {
|
aResult = aMV3.Shape();
|
||||||
aResult = aMV3.Shape();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
//
|
|
||||||
TopExp_Explorer aExp(aResult, TopAbs_SHELL);
|
|
||||||
bDone = aExp.More();
|
|
||||||
for (; aExp.More(); aExp.Next()) {
|
|
||||||
const TopoDS_Shell& aSh = *(TopoDS_Shell*)&aExp.Current();
|
|
||||||
//
|
//
|
||||||
TopoDS_Shell aShellNew;
|
TopExp_Explorer aExp(aResult, TopAbs_SHELL);
|
||||||
if (bFaces) {
|
bDone = aExp.More();
|
||||||
aBB.MakeShell(aShellNew);
|
for (; aExp.More(); aExp.Next()) {
|
||||||
|
const TopoDS_Shell& aSh = *(TopoDS_Shell*)&aExp.Current();
|
||||||
//
|
//
|
||||||
TopExp_Explorer aExp(aSh, TopAbs_FACE);
|
TopoDS_Shell aShellNew;
|
||||||
for (; aExp.More(); aExp.Next()) {
|
if (bFaces) {
|
||||||
const TopoDS_Face& aFSh = *(TopoDS_Face*)&aExp.Current();
|
aBB.MakeShell(aShellNew);
|
||||||
if (!aMFaces.Contains(aFSh)) {
|
//
|
||||||
aBB.Add(aShellNew, aFSh);
|
TopExp_Explorer aExp(aSh, TopAbs_FACE);
|
||||||
|
for (; aExp.More(); aExp.Next()) {
|
||||||
|
const TopoDS_Face& aFSh = *(TopoDS_Face*)&aExp.Current();
|
||||||
|
if (!aMFaces.Contains(aFSh)) {
|
||||||
|
aBB.Add(aShellNew, aFSh);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
aShellNew = aSh;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
aBB.Add(aShells, aShellNew);
|
||||||
}
|
}
|
||||||
else {
|
myOffsetShape = aShells;
|
||||||
aShellNew = aSh;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
aBB.Add(aShells, aShellNew);
|
|
||||||
}
|
}
|
||||||
myOffsetShape = aShells;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4126,17 +4151,16 @@ Standard_Boolean CheckBiNormals
|
|||||||
const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
|
const TopTools_IndexedDataMapOfShapeListOfShape& theOrigins,
|
||||||
const TopTools_MapOfShape& theMFence,
|
const TopTools_MapOfShape& theMFence,
|
||||||
Standard_Boolean& bKeep,
|
Standard_Boolean& bKeep,
|
||||||
Standard_Boolean& bRem)
|
Standard_Boolean& bRemove)
|
||||||
{
|
{
|
||||||
Standard_Boolean bChecked;
|
Standard_Boolean bChecked;
|
||||||
|
Standard_Integer aNbEdgesChecked;
|
||||||
Standard_Real anAngle;
|
Standard_Real anAngle;
|
||||||
|
TopTools_ListOfShape aLEInv;
|
||||||
//
|
//
|
||||||
bKeep = Standard_False;
|
aNbEdgesChecked = 0;
|
||||||
bRem = Standard_True;
|
|
||||||
bChecked = Standard_False;
|
|
||||||
//
|
//
|
||||||
const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm);
|
const TopoDS_Wire& aWIm = BRepTools::OuterWire(aFIm);
|
||||||
//
|
|
||||||
TopExp_Explorer aExp(aWIm, TopAbs_EDGE);
|
TopExp_Explorer aExp(aWIm, TopAbs_EDGE);
|
||||||
for (; aExp.More(); aExp.Next()) {
|
for (; aExp.More(); aExp.Next()) {
|
||||||
const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aExp.Current();
|
const TopoDS_Edge& aEIm = *(TopoDS_Edge*)&aExp.Current();
|
||||||
@@ -4152,7 +4176,6 @@ Standard_Boolean CheckBiNormals
|
|||||||
const TopTools_ListOfShape& aLEOr = theOrigins.FindFromKey(aEIm);
|
const TopTools_ListOfShape& aLEOr = theOrigins.FindFromKey(aEIm);
|
||||||
const TopoDS_Shape& aSOr = aLEOr.First();
|
const TopoDS_Shape& aSOr = aLEOr.First();
|
||||||
if (aSOr.ShapeType() != TopAbs_EDGE) {
|
if (aSOr.ShapeType() != TopAbs_EDGE) {
|
||||||
bRem = Standard_False;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@@ -4180,13 +4203,6 @@ Standard_Boolean CheckBiNormals
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
if (theMFence.Contains(aEIm)) {
|
|
||||||
bChecked = Standard_True;
|
|
||||||
bKeep = Standard_True;
|
|
||||||
bRem = Standard_False;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//
|
|
||||||
const TopoDS_Edge& aEOr = *(TopoDS_Edge*)&aLEOr.First();
|
const TopoDS_Edge& aEOr = *(TopoDS_Edge*)&aLEOr.First();
|
||||||
//
|
//
|
||||||
TopoDS_Edge aEOrF;
|
TopoDS_Edge aEOrF;
|
||||||
@@ -4206,19 +4222,44 @@ Standard_Boolean CheckBiNormals
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
bChecked = Standard_True;
|
++aNbEdgesChecked;
|
||||||
// check coincidence of bi-normals
|
//
|
||||||
anAngle = aDB1.Angle(aDB2);
|
anAngle = aDB1.Angle(aDB2);
|
||||||
if (Abs(anAngle - M_PI) < Precision::Confusion()) {
|
if (Abs(anAngle - M_PI) < Precision::Confusion()) {
|
||||||
bRem = bRem && Standard_True;
|
aLEInv.Append(aEIm);
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
bRem = Standard_False;
|
//
|
||||||
bKeep = Standard_True;
|
bChecked = (aNbEdgesChecked > 0);
|
||||||
|
if (!bChecked) {
|
||||||
|
return bChecked;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// decide whether to remove the split face or not
|
||||||
|
bKeep = Standard_True;
|
||||||
|
bRemove = Standard_False;
|
||||||
|
//
|
||||||
|
if (aLEInv.IsEmpty()) {
|
||||||
|
return bChecked;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
TopTools_ListIteratorOfListOfShape aItLS(aLEInv);
|
||||||
|
for (; aItLS.More(); aItLS.Next()) {
|
||||||
|
const TopoDS_Shape& aE = aItLS.Value();
|
||||||
|
if (theMFence.Contains(aE)) {
|
||||||
|
bKeep = Standard_False;
|
||||||
|
bRemove = Standard_True;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
if (!bRemove) {
|
||||||
|
if (aNbEdgesChecked == aLEInv.Extent()) {
|
||||||
|
bKeep = Standard_False;
|
||||||
|
bRemove = Standard_True;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
return bChecked;
|
return bChecked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user