1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-06-10 11:34:06 +03:00
occt/src/BOPAlgo/BOPAlgo_CheckerSI.cxx
emv b1d15f53b3 0025477: Boolean Operations with additional tolerance - Fuzzy Boolean operations
Implementation of Fuzzy Boolean operations. Such operations allow to perform Boolean operations on the shapes
with near-coincidence between the entities of these shapes, i.e. between shapes in which some entities from one shape
are intended to be coincide with some entities from the other, but the coincidence is not precise.

API for Boolean operations has been improved to have a possibility to add new options.

Modified entities:
1. New option of setting additional tolerance have been added to the following classes:
class BOPAlgo_ArgumentAnalyzer
class BOPAlgo_BOP
class BOPAlgo_Builder
class BOPAlgo_MakerVolume
class BOPAlgo_PaveFiller
class BOPDS_DS
class BRepAlgoAPI_BooleanOperation
class BRepAlgoAPI_Check
class BRepAlgoAPI_Common
class BRepAlgoAPI_Cut
class BRepAlgoAPI_Fuse
class BRepAlgoAPI_Section

2. Following draw commands have been modified to support new functionality:
BOP commands:
bop b1 b2 [tol]
bcommon r b1 b2 [tol]
bcut r b1 b2 [tol]
bfuse r b1 b2 [tol]
bsection r s1 s2 [-n2d/-n2d1/-n2d2] [-na] [tol]
mkvolume r b1 b2 ... [-c] [-ni] [-s] [tol]
bfillds [-s -t] [tol]

