1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00
Files
occt/src/BOPDS/BOPDS_SubIterator.cxx
emv 2bcaa8d588 0028284: Avoid classification of sub-shapes of arguments of BOPs relatively solids during Intersection phase
1. The methods PerformVZ, PerformEZ, PerformFZ and PerformZZ have been transferred from BOPAlgo_PaveFiller to BOPAlgo_CheckerSI class
to perform intersection of sub-shapes with solids only in self-intersection mode.

2. The checks for solids built from the same (shared) faces have been added into methods building the result of Boolean operations -
BOPAlgo_BOP::BuildRC() and BOPAlgo_BOP::BuildSolid().

3. Since the NonDestructive mode is now natively supported by the BOPAlgo_PaveFiller the methods providing the support of this mode by CheckerSI
(BOPAlgo_CheckerSI::PrepareCopy() and BOPAlgo_CheckerSI::PostTreatCopy()) are not needed and have been removed.

4. The pairs of sub-shapes with interfering bounding boxes are now sorted before real intersection to guarantee the constant order of
intersection of sub-shapes and produce more stable result. The class BOPDS_PassKey has been replaced with simpler class BOPDS_Pair.

5. The class BOPDS_SubIterator has been refactored.

6. Test cases for the issue.

7. Adjustment of the test case boolean volumemaker D2.
2017-03-13 11:38:47 +03:00

175 lines
5.0 KiB
C++

// Created by: Peter KURNEV
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BOPDS_SubIterator.hxx>
#include <Bnd_Box.hxx>
#include <BOPCol_BoxBndTree.hxx>
#include <BOPDS_DS.hxx>
#include <BOPDS_Pair.hxx>
#include <BOPDS_MapOfPair.hxx>
#include <NCollection_UBTreeFiller.hxx>
#include <TopoDS_Shape.hxx>
#include <algorithm>
//=======================================================================
//function : BOPDS_SubIterator
//purpose :
//=======================================================================
BOPDS_SubIterator::BOPDS_SubIterator()
:
myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
myList(1, myAllocator)
{
myDS=NULL;
}
//=======================================================================
//function : BOPDS_SubIterator
//purpose :
//=======================================================================
BOPDS_SubIterator::BOPDS_SubIterator(const Handle(NCollection_BaseAllocator)& theAllocator)
:
myAllocator(theAllocator),
myList(1, myAllocator)
{
myDS=NULL;
}
//=======================================================================
//function : ~
//purpose :
//=======================================================================
BOPDS_SubIterator::~BOPDS_SubIterator()
{
}
//=======================================================================
// function: Initialize
// purpose:
//=======================================================================
void BOPDS_SubIterator::Initialize()
{
// sort interfering pairs for constant order of intersection
std::stable_sort(myList.begin(), myList.end());
// initialize iterator to access the pairs
myIterator.Init(myList);
}
//=======================================================================
// function: Value
// purpose:
//=======================================================================
void BOPDS_SubIterator::Value(Standard_Integer& theI1,
Standard_Integer& theI2) const
{
Standard_Integer iT1, iT2, n1, n2;
//
const BOPDS_Pair& aPKB = myIterator.Value();
aPKB.Indices(n1, n2);
//
iT1=(Standard_Integer)(myDS->ShapeInfo(n1).ShapeType());
iT2=(Standard_Integer)(myDS->ShapeInfo(n2).ShapeType());
//
theI1=n1;
theI2=n2;
if (iT1<iT2) {
theI1=n2;
theI2=n1;
}
}
//=======================================================================
// function: Prepare
// purpose:
//=======================================================================
void BOPDS_SubIterator::Prepare()
{
myList.Clear();
//
if (!myDS){
return;
}
//
if (!mySubSet1->Extent() || !mySubSet2->Extent()) {
return;
}
//
myList.SetIncrement(2 * (mySubSet1->Extent() + mySubSet2->Extent()));
//
Intersect();
}
//=======================================================================
// function: Intersect
// purpose:
//=======================================================================
void BOPDS_SubIterator::Intersect()
{
Standard_Integer i, j, iTi, iTj;
BOPCol_BoxBndTree aBBTree;
NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
//
BOPCol_ListIteratorOfListOfInteger aIt(*mySubSet1);
for (; aIt.More(); aIt.Next()) {
i = aIt.Value();
//
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
const Bnd_Box& aBoxEx = aSI.Box();
//
aTreeFiller.Add(i, aBoxEx);
}
//
aTreeFiller.Fill();
//
BOPDS_MapOfPair aMPKFence;
//
aIt.Initialize(*mySubSet2);
for (; aIt.More(); aIt.Next()) {
i = aIt.Value();
//
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
const Bnd_Box& aBoxEx = aSI.Box();
//
BOPCol_BoxBndTreeSelector aSelector;
aSelector.SetBox(aBoxEx);
Standard_Integer aNbSD = aBBTree.Select(aSelector);
if (!aNbSD) {
continue;
}
//
iTi = BOPDS_Tools::TypeToInteger(aSI.ShapeType());
//
const BOPCol_ListOfInteger& aLI = aSelector.Indices();
BOPCol_ListIteratorOfListOfInteger aItLI(aLI);
for (; aItLI.More(); aItLI.Next()) {
j = aItLI.Value();
//
const BOPDS_ShapeInfo& aSJ = myDS->ShapeInfo(j);
iTj = BOPDS_Tools::TypeToInteger(aSJ.ShapeType());
//
// avoid interfering of the same shapes and shape with its sub-shapes
if ((i == j) || ((iTi < iTj) && aSI.HasSubShape(j)) ||
((iTi > iTj) && aSJ.HasSubShape(i))) {
continue;
}
//
BOPDS_Pair aPair(j, i);
if (aMPKFence.Add(aPair)) {
myList.Append(aPair);
}
}
}
}