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:
@@ -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:
|
||||
//=======================================================================
|
||||
|
@@ -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>
|
||||
|
Reference in New Issue
Block a user