1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00
occt/src/BRepAlgo/BRepAlgo_BooleanOperation.cxx
ski 536a3cb80c 0027525: Coding - eliminate warnings on Windows for OCCT with static type of libraries
Useless *.cxx files were removed to eliminate linker warning LNK4221.

Package TopOpeBRepDS was cleaned up from old debugging routines.

Merged OSD_signal_WNT.cxx into OSD_signal.cxx

Class Standard_ErrorHandlerCallback was moved into the Standard_ErrorHandler class as nested class Callback

Eliminated warning about unused variable.
2016-07-14 13:21:33 +03:00

918 lines
29 KiB
C++

// Created on: 1993-10-15
// Created by: Remi LEQUETTE
// Copyright (c) 1993-1999 Matra Datavision
// 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.
#define TRC 0
#define MODIF 1
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepAlgo_BooleanOperation.hxx>
#include <BRepBuilderAPI_Sewing.hxx>
#include <BRepCheck.hxx>
#include <BRepCheck_Edge.hxx>
#include <BRepCheck_Shell.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <BRepLib.hxx>
#include <BRepTools_Substitution.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopOpeBRep_DSFiller.hxx>
#include <TopOpeBRepBuild_HBuilder.hxx>
#include <TopOpeBRepBuild_Tools.hxx>
#include <TopOpeBRepDS_BuildTool.hxx>
#include <TopOpeBRepDS_HDataStructure.hxx>
#include <TopOpeBRepTool_GeomTool.hxx>
#include <TopOpeBRepTool_OutCurveType.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
// sewing
#ifdef OCCT_DEBUG
extern Standard_Boolean TopOpeBRepTool_GetcontextNOSEW();
#endif
#define Opecom(st1,st2) (((st1)==TopAbs_IN) && ((st2)==TopAbs_IN))
#define Opefus(st1,st2) (((st1)==TopAbs_OUT) && ((st2)==TopAbs_OUT))
#define Opecut(st1,st2) (((st1)==TopAbs_OUT) && ((st2)==TopAbs_IN))
// -------------------------------------------------------------------
static void Sub_Classify(TopExp_Explorer& Ex,
const TopAbs_State St1,
TopTools_ListOfShape& Solids2,
BRep_Builder& BB,
TopTools_ListIteratorOfListOfShape& LIter,
TopoDS_Shape& myShape);
#ifdef OCCT_DEBUG
Standard_IMPORT Standard_Integer TopOpeBRepTool_BOOOPE_CHECK_DEB;
#endif
//modified by NIZHNY-MZV Wed Apr 19 17:19:11 2000
//see comments at the top of file TopOpeBRepBuild_Builder1.cxx
//about using of this global variable
extern Standard_Boolean GLOBAL_USE_NEW_BUILDER;
//
//modified by NIZNHY-PKV Sun Dec 15 17:17:56 2002 f
extern void FDSCNX_Close();// see TopOpeBRepDS_connex.cxx
extern void FDSSDM_Close();// see TopOpeBRepDS_samdom.cxx
//=======================================================================
//function : ~BRepAlgo_BooleanOperation
//purpose :
//=======================================================================
BRepAlgo_BooleanOperation::~BRepAlgo_BooleanOperation()
{
FDSSDM_Close();
FDSCNX_Close();
}
//modified by NIZNHY-PKV Sun Dec 15 17:17:58 2002 t
//=======================================================================
//function : BRepAlgoAPI_BooleanOperation
//purpose :
//=======================================================================
BRepAlgo_BooleanOperation::BRepAlgo_BooleanOperation(const TopoDS_Shape& S1,
const TopoDS_Shape& S2)
: myS1(S1),myS2(S2),myBuilderCanWork(Standard_False)
{
TopOpeBRepDS_BuildTool BT;
myHBuilder = new TopOpeBRepBuild_HBuilder(BT);
}
//=======================================================================
//function : PerformDS
//purpose :
//=======================================================================
void BRepAlgo_BooleanOperation::PerformDS()
{
// const Standard_Boolean CheckShapes = Standard_True;
// create a data structure
Handle(TopOpeBRepDS_HDataStructure) HDS;
if (myHBuilder->DataStructure().IsNull())
HDS = new TopOpeBRepDS_HDataStructure();
else {
HDS = myHBuilder->DataStructure();
HDS->ChangeDS().Init();
}
// fill the data Structure
TopOpeBRep_DSFiller DSFiller;
// define face/face intersection tolerances
Standard_Boolean forcetoli = Standard_False;
if (forcetoli) {
Standard_Real tolarc=0,toltang=0;
TopOpeBRep_ShapeIntersector& tobsi = DSFiller.ChangeShapeIntersector();
TopOpeBRep_FacesIntersector& tobfi = tobsi.ChangeFacesIntersector();
tobfi.ForceTolerances(tolarc,toltang);
}
DSFiller.Insert(myS1,myS2,HDS);
// 020499 : JYL : reject if there is an edge of the SD
// not coded sameparameter and not degenerated
Standard_Boolean esp = HDS->EdgesSameParameter();
Standard_Boolean tede = Standard_True;
if (!esp) {
Standard_Integer i,n = HDS->NbShapes();
for (i = 1 ; i <= n; i++) {
const TopoDS_Shape& s = HDS->Shape(i);
if ( s.ShapeType() == TopAbs_EDGE ) {
const TopoDS_Edge& e = TopoDS::Edge(s);
Standard_Boolean sp = BRep_Tool::SameParameter(e);
Standard_Boolean de = BRep_Tool::Degenerated(e);
if ( !sp && !de ) {
tede = Standard_False;
break;
}
}
}
}
myBuilderCanWork = (esp || tede) ;
#ifdef OCCT_DEBUG
if (!esp) cout<<"BRepAlgo_BooleanOperation(DEB) some edges not SameParameter"<<endl;
#endif
if (!myBuilderCanWork) return;
Standard_Real tol3dAPPROX = 1e-7;
Standard_Real tol2dAPPROX = 1e-7;
// set tolerance values used by the APPROX process
TopOpeBRepDS_BuildTool& BTofBuilder = myHBuilder->ChangeBuildTool();
TopOpeBRepTool_GeomTool& GTofBTofBuilder = BTofBuilder.ChangeGeomTool();
GTofBTofBuilder.SetTolerances(tol3dAPPROX,tol2dAPPROX);
//modified by NIZHNY-MZV Thu Apr 20 09:35:44 2000
//see comments at the top of file TopOpeBRepBuild_Builder1.cxx
//about using of this global variable
GLOBAL_USE_NEW_BUILDER = Standard_True;
myHBuilder->Perform(HDS,myS1,myS2);
GLOBAL_USE_NEW_BUILDER = Standard_False;
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void BRepAlgo_BooleanOperation::Perform(const TopAbs_State St1,
const TopAbs_State St2)
{
if ( ! BuilderCanWork() ) {
return;
}
// modif JYL suite aux modifs LBR #if MODIF ...
// on privilegie le traitement KPart (si c'en est un)
// a tous les autres
Standard_Integer kp = myHBuilder->IsKPart();
BRep_Builder BB;
Standard_Boolean sewing = Standard_True;
if ( kp ) {
//modified by NIZHNY-MZV Thu Apr 20 09:34:33 2000
//see comments at the top of file TopOpeBRepBuild_Builder1.cxx
//about using of this global variable
GLOBAL_USE_NEW_BUILDER = Standard_True;
myHBuilder->MergeKPart(St1,St2);
GLOBAL_USE_NEW_BUILDER = Standard_False;
BB.MakeCompound(TopoDS::Compound(myShape));
Done();
TopTools_ListIteratorOfListOfShape its(myHBuilder->Merged(myS1,St1));
for(; its.More(); its.Next()) BB.Add(myShape,its.Value());
}
else {
#if MODIF
//======================================================================
//== Exploration of input shapes
//== Creation of the list of solids
//== Creation of the list of faces OUT OF solid
//== Creation of the list of edges OUT OF face
Standard_Integer nbs1,nbs2,nbf1,nbf2,nbe1,nbe2,nbv1,nbv2;
TopTools_ListOfShape Solids1,Solids2,Faces1,Faces2,Edges1,Edges2,Vertex1,Vertex2;
TopExp_Explorer Ex;
for(Ex.Init(myS1,TopAbs_SOLID),nbs1=0; Ex.More(); Ex.Next()) {
Solids1.Append(Ex.Current()); nbs1++;
}
for(Ex.Init(myS2,TopAbs_SOLID),nbs2=0; Ex.More(); Ex.Next()) {
Solids2.Append(Ex.Current()); nbs2++;
}
//== Faces not in a solid
for(Ex.Init(myS1,TopAbs_FACE,TopAbs_SOLID),nbf1=0; Ex.More(); Ex.Next()) {
Faces1.Append(Ex.Current()); nbf1++;
}
for(Ex.Init(myS2,TopAbs_FACE,TopAbs_SOLID),nbf2=0; Ex.More(); Ex.Next()) {
Faces2.Append(Ex.Current()); nbf2++;
}
//== Edges not in a solid
for(Ex.Init(myS1,TopAbs_EDGE,TopAbs_FACE),nbe1=0; Ex.More(); Ex.Next()) {
Edges1.Append(Ex.Current()); nbe1++;
}
for(Ex.Init(myS2,TopAbs_EDGE,TopAbs_FACE),nbe2=0; Ex.More(); Ex.Next()) {
Edges2.Append(Ex.Current()); nbe2++;
}
//== Vertices not in an edge
for(Ex.Init(myS1,TopAbs_VERTEX,TopAbs_EDGE),nbv1=0; Ex.More(); Ex.Next()) {
Vertex1.Append(Ex.Current()); nbv1++;
}
for(Ex.Init(myS2,TopAbs_VERTEX,TopAbs_EDGE),nbv2=0; Ex.More(); Ex.Next()) {
Vertex2.Append(Ex.Current()); nbv2++;
}
//-- cout<<"Solids1: "<<nbs1<<" Faces1: "<<nbf1<<" Edges1:"<<nbe1<<" Vtx1:"<<nbv1<<endl;
//-- cout<<"Solids2: "<<nbs2<<" Faces2: "<<nbf2<<" Edges2:"<<nbe2<<" Vtx2:"<<nbv2<<endl;
//==
//== Reject operations without direction
//-- Cut Solid by Edge
// Standard_Boolean Correct = Standard_True;
if( (nbs1 && nbs2==0 && St1==TopAbs_OUT && St2==TopAbs_IN)
|| (nbs2 && nbs1==0 && St2==TopAbs_OUT && St1==TopAbs_IN)) {
//-- cout<<"***** Invalid Operation : Cut of a Solid by a Non Solid "<<endl;
Done();
return;
}
if( (nbs1 && nbs2==0 && St1==TopAbs_OUT && St2==TopAbs_OUT)
|| (nbs2 && nbs1==0 && St2==TopAbs_OUT && St1==TopAbs_OUT)) {
//-- cout<<"***** Invalid Operation : Fusion of a Solid and a Non Solid "<<endl;
Done();
return;
}
if( (nbs1>0 && nbs2>0)
&& (nbe1 || nbe2 || nbf1 || nbf2 || nbv1 || nbv2)) {
//-- cout<<"***** Not Yet Implemented : Compound of solid and non Solid"<<endl;
Done();
return;
}
//======================================================================
// make a compound with the new solids
BB.MakeCompound(TopoDS::Compound(myShape));
TopTools_ListIteratorOfListOfShape LIter;
//----------------------------------------------------------------------
TopoDS_Shape SNULL;
if (nbf1 && nbf2) {
SNULL.Nullify();
if ( Opecom(St1,St2) ) {
TopTools_ListIteratorOfListOfShape itloe = myHBuilder->Section();
for(; itloe.More(); itloe.Next()) BB.Add(myShape,itloe.Value());
}
else {
if(nbf1) {
myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
for(LIter.Initialize(Faces1);LIter.More();LIter.Next()) {
if (myHBuilder->IsSplit(LIter.Value(),St1)) {
TopTools_ListIteratorOfListOfShape its;
for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
its.More();its.Next()) BB.Add(myShape,its.Value());
}
else {
const TopoDS_Shape& LV = LIter.Value();
if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
BB.Add(myShape,LV);
}
else {
//-- Classify :
Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
}
//-- End Classification
}
}
} // nbf1
SNULL.Nullify();
if ( Opefus(St1,St2) ) {
if(nbf2) {
myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
for(LIter.Initialize(Faces2);LIter.More();LIter.Next()) {
if (myHBuilder->IsSplit(LIter.Value(),St2)) {
TopTools_ListIteratorOfListOfShape its;
for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
its.More();its.Next()) BB.Add(myShape,its.Value());
}
else {
const TopoDS_Shape& LV = LIter.Value();
if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
BB.Add(myShape,LV);
}
else {
//-- Classify :
Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
}
//-- End Classification
}
}
} // nbf2
} // Fus
}
} // nbf1 && nbf2
else if (nbf1 || nbf2) {
SNULL.Nullify();
if(nbf1) {
myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
// modified by IFV for treating operation between shell and solid
const TopTools_ListOfShape& MergedShapes = myHBuilder->Merged(myS1,St1);
TopTools_IndexedMapOfShape aMapOfFaces;
sewing = Standard_False;
if(MergedShapes.Extent() != 0) {
TopTools_ListIteratorOfListOfShape its(MergedShapes);
for(; its.More(); its.Next()) {
BB.Add(myShape,its.Value());
}
TopExp::MapShapes(myShape, TopAbs_FACE, aMapOfFaces);
}
for(LIter.Initialize(Faces1);LIter.More();LIter.Next()) {
if (myHBuilder->IsSplit(LIter.Value(),St1)) {
TopTools_ListIteratorOfListOfShape its;
for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
its.More();its.Next()) {
if(!aMapOfFaces.Contains(its.Value())) BB.Add(myShape,its.Value());
}
}
else {
const TopoDS_Shape& LV = LIter.Value();
if(!aMapOfFaces.Contains(LV)) {
if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
BB.Add(myShape,LV);
}
else {
//-- Classify :
Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
}
//-- End Classification
}
}
}
} // nbf1
SNULL.Nullify();
if(nbf2) {
myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
// modified by IFV for treating operation between shell and solid
const TopTools_ListOfShape& MergedShapes = myHBuilder->Merged(myS2,St2);
TopTools_IndexedMapOfShape aMapOfFaces;
sewing = Standard_False;
if(MergedShapes.Extent() != 0) {
TopTools_ListIteratorOfListOfShape its(MergedShapes);
for(; its.More(); its.Next()) {
BB.Add(myShape,its.Value());
}
TopExp::MapShapes(myShape, TopAbs_FACE, aMapOfFaces);
}
for(LIter.Initialize(Faces2);LIter.More();LIter.Next()) {
if (myHBuilder->IsSplit(LIter.Value(),St2)) {
TopTools_ListIteratorOfListOfShape its;
for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
its.More();its.Next()) {
if(!aMapOfFaces.Contains(its.Value())) BB.Add(myShape,its.Value());
}
}
else {
const TopoDS_Shape& LV = LIter.Value();
if(!aMapOfFaces.Contains(LV)) {
if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
BB.Add(myShape,LV);
}
else {
//-- Classify :
Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
}
//-- End Classification
}
}
}
} // nbf2
} // (nbf1 || nbf2)
//----------------------------------------------------------------------
if(nbe1) {
myHBuilder->MergeShapes(myS1,St1,SNULL,St2);
for(LIter.Initialize(Edges1);LIter.More();LIter.Next()) {
if (myHBuilder->IsSplit(LIter.Value(),St1)) {
TopTools_ListIteratorOfListOfShape its;
for(its.Initialize(myHBuilder->Splits(LIter.Value(),St1));
its.More();its.Next()) {
BB.Add(myShape,its.Value());
}
}
else {
const TopoDS_Shape& LV = LIter.Value();
if( (LV.Orientation() == TopAbs_EXTERNAL && St1==TopAbs_OUT )
||(LV.Orientation() == TopAbs_INTERNAL && St1==TopAbs_IN )) {
BB.Add(myShape,LV);
}
else {
//-- Classify :
Sub_Classify(Ex,St1,Solids2,BB,LIter,myShape);
}
//-- End Classification
}
}
}
if(nbe2) {
myHBuilder->MergeShapes(SNULL,St1,myS2,St2);
for(LIter.Initialize(Edges2);LIter.More();LIter.Next()) {
if (myHBuilder->IsSplit(LIter.Value(),St2)) {
TopTools_ListIteratorOfListOfShape its;
for(its.Initialize(myHBuilder->Splits(LIter.Value(),St2));
its.More();its.Next()) {
BB.Add(myShape,its.Value());
}
}
else {
const TopoDS_Shape& LV = LIter.Value();
if( (LV.Orientation() == TopAbs_EXTERNAL && St2==TopAbs_OUT )
||(LV.Orientation() == TopAbs_INTERNAL && St2==TopAbs_IN )) {
BB.Add(myShape,LV);
}
else {
//-- Classify :
Sub_Classify(Ex,St2,Solids1,BB,LIter,myShape);
}
//-- End Classification
}
}
}
//----------------------------------------------------------------------
//-- V1:Vertex1 state1 = OUT -> Preserve V1 if V1 is Out all S2
//-- V1:Vertex1 state1 = IN -> Preserve V1 if V1 is In one of S2
if(nbv1 && nbs2) {
if(St1 == TopAbs_IN) {
for(LIter.Initialize(Vertex1);LIter.More();LIter.Next()) {
Standard_Boolean keep = Standard_False;
Standard_Boolean ok = Standard_True;
const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
gp_Pnt P=BRep_Tool::Pnt(V);
Standard_Real Tol = BRep_Tool::Tolerance(V);
TopTools_ListIteratorOfListOfShape SIter;
for(SIter.Initialize(Solids2);
SIter.More() && ok==Standard_True;
SIter.Next()) {
BRepClass3d_SolidClassifier SolClass(SIter.Value());
SolClass.Perform(P,Tol);
if(SolClass.State() == TopAbs_IN) {
ok=Standard_False;
keep = Standard_True;
}
}
if(keep) {
BB.Add(myShape,LIter.Value());
}
}
}
else {
if(St1 == TopAbs_OUT) {
for(LIter.Initialize(Vertex1);LIter.More();LIter.Next()) {
Standard_Boolean keep = Standard_True;
Standard_Boolean ok = Standard_True;
const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
gp_Pnt P=BRep_Tool::Pnt(V);
Standard_Real Tol = BRep_Tool::Tolerance(V);
TopTools_ListIteratorOfListOfShape SIter;
for(SIter.Initialize(Solids2);
SIter.More() && ok==Standard_True;
SIter.Next()) {
BRepClass3d_SolidClassifier SolClass(SIter.Value());
SolClass.Perform(P,Tol);
if(SolClass.State() != TopAbs_OUT) {
keep = Standard_False;
ok = Standard_False;
}
}
if(keep) {
BB.Add(myShape,LIter.Value());
}
}
}
}
}
if(nbv2 && nbs1) {
if(St2 == TopAbs_IN) {
for(LIter.Initialize(Vertex2);LIter.More();LIter.Next()) {
Standard_Boolean keep = Standard_False;
Standard_Boolean ok = Standard_True;
const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
gp_Pnt P=BRep_Tool::Pnt(V);
Standard_Real Tol = BRep_Tool::Tolerance(V);
TopTools_ListIteratorOfListOfShape SIter;
for(SIter.Initialize(Solids1);
SIter.More() && ok==Standard_True;
SIter.Next()) {
BRepClass3d_SolidClassifier SolClass(SIter.Value());
SolClass.Perform(P,Tol);
if(SolClass.State() == TopAbs_IN) {
ok=Standard_False;
keep = Standard_True;
}
}
if(keep) {
BB.Add(myShape,LIter.Value());
}
}
}
else {
if(St2 == TopAbs_OUT) {
for(LIter.Initialize(Vertex2);LIter.More();LIter.Next()) {
Standard_Boolean keep = Standard_True;
Standard_Boolean ok = Standard_True;
const TopoDS_Vertex& V=TopoDS::Vertex(LIter.Value());
gp_Pnt P=BRep_Tool::Pnt(V);
Standard_Real Tol = BRep_Tool::Tolerance(V);
TopTools_ListIteratorOfListOfShape SIter;
for(SIter.Initialize(Solids1);
SIter.More() && ok==Standard_True;
SIter.Next()) {
BRepClass3d_SolidClassifier SolClass(SIter.Value());
SolClass.Perform(P,Tol);
if(SolClass.State() != TopAbs_OUT) {
keep = Standard_False;
ok = Standard_False;
}
}
if(keep) {
BB.Add(myShape,LIter.Value());
}
}
}
}
}
if(nbs1 && nbs2 ) {
myHBuilder->MergeShapes(myS1,St1,myS2,St2);
if(myHBuilder->IsMerged(myS1,St1)) {
TopTools_ListIteratorOfListOfShape its;
its = myHBuilder->Merged(myS1,St1);
Standard_Integer nbSolids = 0;
for(; its.More(); its.Next(), nbSolids++) {
BB.Add(myShape,its.Value());
}
}
}
#else
myHBuilder->MergeSolids(myS1,St1,myS2,St2);
TopTools_ListIteratorOfListOfShape its;
BB.MakeCompound(TopoDS::Compound(myShape));
its = myHBuilder->Merged(myS1,St1);
while (its.More()) {
BB.Add(myShape,its.Value());
its.Next();
}
#endif
// #if MODIF
}
// Creation of the Map used in IsDeleted.
TopExp_Explorer ex;
ex.Init(myShape,TopAbs_FACE);
for (; ex.More(); ex.Next()) myMap.Add(ex.Current());
ex.Init(myShape,TopAbs_EDGE); // for FRIKO
for (; ex.More(); ex.Next()) myMap.Add(ex.Current());
// Checking same parameter of new edges of section
Standard_Real eTol,cTol;
for (myHBuilder->InitSection(1);
myHBuilder->MoreSection();
myHBuilder->NextSection()) {
const TopoDS_Shape& cur = myHBuilder->CurrentSection();
if (cur.ShapeType()==TopAbs_EDGE) {
BRepCheck_Edge bce(TopoDS::Edge(cur));
cTol=bce.Tolerance();
eTol = BRep_Tool::Tolerance(TopoDS::Edge(cur));
if (eTol<cTol) {
BB.UpdateEdge(TopoDS::Edge(cur), cTol);
for (ex.Init(cur, TopAbs_VERTEX); ex.More(); ex.Next()) {
eTol = BRep_Tool::Tolerance(TopoDS::Vertex(ex.Current()));
if (eTol<cTol) {
// Update can only increase tolerance, so if the vertex
// has a greater tolerance thanits edges it is not touched
BB.UpdateVertex(TopoDS::Vertex(ex.Current()), cTol);
}
}
}
}
}
Standard_Real maxTol = RealLast(); // MSV: unlimit tolerance
TopOpeBRepBuild_Tools::CorrectTolerances(myShape,maxTol);
TopExp_Explorer ex1, ex2, ex3;
TopTools_ListOfShape theOldShell, theNewShell;
Standard_Boolean modif =Standard_False;
#ifdef OCCT_DEBUG
Standard_Boolean nosew = TopOpeBRepTool_GetcontextNOSEW();
if (nosew) sewing = Standard_False;
#endif
if (sewing) {
topToSew.Clear();
for (ex1.Init(myShape, TopAbs_SHELL); ex1.More(); ex1.Next()) {
BRepCheck_Shell bcs(TopoDS::Shell(ex1.Current()));
if (bcs.Closed()==BRepCheck_NotClosed) {
// it is required to add them face by face to avoid IsModified on faces
BRepBuilderAPI_Sewing brts;
for (ex3.Init(ex1.Current(), TopAbs_FACE); ex3.More(); ex3.Next()) {
brts.Add(ex3.Current());
}
brts.Perform();
ex2.Init(brts.SewedShape(), TopAbs_SHELL);
if (ex2.More()) {
ex2.Next();
if (!ex2.More()) {
ex2.Init(brts.SewedShape(), TopAbs_SHELL);
theOldShell.Append(ex1.Current());
theNewShell.Append(ex2.Current());
modif =Standard_True;
for (ex3.Init(ex1.Current(), TopAbs_EDGE); ex3.More(); ex3.Next()) {
const TopoDS_Edge& ledg = TopoDS::Edge(ex3.Current());
if (brts.IsSectionBound(ledg)) {
topToSew.Bind(ledg, brts.SectionToBoundary(ledg));
if (!BRep_Tool::SameParameter(brts.SectionToBoundary(ledg))) {
BRepLib::SameParameter(ledg, BRep_Tool::Tolerance(brts.SectionToBoundary(ledg)));
}
}
}
for (ex3.Init(ex1.Current(), TopAbs_FACE); ex3.More(); ex3.Next()) {
if (brts.IsModified(ex3.Current())) {
topToSew.Bind(ex3.Current(), brts.Modified(ex3.Current()));
}
}
}
}
}
}
} // sewing
if (modif) {
BRepTools_Substitution bsub;
TopTools_ListIteratorOfListOfShape itl(theOldShell);
TopTools_ListOfShape forSub;
for (; itl.More();itl.Next()) {
forSub.Append(theNewShell.First());
bsub.Substitute(itl.Value(), forSub);
theNewShell.RemoveFirst();
forSub.Clear();
}
bsub.Build(myShape);
if (bsub.IsCopied(myShape)) {
myShape=(bsub.Copy(myShape)).First();
}
}
Done();
}
//=======================================================================
//function : Builder
//purpose :
//=======================================================================
Handle(TopOpeBRepBuild_HBuilder) BRepAlgo_BooleanOperation::Builder()const
{
return myHBuilder;
}
//=======================================================================
//function : TopoDS_Shape&
//purpose :
//=======================================================================
const TopoDS_Shape& BRepAlgo_BooleanOperation::Shape1() const
{
return myS1;
}
//=======================================================================
//function : TopoDS_Shape&
//purpose :
//=======================================================================
const TopoDS_Shape& BRepAlgo_BooleanOperation::Shape2() const
{
return myS2;
}
//=======================================================================
//function : BuilderCanWork
//purpose :
//=======================================================================
void BRepAlgo_BooleanOperation::BuilderCanWork(const Standard_Boolean Val)
{
myBuilderCanWork = Val;
}
//=======================================================================
//function : BuilderCanWork
//purpose :
//=======================================================================
Standard_Boolean BRepAlgo_BooleanOperation::BuilderCanWork() const
{
return myBuilderCanWork;
}
void Sub_Classify(TopExp_Explorer& Ex,
const TopAbs_State St1,
TopTools_ListOfShape& Solids2,
BRep_Builder& BB,
TopTools_ListIteratorOfListOfShape& LIter,
TopoDS_Shape& myShape) {
Ex.Init(LIter.Value(),TopAbs_VERTEX);
if(Ex.More()) {
if(St1 == TopAbs_IN) {
Standard_Boolean keep = Standard_False;
Standard_Boolean ok = Standard_True;
const TopoDS_Vertex& V=TopoDS::Vertex(Ex.Current());
gp_Pnt P=BRep_Tool::Pnt(V);
Standard_Real Tol = BRep_Tool::Tolerance(V);
TopTools_ListIteratorOfListOfShape SIter;
for(SIter.Initialize(Solids2);
SIter.More() && ok==Standard_True;
SIter.Next()) {
BRepClass3d_SolidClassifier SolClass(SIter.Value());
SolClass.Perform(P,Tol);
if(SolClass.State() == TopAbs_IN) {
ok=Standard_False;
keep = Standard_True;
}
}
if(keep) {
BB.Add(myShape,LIter.Value());
}
}
else {
if(St1 == TopAbs_OUT) {
Standard_Boolean keep = Standard_True;
Standard_Boolean ok = Standard_True;
const TopoDS_Vertex& V=TopoDS::Vertex(Ex.Current());
gp_Pnt P=BRep_Tool::Pnt(V);
Standard_Real Tol = BRep_Tool::Tolerance(V);
TopTools_ListIteratorOfListOfShape SIter;
for(SIter.Initialize(Solids2);
SIter.More() && ok==Standard_True;
SIter.Next()) {
BRepClass3d_SolidClassifier SolClass(SIter.Value());
SolClass.Perform(P,Tol);
if(SolClass.State() != TopAbs_OUT) {
keep = Standard_False;
ok = Standard_False;
}
}
if(keep) {
BB.Add(myShape,LIter.Value());
}
}
}
}
}
//=======================================================================
//function : InitParameters
//purpose : Info on geometry : PCurve, Approx, ...
//=======================================================================
void BRepAlgo_BooleanOperation::InitParameters()
{
TopOpeBRepDS_BuildTool& BTofBuilder = myHBuilder->ChangeBuildTool();
TopOpeBRepTool_GeomTool& GTofBTofBuilder = BTofBuilder.ChangeGeomTool();
GTofBTofBuilder.Define(TopOpeBRepTool_APPROX);
GTofBTofBuilder.DefineCurves(Standard_True);
GTofBTofBuilder.DefinePCurves1(Standard_True);
GTofBTofBuilder.DefinePCurves2(Standard_True);
}
//=======================================================================
//function : Modified
//purpose :
//=======================================================================
const TopTools_ListOfShape& BRepAlgo_BooleanOperation::Modified(const TopoDS_Shape& S)
{
myGenerated.Clear();
TopTools_MapOfShape aMap; // to check if shape can be added in list more then one time
aMap.Clear();
if (myHBuilder->IsSplit(S, TopAbs_OUT)) {
TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_OUT));
for(;It.More();It.Next()) {
if (topToSew.IsBound(It.Value()))
{if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
else
{if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
}
}
if (myHBuilder->IsSplit(S, TopAbs_IN)) {
TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_IN));
for(;It.More();It.Next()) {
if (topToSew.IsBound(It.Value()))
{if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
else
{if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
}
}
if (myHBuilder->IsSplit(S, TopAbs_ON)) {
TopTools_ListIteratorOfListOfShape It(myHBuilder->Splits(S, TopAbs_ON));
for(;It.More();It.Next()) {
if (topToSew.IsBound(It.Value()))
{if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
else
{if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
}
}
if (myHBuilder->IsMerged(S, TopAbs_OUT)) {
TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_OUT));
for(;It.More();It.Next()) {
if (topToSew.IsBound(It.Value()))
{if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
else
{if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
}
}
if (myHBuilder->IsMerged(S, TopAbs_IN)) {
TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_IN));
for(;It.More();It.Next()) {
if (topToSew.IsBound(It.Value()))
{if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
else
{if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
}
}
if (myHBuilder->IsMerged(S, TopAbs_ON)) {
TopTools_ListIteratorOfListOfShape It(myHBuilder->Merged(S, TopAbs_ON));
for(;It.More();It.Next()) {
if (topToSew.IsBound(It.Value()))
{if(aMap.Add(topToSew.Find(It.Value()))) myGenerated.Append(topToSew.Find(It.Value()));}
else
{if(aMap.Add(It.Value())) myGenerated.Append(It.Value());}
}
}
return myGenerated;
}
//=======================================================================
//function : IsDeleted
//purpose :
//=======================================================================
Standard_Boolean BRepAlgo_BooleanOperation::IsDeleted(const TopoDS_Shape& S)
{
Standard_Boolean Deleted = Standard_True;
if (myMap.Contains(S) ||
myHBuilder->IsMerged(S, TopAbs_OUT) ||
myHBuilder->IsMerged(S, TopAbs_IN) ||
myHBuilder->IsMerged(S, TopAbs_ON) ||
myHBuilder->IsSplit (S, TopAbs_OUT) ||
myHBuilder->IsSplit (S, TopAbs_IN) ||
myHBuilder->IsSplit (S, TopAbs_ON))
return Standard_False;
return Deleted;
}