1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0028189: Result of Boolean operation is non-manifold wire

1. The result of Boolean operation on the arguments of collection type, containers WIRE/SHELL/COMPSOLID, is also a collection.
The containers of type WIRE included into result should now also (as the SHELLs) have coherent orientation of its sub-shapes.
For that the new method has been implemented (BOPTools_AlgoTools::OrientEdgesOnWire(TopoDS_Shape&)) which reorients edges for correct ordering.
The duplicating containers, i.e. containers with the contents completely included in other containers, are now avoided in the result of BOP.
2. The result of Fuse operation on Compsolids is now also will be Compsolid.
3. Documentation has been updated.
4. New test cases for the issue.
5. Adjusting test cases to current behavior.

Correction of test case bugs/modalg_4/bug726_2 according to the new behavior
This commit is contained in:
emv
2016-12-29 15:42:08 +03:00
committed by apn
parent 400af1bcf6
commit 77a11d3df1
43 changed files with 626 additions and 47 deletions

View File

@@ -18,6 +18,7 @@
#include <BOPCol_IndexedMapOfShape.hxx>
#include <BOPCol_MapOfShape.hxx>
#include <BOPCol_MapOfOrientedShape.hxx>
#include <BOPTools.hxx>
#include <BOPTools_AlgoTools.hxx>
#include <BOPTools_AlgoTools2D.hxx>
@@ -54,6 +55,7 @@
#include <TopAbs_Orientation.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_CompSolid.hxx>
#include <TopoDS_Edge.hxx>
@@ -197,6 +199,94 @@ void BOPTools_AlgoTools::MakeConnexityBlocks
}// for (; aIt.More(); aIt.Next())
}
//=======================================================================
// function: OrientEdgesOnWire
// purpose: Reorient edges on wire for correct ordering
//=======================================================================
void BOPTools_AlgoTools::OrientEdgesOnWire(TopoDS_Shape& theWire)
{
// make vertex-edges connexity map
BOPCol_IndexedDataMapOfShapeListOfShape aVEMap;
BOPTools::MapShapesAndAncestors(theWire, TopAbs_VERTEX, TopAbs_EDGE, aVEMap);
//
if (aVEMap.IsEmpty()) {
return;
}
//
BRep_Builder aBB;
// new wire
TopoDS_Wire aWire;
aBB.MakeWire(aWire);
// fence map
BOPCol_MapOfOrientedShape aMFence;
//
TopoDS_Iterator aIt(theWire);
for (; aIt.More(); aIt.Next()) {
const TopoDS_Edge& aEC = TopoDS::Edge(aIt.Value());
if (!aMFence.Add(aEC)) {
continue;
}
//
// add edge to a wire as it is
aBB.Add(aWire, aEC);
//
TopoDS_Vertex aV1, aV2;
TopExp::Vertices(aEC, aV1, aV2, Standard_True);
//
if (aV1.IsSame(aV2)) {
// closed edge, go to the next edge
continue;
}
//
// orient the adjacent edges
for (Standard_Integer i = 0; i < 2; ++i) {
TopoDS_Shape aVC = !i ? aV1 : aV2;
//
for (;;) {
const BOPCol_ListOfShape& aLE = aVEMap.FindFromKey(aVC);
if (aLE.Extent() != 2) {
// free vertex or multi-connexity, go to the next edge
break;
}
//
Standard_Boolean bStop = Standard_True;
//
BOPCol_ListIteratorOfListOfShape aItLE(aLE);
for (; aItLE.More(); aItLE.Next()) {
const TopoDS_Edge& aEN = TopoDS::Edge(aItLE.Value());
if (aMFence.Contains(aEN)) {
continue;
}
//
TopoDS_Vertex aVN1, aVN2;
TopExp::Vertices(aEN, aVN1, aVN2, Standard_True);
if (aVN1.IsSame(aVN2)) {
// closed edge, go to the next edge
break;
}
//
// change orientation if necessary and go to the next edges
if ((!i && aVC.IsSame(aVN2)) || (i && aVC.IsSame(aVN1))) {
aBB.Add(aWire, aEN);
}
else {
aBB.Add(aWire, aEN.Reversed());
}
aMFence.Add(aEN);
aVC = aVC.IsSame(aVN1) ? aVN2 : aVN1;
bStop = Standard_False;
break;
}
//
if (bStop) {
break;
}
}
}
}
//
theWire = aWire;
}
//=======================================================================
// function: OrientFacesOnShell
// purpose:
//=======================================================================

View File

@@ -193,8 +193,12 @@ public:
//! theLCB (as list of compounds)
//! in terms of connexity by the shapes of theType
Standard_EXPORT static void MakeConnexityBlocks (const TopoDS_Shape& theS, const TopAbs_ShapeEnum theType1, const TopAbs_ShapeEnum theType2, BOPCol_ListOfShape& theLCB);
Standard_EXPORT static void OrientFacesOnShell (TopoDS_Shape& theS);
//! Correctly orients edges on the wire
Standard_EXPORT static void OrientEdgesOnWire (TopoDS_Shape& theWire);
//! Correctly orients faces on the shell
Standard_EXPORT static void OrientFacesOnShell (TopoDS_Shape& theShell);
//! Provides valid values of tolerances for the shape <theS>