mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
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.
918 lines
29 KiB
C++
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;
|
|
}
|