mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-05-25 09:07:26 +08:00
License statement text corrected; compiler warnings caused by Bison 2.41 disabled for MSVC; a few other compiler warnings on 54-bit Windows eliminated by appropriate type cast Wrong license statements corrected in several files. Copyright and license statements added in XSD and GLSL files. Copyright year updated in some files. Obsolete documentation files removed from DrawResources.
924 lines
29 KiB
C++
924 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 <BRepAlgo_BooleanOperation.ixx>
|
|
#include <TopOpeBRep_DSFiller.hxx>
|
|
#include <TopOpeBRepDS_HDataStructure.hxx>
|
|
#include <TopOpeBRepDS_BuildTool.hxx>
|
|
#include <TopOpeBRepTool_OutCurveType.hxx>
|
|
#include <TopOpeBRepTool_GeomTool.hxx>
|
|
#include <BRep_Builder.hxx>
|
|
#include <BRepLib.hxx>
|
|
#include <TopoDS.hxx>
|
|
#include <TopTools_ListOfShape.hxx>
|
|
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
|
#include <TopTools_MapOfShape.hxx>
|
|
#include <BRep_Tool.hxx>
|
|
#include <BRepClass3d_SolidClassifier.hxx>
|
|
|
|
// sewing
|
|
#include <BRepTools_Substitution.hxx>
|
|
#include <BRepBuilderAPI_Sewing.hxx>
|
|
#include <BRepCheck.hxx>
|
|
#include <BRepCheck_Edge.hxx>
|
|
#include <BRepCheck_Shell.hxx>
|
|
|
|
#include <TopOpeBRepDS_DSX.hxx>
|
|
|
|
#include <TopOpeBRepBuild_Tools.hxx>
|
|
#include <TopExp_Explorer.hxx>
|
|
#include <TopExp.hxx>
|
|
#include <TopTools_IndexedMapOfShape.hxx>
|
|
|
|
|
|
#ifdef DEB
|
|
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 DEB
|
|
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 : Delete
|
|
//purpose : alias ~BRepAlgoAPI_BooleanOperation
|
|
//=======================================================================
|
|
void BRepAlgo_BooleanOperation::Delete()
|
|
{
|
|
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();
|
|
}
|
|
|
|
#ifdef DEB
|
|
TopOpeBRepDS_SettraceSPSX_HDS(HDS);
|
|
#endif
|
|
|
|
// 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 DEB
|
|
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 DEB
|
|
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;
|
|
}
|