Check commands:
bopcheck Shape [level of check: 0 - 9] [-t -s] [-tol tol]
bopargcheck [-F/O/C/T/S/U] [/R|F|T|V|E|I|P|C|S]] [#BF] [-tol tol]

3. Two new classes have been added to API to provide the root interface for algorithms
class BRepAlgoAPI_Algo
class BRepAlgoAPI_BuilderAlgo

Fix to eliminate the warning.

Test-cases for issue #25477
2014-11-28 12:24:39 +03:00

422 lines
10 KiB
C++

// Created by: Peter KURNEV
// Copyright (c) 2010-2014 OPEN CASCADE SAS
// Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
// Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
// EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// 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 <BOPAlgo_CheckerSI.ixx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_Failure.hxx>
#include <BRepBuilderAPI_Copy.hxx>
#include <TopTools_ListOfShape.hxx>
#include <BOPCol_MapOfShape.hxx>
#include <BOPDS_DS.hxx>
#include <BOPDS_IteratorSI.hxx>
#include <BOPDS_PIteratorSI.hxx>
#include <BOPDS_Interf.hxx>
#include <BOPDS_MapOfPassKey.hxx>
#include <BOPDS_PassKey.hxx>
#include <BOPDS_VectorOfInterfVV.hxx>
#include <BOPDS_VectorOfInterfVE.hxx>
#include <BOPDS_VectorOfInterfVE.hxx>
#include <BOPDS_VectorOfInterfVF.hxx>
#include <BOPDS_VectorOfInterfEF.hxx>
#include <BOPDS_VectorOfInterfFF.hxx>
#include <IntTools_Context.hxx>
#include <BOPTools.hxx>
#include <BOPTools_AlgoTools.hxx>
//=======================================================================
//function :
//purpose :
//=======================================================================
BOPAlgo_CheckerSI::BOPAlgo_CheckerSI()
:
BOPAlgo_PaveFiller()
{
myLevelOfCheck=BOPDS_DS::NbInterfTypes()-1;
myNonDestructive=Standard_True;
}
//=======================================================================
//function : ~
//purpose :
//=======================================================================
BOPAlgo_CheckerSI::~BOPAlgo_CheckerSI()
{
}
//=======================================================================
//function : SetLevelOfCheck
//purpose :
//=======================================================================
void BOPAlgo_CheckerSI::SetLevelOfCheck(const Standard_Integer theLevel)
{
Standard_Integer aNbLists;
//
aNbLists=BOPDS_DS::NbInterfTypes();
if (theLevel >= 0 && theLevel < aNbLists) {
myLevelOfCheck = theLevel;
}
}
//=======================================================================
//function : SetNonDestructive
//purpose :
//=======================================================================
void BOPAlgo_CheckerSI::SetNonDestructive(const Standard_Boolean theFlag)
{
myNonDestructive=theFlag;
}
//=======================================================================
//function : NonDestructive
//purpose :
//=======================================================================
Standard_Boolean BOPAlgo_CheckerSI::NonDestructive() const
{
return myNonDestructive;
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void BOPAlgo_CheckerSI::Init()
{
myErrorStatus=0;
//
Clear();
//
// 1. myDS
myDS=new BOPDS_DS(myAllocator);
myDS->SetArguments(myArguments);
myDS->SetFuzzyValue(myFuzzyValue);
myDS->Init();
//
// 2.myIterator
BOPDS_PIteratorSI theIterSI=new BOPDS_IteratorSI(myAllocator);
theIterSI->SetDS(myDS);
theIterSI->Prepare();
theIterSI->UpdateByLevelOfCheck(myLevelOfCheck);
//
myIterator=theIterSI;
//
// 3 myContext
myContext=new IntTools_Context;
//
myErrorStatus=0;
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void BOPAlgo_CheckerSI::Perform()
{
try {
Standard_Integer iErr;
//
OCC_CATCH_SIGNALS
//
myErrorStatus=0;
if (myArguments.Extent()!=1) {
myErrorStatus=10;
return;
}
//
if (myNonDestructive) {
PrepareCopy();
if (myErrorStatus) {
return;
}
}
//
BOPAlgo_PaveFiller::Perform();
iErr=myErrorStatus;
//
PostTreat();
if (myErrorStatus) {
iErr=myErrorStatus;
}
//
if (myNonDestructive) {
PostTreatCopy();
if (myErrorStatus) {
iErr=myErrorStatus;
}
}
//
if (iErr) {
myErrorStatus=iErr;
}
}
//
catch (Standard_Failure) {
if (myNonDestructive) {
PostTreatCopy();
}
//
myErrorStatus=11;
}
}
//=======================================================================
//function : PostTreat
//purpose :
//=======================================================================
void BOPAlgo_CheckerSI::PostTreat()
{
Standard_Integer i, aNb, n1, n2;
BOPDS_PassKey aPK;
//
myErrorStatus=0;
//
BOPDS_MapOfPassKey& aMPK=
*((BOPDS_MapOfPassKey*)&myDS->Interferences());
aMPK.Clear();
//
// 0
BOPDS_VectorOfInterfVV& aVVs=myDS->InterfVV();
aNb=aVVs.Extent();
for (i=0; i!=aNb; ++i) {
const BOPDS_InterfVV& aVV=aVVs(i);
aVV.Indices(n1, n2);
if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
continue;
}
aPK.SetIds(n1, n2);
aMPK.Add(aPK);
}
//
// 1
BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE();
aNb=aVEs.Extent();
for (i=0; i!=aNb; ++i) {
const BOPDS_InterfVE& aVE=aVEs(i);
aVE.Indices(n1, n2);
if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
continue;
}
aPK.SetIds(n1, n2);
aMPK.Add(aPK);
}
//
// 2
BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
aNb=aEEs.Extent();
for (i=0; i!=aNb; ++i) {
const BOPDS_InterfEE& aEE=aEEs(i);
aEE.Indices(n1, n2);
if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
continue;
}
aPK.SetIds(n1, n2);
aMPK.Add(aPK);
}
//
// 3
BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
aNb=aVFs.Extent();
for (i=0; i!=aNb; ++i) {
const BOPDS_InterfVF& aVF=aVFs(i);
aVF.Indices(n1, n2);
if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
continue;
}
aPK.SetIds(n1, n2);
aMPK.Add(aPK);
}
//
// 4
BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
aNb=aEFs.Extent();
for (i=0; i!=aNb; ++i) {
const BOPDS_InterfEF& aEF=aEFs(i);
if (aEF.CommonPart().Type()==TopAbs_SHAPE) {
continue;
}
aEF.Indices(n1, n2);
if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
continue;
}
aPK.SetIds(n1, n2);
aMPK.Add(aPK);
}
//
// 5
BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
aNb=aFFs.Extent();
for (i=0; i!=aNb; ++i) {
Standard_Boolean bTangentFaces, bFlag;
Standard_Integer aNbC, aNbP, j, iFound;
//
const BOPDS_InterfFF& aFF=aFFs(i);
aFF.Indices(n1, n2);
//
bTangentFaces=aFF.TangentFaces();
aNbP=aFF.Points().Extent();
const BOPDS_VectorOfCurve& aVC=aFF.Curves();
aNbC=aVC.Extent();
if (!aNbP && !aNbC && !bTangentFaces) {
continue;
}
//
iFound=0;
if (bTangentFaces) {
const TopoDS_Face& aF1=*((TopoDS_Face*)&myDS->Shape(n1));
const TopoDS_Face& aF2=*((TopoDS_Face*)&myDS->Shape(n2));
bFlag=BOPTools_AlgoTools::AreFacesSameDomain
(aF1, aF2, myContext);
if (bFlag) {
++iFound;
}
}
else {
for (j=0; j!=aNbC; ++j) {
const BOPDS_Curve& aNC=aVC(j);
const BOPDS_ListOfPaveBlock& aLPBC=aNC.PaveBlocks();
if (aLPBC.Extent()) {
++iFound;
break;
}
}
}
//
if (!iFound) {
continue;
}
//
aPK.SetIds(n1, n2);
aMPK.Add(aPK);
}
//
//
// 6
BOPDS_VectorOfInterfVZ& aVZs=myDS->InterfVZ();
aNb=aVZs.Extent();
for (i=0; i!=aNb; ++i) {
//
const BOPDS_InterfVZ& aVZ=aVZs(i);
aVZ.Indices(n1, n2);
if (myDS->IsNewShape(n1) || myDS->IsNewShape(n2)) {
continue;
}
aPK.SetIds(n1, n2);
aMPK.Add(aPK);
}
//
// 7
BOPDS_VectorOfInterfEZ& aEZs=myDS->InterfEZ();
aNb=aEZs.Extent();
for (i=0; i!=aNb; ++i) {
//
const BOPDS_InterfEZ& aEZ=aEZs(i);
aEZ.Indices(n1, n2);
aPK.SetIds(n1, n2);
aMPK.Add(aPK);
}
//
// 8
BOPDS_VectorOfInterfFZ& aFZs=myDS->InterfFZ();
aNb=aFZs.Extent();
for (i=0; i!=aNb; ++i) {
//
const BOPDS_InterfFZ& aFZ=aFZs(i);
aFZ.Indices(n1, n2);
aPK.SetIds(n1, n2);
aMPK.Add(aPK);
}
//
// 9
BOPDS_VectorOfInterfZZ& aZZs=myDS->InterfZZ();
aNb=aZZs.Extent();
for (i=0; i!=aNb; ++i) {
//
const BOPDS_InterfZZ& aZZ=aZZs(i);
aZZ.Indices(n1, n2);
aPK.SetIds(n1, n2);
aMPK.Add(aPK);
}
}
//=======================================================================
//function : PrepareCopy
//purpose :
//=======================================================================
void BOPAlgo_CheckerSI::PrepareCopy()
{
Standard_Boolean bIsDone;
BRepBuilderAPI_Copy aCopier;
BOPCol_MapOfShape aMSA;
BOPCol_MapIteratorOfMapOfShape aItMS;
//
myErrorStatus=0;
//
myNewOldMap.Clear();
//
const TopoDS_Shape& aSA=myArguments.First();
//
BOPTools::MapShapes(aSA, aMSA);
//
aCopier.Perform(aSA, Standard_False);
bIsDone=aCopier.IsDone();
if (!bIsDone) {
myErrorStatus=12;
return;
}
//
const TopoDS_Shape& aSC=aCopier.Shape();
//
aItMS.Initialize(aMSA);
for(; aItMS.More(); aItMS.Next()) {
const TopoDS_Shape& aSAx=aItMS.Value();
const TopoDS_Shape& aSCx=aCopier.Modified(aSAx).First();
myNewOldMap.Bind(aSCx, aSAx);
}
//
myArguments.Clear();
myArguments.Append(aSC);
}
//=======================================================================
//function : PostTreatCopy
//purpose :
//=======================================================================
void BOPAlgo_CheckerSI::PostTreatCopy()
{
Standard_Integer i, aNb;
//
myErrorStatus=0;
//
aNb=myDS->NbSourceShapes();
for (i=0; i!=aNb; ++i) {
BOPDS_ShapeInfo& aSI=myDS->ChangeShapeInfo(i);
const TopoDS_Shape& aSCi=aSI.Shape();
if (!myNewOldMap.IsBound(aSCi)) {
myErrorStatus=13;
return;
}
//
const TopoDS_Shape& aSAi=myNewOldMap.Find(aSCi);
aSI.SetShape(aSAi);
}
}
//
// myErrorStatus:
//
// 10 - The number of the arguments is not 1
// 11 - Exception is caught
// 12 - BRepBuilderAPI_Copy is not done
// 13 - myNewOldMap doe not contain DS shape