mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-06-25 12:04:07 +03:00
1382 lines
38 KiB
C++
Executable File
1382 lines
38 KiB
C++
Executable File
// Created on: 2001-11-02
|
|
// Created by: Peter KURNEV
|
|
// Copyright (c) 2001-2012 OPEN CASCADE SAS
|
|
//
|
|
// The content of this file is subject to the Open CASCADE Technology Public
|
|
// License Version 6.5 (the "License"). You may not use the content of this file
|
|
// except in compliance with the License. Please obtain a copy of the License
|
|
// at http://www.opencascade.org and read it completely before using this file.
|
|
//
|
|
// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
|
|
// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
|
|
//
|
|
// The Original Code and all software distributed under the License is
|
|
// distributed on an "AS IS" basis, without warranty of any kind, and the
|
|
// Initial Developer hereby disclaims all such warranties, including without
|
|
// limitation, any warranties of merchantability, fitness for a particular
|
|
// purpose or non-infringement. Please see the License for the specific terms
|
|
// and conditions governing the rights and limitations under the License.
|
|
|
|
|
|
#include <BOP_ShellSolid.ixx>
|
|
|
|
#include <gp_Dir.hxx>
|
|
#include <Standard_Failure.hxx>
|
|
#include <Standard_ErrorHandler.hxx>
|
|
|
|
#include <BRep_Builder.hxx>
|
|
#include <BRep_Tool.hxx>
|
|
|
|
#include <TColStd_ListIteratorOfListOfInteger.hxx>
|
|
|
|
#include <TopoDS.hxx>
|
|
#include <TopoDS_Face.hxx>
|
|
#include <TopoDS_Edge.hxx>
|
|
#include <TopoDS_Shell.hxx>
|
|
#include <TopoDS_Compound.hxx>
|
|
|
|
#include <TopExp.hxx>
|
|
|
|
#include <TopTools_ListOfShape.hxx>
|
|
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
|
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
|
|
|
#include <BooleanOperations_ShapesDataStructure.hxx>
|
|
|
|
#include <IntTools_Tools.hxx>
|
|
#include <IntTools_Context.hxx>
|
|
|
|
#include <BOP_WireEdgeSet.hxx>
|
|
#include <BOP_SDFWESFiller.hxx>
|
|
#include <BOP_FaceBuilder.hxx>
|
|
#include <BOP_BuilderTools.hxx>
|
|
#include <BOP_CorrectTolerances.hxx>
|
|
#include <BOP_Draw.hxx>
|
|
#include <BOP_Refiner.hxx>
|
|
|
|
#include <BOPTools_DSFiller.hxx>
|
|
#include <BOPTools_InterferencePool.hxx>
|
|
#include <BOPTools_CArray1OfSSInterference.hxx>
|
|
#include <BOPTools_SSInterference.hxx>
|
|
#include <BOPTools_ESInterference.hxx>
|
|
#include <BOPTools_VSInterference.hxx>
|
|
|
|
#include <BOPTools_ListOfPaveBlock.hxx>
|
|
#include <BOPTools_PaveBlock.hxx>
|
|
#include <BOPTools_Tools3D.hxx>
|
|
#include <BOPTools_Curve.hxx>
|
|
|
|
#include <BOPTools_PaveFiller.hxx>
|
|
#include <BOPTools_SplitShapesPool.hxx>
|
|
#include <BOPTools_ListIteratorOfListOfPaveBlock.hxx>
|
|
|
|
#include <BOPTools_SolidStateFiller.hxx>
|
|
#include <BOPTools_PCurveMaker.hxx>
|
|
#include <BOPTools_DEProcessor.hxx>
|
|
|
|
#include <BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger.hxx>
|
|
#include <BOPTColStd_Dump.hxx>
|
|
|
|
#include <BRepTools.hxx>
|
|
#include <Geom_Surface.hxx>
|
|
#include <GeomAPI_ProjectPointOnSurf.hxx>
|
|
|
|
#include <BOP_ShellSolidHistoryCollector.hxx>
|
|
|
|
static Standard_Boolean CheckSameDomainFaceInside(const TopoDS_Face& theFace1,
|
|
const TopoDS_Face& theFace2);
|
|
|
|
//////
|
|
|
|
//=======================================================================
|
|
// function: BOP_ShellSolid::BOP_ShellSolid
|
|
// purpose:
|
|
//=======================================================================
|
|
BOP_ShellSolid::BOP_ShellSolid()
|
|
{
|
|
char* xr=getenv("MDISP");
|
|
if (xr!=NULL) {
|
|
myDraw=0;
|
|
if (!strcmp (xr, "yes")) {
|
|
myDraw=1;
|
|
}
|
|
}
|
|
else {
|
|
myDraw=0;
|
|
}
|
|
myRank=0;
|
|
}
|
|
//=======================================================================
|
|
// function: Destroy
|
|
// purpose:
|
|
//=======================================================================
|
|
void BOP_ShellSolid::Destroy() {}
|
|
|
|
//=======================================================================
|
|
// function: Do
|
|
// purpose:
|
|
//=======================================================================
|
|
void BOP_ShellSolid::Do()
|
|
{
|
|
myErrorStatus=0;
|
|
myIsDone=Standard_False;
|
|
//
|
|
// Filling the DS
|
|
BOPTools_DSFiller aDSFiller;
|
|
aDSFiller.SetShapes (myShape1, myShape2);
|
|
//
|
|
aDSFiller.Perform ();
|
|
//
|
|
DoWithFiller(aDSFiller);
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: DoWithFiller
|
|
// purpose:
|
|
//=======================================================================
|
|
void BOP_ShellSolid::DoWithFiller(const BOPTools_DSFiller& aDSFiller)
|
|
{
|
|
myErrorStatus=0;
|
|
myIsDone=Standard_False;
|
|
//
|
|
myResultMap.Clear();
|
|
myModifiedMap.Clear();
|
|
//
|
|
myDSFiller=(BOPTools_DSFiller*) &aDSFiller;
|
|
//
|
|
|
|
try {
|
|
OCC_CATCH_SIGNALS
|
|
if(!myDSFiller->IsDone()) {
|
|
myErrorStatus = 1;
|
|
BOPTColStd_Dump::PrintMessage("DSFiller is invalid: Can not build result\n");
|
|
return;
|
|
}
|
|
Standard_Boolean bCheckTypes;
|
|
|
|
bCheckTypes=CheckArgTypes();
|
|
if (!bCheckTypes) {
|
|
myErrorStatus=10;
|
|
return;
|
|
}
|
|
//
|
|
Standard_Boolean bIsNewFiller;
|
|
bIsNewFiller=aDSFiller.IsNewFiller();
|
|
|
|
if (bIsNewFiller) {
|
|
Prepare();
|
|
aDSFiller.SetNewFiller(!bIsNewFiller);
|
|
}
|
|
//
|
|
myRank=(myDSFiller->DS().Object().ShapeType()==TopAbs_SHELL) ? 1 : 2;
|
|
//
|
|
DoNewFaces();
|
|
//
|
|
BuildResult();
|
|
//
|
|
// Treat of internals
|
|
CollectInternals();
|
|
BOP_Refiner aRefiner;
|
|
aRefiner.SetShape(myResult);
|
|
aRefiner.SetInternals(myInternals);
|
|
aRefiner.Do();
|
|
//
|
|
//
|
|
BOP_CorrectTolerances::CorrectTolerances(myResult, 0.01);
|
|
//
|
|
FillModified();
|
|
|
|
if(!myHistory.IsNull()) {
|
|
Handle(BOP_ShellSolidHistoryCollector) aHistory =
|
|
Handle(BOP_ShellSolidHistoryCollector)::DownCast(myHistory);
|
|
aHistory->SetResult(myResult, myDSFiller);
|
|
}
|
|
myIsDone=Standard_True;
|
|
}
|
|
catch ( Standard_Failure ) {
|
|
myErrorStatus = 1;
|
|
BOPTColStd_Dump::PrintMessage("Can not build result\n");
|
|
}
|
|
}
|
|
|
|
//=================================================================================
|
|
// function: BuildResult
|
|
// purpose:
|
|
//=================================================================================
|
|
void BOP_ShellSolid::BuildResult()
|
|
{
|
|
const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
|
|
|
|
Standard_Integer i, j, aNb, iRank, aNbFaces;
|
|
BooleanOperations_StateOfShape aState, aStateToCompare;
|
|
BRep_Builder aBB;
|
|
TopoDS_Compound aFCompound, aRes;
|
|
//
|
|
aBB.MakeCompound(aRes);
|
|
//
|
|
// 1. Make aCompound containing all faces for thr Result
|
|
aBB.MakeCompound(aFCompound);
|
|
//
|
|
// 1.1. Old Faces with right 3D-state
|
|
aNb=aDS.NumberOfSourceShapes();
|
|
for (i=1; i<=aNb; i++) {
|
|
const TopoDS_Shape& aS=aDS.Shape(i);
|
|
|
|
if (aS.ShapeType()==TopAbs_FACE){
|
|
if (aDS.Rank(i)==myRank){
|
|
aState=aDS.GetState(i);
|
|
if (aState==BooleanOperations_IN ||
|
|
aState==BooleanOperations_OUT) {
|
|
iRank=aDS.Rank(i);
|
|
aStateToCompare=BOP_BuilderTools::StateToCompare(iRank, myOperation);
|
|
if (aState==aStateToCompare) {
|
|
aBB.Add(aFCompound, aS);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//
|
|
// 1.2. aListOfNewFaces
|
|
TopTools_ListIteratorOfListOfShape anIt(myNewFaces);
|
|
for(; anIt.More(); anIt.Next()) {
|
|
aBB.Add(aFCompound, anIt.Value());
|
|
}
|
|
//
|
|
// 2.
|
|
TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
|
|
TopTools_IndexedMapOfShape aProcessedEdges;
|
|
|
|
TopExp::MapShapesAndAncestors(aFCompound, TopAbs_EDGE, TopAbs_FACE, aEFMap);
|
|
aNb=aEFMap.Extent();
|
|
for (i=1; i<=aNb; i++) {
|
|
const TopoDS_Shape& aE=aEFMap.FindKey(i);
|
|
TopTools_IndexedMapOfShape aFaces;
|
|
Path (aE, aEFMap, aFaces, aProcessedEdges);
|
|
|
|
TopoDS_Shell aShell, aShellNew;
|
|
aBB.MakeShell(aShell);
|
|
|
|
aNbFaces=aFaces.Extent();
|
|
if (aNbFaces) {
|
|
for (j=1; j<=aNbFaces; j++) {
|
|
const TopoDS_Shape& aF=aFaces(j);
|
|
aBB.Add(aShell, aF);
|
|
}
|
|
|
|
OrientFacesOnShell(aShell, aShellNew);
|
|
|
|
aBB.Add(aRes, aShellNew);
|
|
}
|
|
}
|
|
myResult=aRes;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: DoNewFaces
|
|
// purpose:
|
|
//=======================================================================
|
|
void BOP_ShellSolid::DoNewFaces()
|
|
{
|
|
const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
|
|
BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
|
|
BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
|
|
//
|
|
// EF Maps
|
|
const TopoDS_Shape& anObj=aDS.Object();
|
|
const TopoDS_Shape& aTool=aDS.Tool();
|
|
|
|
TopTools_IndexedMapOfShape anEMap;
|
|
TopTools_IndexedDataMapOfShapeListOfShape aMEFObj, aMEFTool;
|
|
TopExp::MapShapesAndAncestors (anObj, TopAbs_EDGE , TopAbs_FACE , aMEFObj);
|
|
TopExp::MapShapesAndAncestors (aTool, TopAbs_EDGE , TopAbs_FACE , aMEFTool);
|
|
//
|
|
// vars
|
|
Standard_Boolean bIsTouchCase, bIsTouch;
|
|
Standard_Integer i, aNb, j, aNbj, iFF, nF1, iRank;
|
|
TopTools_ListOfShape aListOfNewFaces;
|
|
TopAbs_Orientation anOriF1;
|
|
//
|
|
// DoMap
|
|
BOPTColStd_IndexedDataMapOfIntegerIndexedMapOfInteger aFFMap;
|
|
BOP_BuilderTools::DoMap(aFFs, aFFMap);
|
|
|
|
//
|
|
aNb=aFFMap.Extent();
|
|
for (i=1; i<=aNb; i++) {
|
|
//
|
|
// a. Prepare info about the Face nF1 and create WES for nF1
|
|
nF1=aFFMap.FindKey(i);
|
|
const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF1));
|
|
|
|
anOriF1=aF1.Orientation();
|
|
iRank=aDS.Rank(nF1);
|
|
|
|
if (iRank!=myRank) {
|
|
continue;
|
|
}
|
|
|
|
myFace=aF1;
|
|
myFace.Orientation(TopAbs_FORWARD);
|
|
BOP_WireEdgeSet aWES (myFace);
|
|
|
|
const TColStd_IndexedMapOfInteger& aFFIndicesMap=aFFMap.FindFromIndex(i);
|
|
aNbj=aFFIndicesMap.Extent();
|
|
//
|
|
// b. The Switch: Same Domain Faces or Non-Same Domain Faces
|
|
bIsTouchCase=Standard_False;
|
|
for (j=1; j<=aNbj; j++) {
|
|
iFF=aFFIndicesMap(j);
|
|
BOPTools_SSInterference& aFF=aFFs(iFF);
|
|
bIsTouchCase=aFF.IsTangentFaces();
|
|
if (bIsTouchCase) {
|
|
break;
|
|
}
|
|
}
|
|
//
|
|
// c. Filling the WES for nF1
|
|
if (bIsTouchCase) {
|
|
// 1. Add Split Parts having states in accordance with operation
|
|
AddSplitPartsINOUT (nF1, aWES);
|
|
// 2. Add Section Edges to the WES
|
|
for (j=1; j<=aNbj; j++) {
|
|
iFF=aFFIndicesMap(j);
|
|
BOPTools_SSInterference& aFF=aFFs(iFF);
|
|
bIsTouch=aFF.IsTangentFaces();
|
|
if (!bIsTouch) {
|
|
AddSectionPartsSo(nF1, iFF, aWES);
|
|
}
|
|
}
|
|
// 3. Add IN2D, ON2D Parts to the WES
|
|
anEMap.Clear();// xft
|
|
for (j=1; j<=aNbj; j++) {
|
|
iFF=aFFIndicesMap(j);
|
|
BOPTools_SSInterference& aFF=aFFs(iFF);
|
|
bIsTouch=aFF.IsTangentFaces();
|
|
if (bIsTouch) {
|
|
//xf
|
|
//AddINON2DPartsSh(nF1, iFF, aWES);
|
|
AddINON2DPartsSh(nF1, iFF, aWES, anEMap);
|
|
//xt
|
|
}
|
|
}
|
|
// 4. Add EF parts (E (from F2) on F1 ),
|
|
// where F2 is non-same-domain face to F1
|
|
//anEMap.Clear();//xft
|
|
//
|
|
// anEMap will contain all Split parts that has already in aWES
|
|
const TopTools_ListOfShape& aLE=aWES.StartElements();
|
|
TopTools_ListIteratorOfListOfShape anIt;
|
|
anIt.Initialize (aLE);
|
|
for (; anIt.More(); anIt.Next()) {
|
|
TopoDS_Shape& anE=anIt.Value();
|
|
anEMap.Add(anE);
|
|
}
|
|
//
|
|
for (j=1; j<=aNbj; j++) {
|
|
iFF=aFFIndicesMap(j);
|
|
BOPTools_SSInterference& aFF=aFFs(iFF);
|
|
bIsTouch=aFF.IsTangentFaces();
|
|
if (!bIsTouch) {
|
|
AddPartsEFNonSDSh (nF1, iFF, anEMap, aWES);
|
|
AddPartsEENonSDSh (nF1, iFF, anEMap, aWES);
|
|
}
|
|
}
|
|
//
|
|
}// end of if (bIsTouchCase)
|
|
else {
|
|
// 1. Add Split Parts having states in accordance with operation
|
|
AddSplitPartsINOUT (nF1, aWES);
|
|
// 2. Add Split Parts with state ON
|
|
AddSplitPartsONSo (nF1, aMEFObj, aMEFTool, aWES);
|
|
// 3. Add Section Edges to the WES
|
|
for (j=1; j<=aNbj; j++) {
|
|
iFF=aFFIndicesMap(j);
|
|
AddSectionPartsSo(nF1, iFF, aWES);
|
|
}
|
|
// 4. Add EF parts (E (from F2) on F1 )
|
|
anEMap.Clear();
|
|
for (j=1; j<=aNbj; j++) {
|
|
iFF=aFFIndicesMap(j);
|
|
AddPartsEFSo(nF1, iFF, aMEFObj, aMEFTool, anEMap, aWES);
|
|
}
|
|
|
|
}// end of (bIsTouchCase)'s else
|
|
//
|
|
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
// Display the WES
|
|
if (myDraw) {
|
|
const TopTools_ListOfShape& aWESL=aWES.StartElements();
|
|
BOP_Draw::DrawListOfEdgesWithPC (myFace, aWESL, i, "ew_");
|
|
BOP_Draw::Wait();
|
|
}
|
|
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
//
|
|
// d. Build new Faces from myFace
|
|
BOP_FaceBuilder aFB;
|
|
aFB.SetTreatSDScales(1);
|
|
aFB.SetTreatment(0); // 0-Do Internal Edges
|
|
aFB.Do(aWES);
|
|
|
|
const TopTools_ListOfShape& aLF=aFB.NewFaces();
|
|
//
|
|
// e. Do Internal Vertices
|
|
DoInternalVertices(nF1, aLF);
|
|
//
|
|
// f. Orient new faces
|
|
TopTools_ListOfShape aLFx;
|
|
TopTools_ListIteratorOfListOfShape anIt;
|
|
anIt.Initialize(aLF);
|
|
for (; anIt.More(); anIt.Next()) {
|
|
TopoDS_Shape& aFx=anIt.Value();
|
|
aFx.Orientation(anOriF1);
|
|
aListOfNewFaces.Append(aFx);
|
|
aLFx.Append(aFx);
|
|
|
|
if(!myHistory.IsNull()) {
|
|
Handle(BOP_ShellSolidHistoryCollector) aHistory =
|
|
Handle(BOP_ShellSolidHistoryCollector)::DownCast(myHistory);
|
|
|
|
if(!aHistory.IsNull()) {
|
|
aHistory->AddNewFace(aF1, aFx, myDSFiller);
|
|
}
|
|
}
|
|
}
|
|
//
|
|
// Fill "Modified"
|
|
FillModified(aF1, aLFx);
|
|
//
|
|
}// for (i=1; i<=aNb; i++)
|
|
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
// Display the new Faces
|
|
if (myDraw) {
|
|
BOP_Draw::DrawListOfShape(aListOfNewFaces, "fn_");
|
|
}
|
|
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
myNewFaces.Clear();
|
|
myNewFaces.Append(aListOfNewFaces);
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: DetectSDFaces
|
|
// purpose:
|
|
//=======================================================================
|
|
void BOP_ShellSolid::DetectSDFaces()
|
|
{
|
|
const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
|
|
BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
|
|
BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
|
|
//
|
|
Standard_Boolean bFlag;
|
|
Standard_Integer i, aNb, nF1, nF2, iZone, aNbSps, iSenseFlag;
|
|
gp_Dir aDNF1, aDNF2;
|
|
|
|
aNb=aFFs.Extent();
|
|
for (i=1; i<=aNb; i++) {
|
|
bFlag=Standard_False;
|
|
|
|
BOPTools_SSInterference& aFF=aFFs(i);
|
|
|
|
nF1=aFF.Index1();
|
|
nF2=aFF.Index2();
|
|
const TopoDS_Face& aF1=TopoDS::Face(aDS.Shape(nF1));
|
|
const TopoDS_Face& aF2=TopoDS::Face(aDS.Shape(nF2));
|
|
//
|
|
// iSenseFlag;
|
|
const BOPTools_ListOfPaveBlock& aLPB=aFF.PaveBlocks();
|
|
aNbSps=aLPB.Extent();
|
|
|
|
if (!aNbSps) {
|
|
continue;
|
|
}
|
|
|
|
const BOPTools_PaveBlock& aPB=aLPB.First();
|
|
const TopoDS_Edge& aSpE=TopoDS::Edge(aDS.Shape(aPB.Edge()));
|
|
|
|
BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpE, aF1, aDNF1);
|
|
BOPTools_Tools3D::GetNormalToFaceOnEdge (aSpE, aF2, aDNF2);
|
|
iSenseFlag=BOPTools_Tools3D::SenseFlag (aDNF1, aDNF2);
|
|
//
|
|
if (iSenseFlag==1 || iSenseFlag==-1) {
|
|
//
|
|
//
|
|
TopoDS_Face aF1FWD=aF1;
|
|
aF1FWD.Orientation (TopAbs_FORWARD);
|
|
|
|
BOP_WireEdgeSet aWES (aF1FWD);
|
|
BOP_SDFWESFiller aWESFiller(nF1, nF2, *myDSFiller);
|
|
aWESFiller.SetSenseFlag(iSenseFlag);
|
|
aWESFiller.SetOperation(BOP_COMMON);
|
|
aWESFiller.Do(aWES);
|
|
|
|
BOP_FaceBuilder aFB;
|
|
aFB.Do(aWES);
|
|
const TopTools_ListOfShape& aLF=aFB.NewFaces();
|
|
|
|
iZone=0;
|
|
TopTools_ListIteratorOfListOfShape anIt(aLF);
|
|
for (; anIt.More(); anIt.Next()) {
|
|
const TopoDS_Shape& aFR=anIt.Value();
|
|
|
|
if (aFR.ShapeType()==TopAbs_FACE) {
|
|
const TopoDS_Face& aFaceResult=TopoDS::Face(aFR);
|
|
//
|
|
Standard_Boolean bIsValidIn2D, bNegativeFlag;
|
|
bIsValidIn2D=BOPTools_Tools3D::IsValidArea (aFaceResult, bNegativeFlag);
|
|
if (bIsValidIn2D) {
|
|
|
|
if(CheckSameDomainFaceInside(aFaceResult, aF2)) {
|
|
iZone=1;
|
|
break;
|
|
}
|
|
}
|
|
//
|
|
}
|
|
}
|
|
|
|
if (iZone) {
|
|
bFlag=Standard_True;
|
|
aFF.SetStatesMap(aWESFiller.StatesMap());
|
|
}
|
|
|
|
}// if (iSenseFlag)
|
|
|
|
aFF.SetTangentFacesFlag(bFlag);
|
|
aFF.SetSenseFlag (iSenseFlag);
|
|
}// end of for (i=1; i<=aNb; i++)
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: AddSplitPartsINOUT
|
|
// purpose:
|
|
//=======================================================================
|
|
void BOP_ShellSolid::AddSplitPartsINOUT(const Standard_Integer nF1,
|
|
BOP_WireEdgeSet& aWES)
|
|
{
|
|
const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
|
|
const BOPTools_PaveFiller& aPaveFiller=myDSFiller->PaveFiller();
|
|
const BOPTools_SplitShapesPool& aSplitShapesPool=aPaveFiller.SplitShapesPool();
|
|
|
|
Standard_Integer nE, nSp, iRankF1, aNbPB;
|
|
BooleanOperations_StateOfShape aState, aStateCmp;
|
|
TopAbs_Orientation anOr;
|
|
TopExp_Explorer anExp;
|
|
TopoDS_Edge aSS;
|
|
//
|
|
iRankF1=aDS.Rank(nF1);
|
|
aStateCmp=BOP_BuilderTools::StateToCompare(iRankF1, myOperation);
|
|
|
|
anExp.Init(myFace, TopAbs_EDGE);
|
|
for (; anExp.More(); anExp.Next()) {
|
|
const TopoDS_Shape& anE=anExp.Current();
|
|
anOr=anE.Orientation();
|
|
|
|
nE=aDS.ShapeIndex(anE, iRankF1);
|
|
|
|
const BOPTools_ListOfPaveBlock& aLPB=aSplitShapesPool(aDS.RefEdge(nE));
|
|
aNbPB=aLPB.Extent();
|
|
// case: No splits on Egde
|
|
if (!aNbPB) {
|
|
aState=aDS.GetState(nE);
|
|
if (aState==aStateCmp) {
|
|
aSS=TopoDS::Edge(anE);
|
|
//modified by NIZNHY-PKV Mon Sep 19 09:13:59 2011f
|
|
if (anOr==TopAbs_INTERNAL) {
|
|
aSS.Orientation(TopAbs_FORWARD);
|
|
aWES.AddStartElement (aSS);
|
|
aSS.Orientation(TopAbs_REVERSED);
|
|
aWES.AddStartElement (aSS);
|
|
}
|
|
else{
|
|
aSS.Orientation(anOr);
|
|
aWES.AddStartElement (aSS);
|
|
}
|
|
//aSS.Orientation(anOr);
|
|
//aWES.AddStartElement (aSS);
|
|
//modified by NIZNHY-PKV Mon Sep 19 09:14:02 2011t
|
|
}
|
|
continue;
|
|
}
|
|
// case: There are splits on Egde
|
|
BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aLPB);
|
|
for (; aPBIt.More(); aPBIt.Next()) {
|
|
const BOPTools_PaveBlock& aPB=aPBIt.Value();
|
|
nSp=aPB.Edge();
|
|
|
|
aState=aDS.GetState(nSp);
|
|
if (aState==aStateCmp) {
|
|
const TopoDS_Shape& aSplit=aDS.Shape(nSp);
|
|
aSS=TopoDS::Edge(aSplit);
|
|
//modified by NIZNHY-PKV Mon Sep 19 08:58:23 2011f
|
|
if (anOr==TopAbs_INTERNAL) {
|
|
aSS.Orientation(TopAbs_FORWARD);
|
|
aWES.AddStartElement (aSS);
|
|
aSS.Orientation(TopAbs_REVERSED);
|
|
aWES.AddStartElement (aSS);
|
|
}
|
|
else{
|
|
aSS.Orientation(anOr);
|
|
aWES.AddStartElement (aSS);
|
|
}
|
|
//aSS.Orientation(anOr);
|
|
//aWES.AddStartElement (aSS);
|
|
//modified by NIZNHY-PKV Mon Sep 19 08:58:33 2011t
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//=======================================================================
|
|
// function: Prepare
|
|
// purpose:
|
|
//=======================================================================
|
|
void BOP_ShellSolid::Prepare()
|
|
{
|
|
//...
|
|
const BOPTools_PaveFiller& aPaveFiller=myDSFiller->PaveFiller();
|
|
//
|
|
// 1 States
|
|
BOPTools_SolidStateFiller aStateFiller(aPaveFiller);
|
|
aStateFiller.Do();
|
|
//
|
|
// 2 Project section edges on corresp. faces -> P-Curves on edges.
|
|
BOPTools_PCurveMaker aPCurveMaker(aPaveFiller);
|
|
aPCurveMaker.Do();
|
|
//
|
|
// 3. Degenerated Edges Processing
|
|
BOPTools_DEProcessor aDEProcessor(aPaveFiller);
|
|
aDEProcessor.Do();
|
|
//
|
|
// 4. DetectSame Domain Faces
|
|
DetectSDFaces();
|
|
//
|
|
// 5. FillSectionEdges
|
|
FillSectionEdges();
|
|
}
|
|
|
|
///////////////////
|
|
//=======================================================================
|
|
// function: OrientFacesOnShell
|
|
// purpose:
|
|
//=======================================================================
|
|
void BOP_ShellSolid::OrientFacesOnShell (const TopoDS_Shell& aShell,
|
|
TopoDS_Shell& aShellNew)
|
|
{
|
|
Standard_Boolean bIsProcessed1, bIsProcessed2;
|
|
Standard_Integer i, aNbE, aNbF, j;
|
|
TopAbs_Orientation anOrE1, anOrE2;
|
|
|
|
TopTools_IndexedDataMapOfShapeListOfShape aEFMap;
|
|
TopTools_IndexedMapOfShape aProcessedFaces;
|
|
BRep_Builder aBB;
|
|
|
|
aBB.MakeShell(aShellNew);
|
|
|
|
TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aEFMap);
|
|
|
|
aNbE=aEFMap.Extent();
|
|
//
|
|
// One seam edge in aEFMap contains 2 equivalent faces.
|
|
for (i=1; i<=aNbE; i++) {
|
|
TopTools_ListOfShape& aLF=aEFMap.ChangeFromIndex(i);
|
|
|
|
if (aLF.Extent()>1) {
|
|
TopTools_ListOfShape aLFTmp;
|
|
TopTools_IndexedMapOfShape aFM;
|
|
|
|
TopTools_ListIteratorOfListOfShape anIt(aLF);
|
|
for (; anIt.More(); anIt.Next()) {
|
|
const TopoDS_Shape& aF=anIt.Value();
|
|
if (!aFM.Contains(aF)) {
|
|
aFM.Add(aF);
|
|
aLFTmp.Append(aF);
|
|
}
|
|
}
|
|
aLF.Clear();
|
|
aLF=aLFTmp;
|
|
}
|
|
}
|
|
//
|
|
// Do
|
|
for (i=1; i<=aNbE; i++) {
|
|
const TopoDS_Edge& aE=TopoDS::Edge(aEFMap.FindKey(i));
|
|
|
|
if (BRep_Tool::Degenerated(aE)) {
|
|
continue;
|
|
}
|
|
|
|
const TopTools_ListOfShape& aLF=aEFMap.FindFromIndex(i);
|
|
aNbF=aLF.Extent();
|
|
|
|
if (aNbF==2) {
|
|
TopoDS_Face& aF1=TopoDS::Face(aLF.First());
|
|
TopoDS_Face& aF2=TopoDS::Face(aLF.Last() );
|
|
|
|
|
|
bIsProcessed1=aProcessedFaces.Contains(aF1);
|
|
bIsProcessed2=aProcessedFaces.Contains(aF2);
|
|
|
|
if (bIsProcessed1 && bIsProcessed2) {
|
|
continue;
|
|
}
|
|
|
|
if (!bIsProcessed1 && !bIsProcessed2) {
|
|
aProcessedFaces.Add(aF1);
|
|
aBB.Add(aShellNew, aF1);
|
|
|
|
bIsProcessed1=!bIsProcessed1;
|
|
}
|
|
|
|
//
|
|
TopoDS_Face aF1x, aF2x;
|
|
|
|
aF1x=aF1;
|
|
if (bIsProcessed1) {
|
|
j=aProcessedFaces.FindIndex(aF1);
|
|
aF1x=TopoDS::Face(aProcessedFaces.FindKey(j));
|
|
}
|
|
|
|
aF2x=aF2;
|
|
if (bIsProcessed2) {
|
|
j=aProcessedFaces.FindIndex(aF2);
|
|
aF2x=TopoDS::Face(aProcessedFaces.FindKey(j));
|
|
}
|
|
//
|
|
|
|
anOrE1=Orientation(aE, aF1x);
|
|
anOrE2=Orientation(aE, aF2x);
|
|
|
|
if (bIsProcessed1 && !bIsProcessed2) {
|
|
|
|
if (anOrE1==anOrE2) {
|
|
if (!BRep_Tool::IsClosed(aE, aF1) &&
|
|
!BRep_Tool::IsClosed(aE, aF2)) {
|
|
aF2.Reverse();
|
|
}
|
|
}
|
|
aProcessedFaces.Add(aF2);
|
|
aBB.Add(aShellNew, aF2);
|
|
}
|
|
|
|
else if (!bIsProcessed1 && bIsProcessed2) {
|
|
if (anOrE1==anOrE2) {
|
|
if (!BRep_Tool::IsClosed(aE, aF1) &&
|
|
!BRep_Tool::IsClosed(aE, aF2)) {
|
|
aF1.Reverse();
|
|
}
|
|
}
|
|
aProcessedFaces.Add(aF1);
|
|
aBB.Add(aShellNew, aF1);
|
|
}
|
|
}
|
|
}
|
|
//
|
|
//
|
|
for (i=1; i<=aNbE; i++) {
|
|
const TopoDS_Edge& aE=TopoDS::Edge(aEFMap.FindKey(i));
|
|
|
|
if (BRep_Tool::Degenerated(aE)) {
|
|
continue;
|
|
}
|
|
|
|
const TopTools_ListOfShape& aLF=aEFMap.FindFromIndex(i);
|
|
aNbF=aLF.Extent();
|
|
if (aNbF!=2) {
|
|
TopTools_ListIteratorOfListOfShape anIt(aLF);
|
|
for(; anIt.More(); anIt.Next()) {
|
|
const TopoDS_Face& aF=TopoDS::Face(anIt.Value());
|
|
if (!aProcessedFaces.Contains(aF)) {
|
|
aProcessedFaces.Add(aF);
|
|
aBB.Add(aShellNew, aF);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
//function : Orientation
|
|
//purpose :
|
|
//=======================================================================
|
|
TopAbs_Orientation BOP_ShellSolid::Orientation(const TopoDS_Edge& anE,
|
|
const TopoDS_Face& aF)
|
|
{
|
|
TopAbs_Orientation anOr=TopAbs_INTERNAL;
|
|
|
|
TopExp_Explorer anExp;
|
|
anExp.Init(aF, TopAbs_EDGE);
|
|
for (; anExp.More(); anExp.Next()) {
|
|
const TopoDS_Edge& anEF1=TopoDS::Edge(anExp.Current());
|
|
if (anEF1.IsSame(anE)) {
|
|
anOr=anEF1.Orientation();
|
|
break;
|
|
}
|
|
}
|
|
return anOr;
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: Path
|
|
// purpose:
|
|
//=======================================================================
|
|
void BOP_ShellSolid::Path (const TopoDS_Shape& aE,
|
|
const TopTools_IndexedDataMapOfShapeListOfShape& aEFMap,
|
|
TopTools_IndexedMapOfShape& aFaces,
|
|
TopTools_IndexedMapOfShape& aProcessedEdges)
|
|
{
|
|
if (!aProcessedEdges.Contains(aE)) {
|
|
aProcessedEdges.Add(aE);
|
|
|
|
Standard_Integer i, aNbE;
|
|
const TopTools_ListOfShape& aFList=aEFMap.FindFromKey(aE);
|
|
|
|
TopTools_ListIteratorOfListOfShape anIt(aFList);
|
|
for(; anIt.More(); anIt.Next()) {
|
|
const TopoDS_Shape& aF=anIt.Value();
|
|
aFaces.Add(aF);
|
|
|
|
TopTools_IndexedMapOfShape aME;
|
|
TopExp::MapShapes(aF, TopAbs_EDGE, aME);
|
|
aNbE=aME.Extent();
|
|
for (i=1; i<=aNbE; i++) {
|
|
const TopoDS_Shape& aENext=aME(i);
|
|
Path(aENext, aEFMap, aFaces, aProcessedEdges);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: CheckArgTypes
|
|
// purpose:
|
|
//=======================================================================
|
|
Standard_Boolean BOP_ShellSolid::CheckArgTypes(const TopAbs_ShapeEnum theType1,
|
|
const TopAbs_ShapeEnum theType2,
|
|
const BOP_Operation theOperation)
|
|
{
|
|
Standard_Boolean bFlag=Standard_False;
|
|
|
|
if (theType1==TopAbs_SHELL && theType2==TopAbs_SOLID) {
|
|
if (theOperation==BOP_FUSE || theOperation==BOP_CUT21) {
|
|
return bFlag;
|
|
}
|
|
}
|
|
//
|
|
if (theType1==TopAbs_SOLID && theType2==TopAbs_SHELL) {
|
|
if (theOperation==BOP_FUSE || theOperation==BOP_CUT) {
|
|
return bFlag;
|
|
}
|
|
}
|
|
//
|
|
return !bFlag;
|
|
}
|
|
|
|
|
|
//=======================================================================
|
|
// function: CheckArgTypes
|
|
// purpose:
|
|
//=======================================================================
|
|
Standard_Boolean BOP_ShellSolid::CheckArgTypes() const
|
|
{
|
|
// Standard_Boolean bFlag=Standard_False;
|
|
|
|
TopAbs_ShapeEnum aT1, aT2;
|
|
const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
|
|
|
|
aT1=aDS.Object().ShapeType();
|
|
aT2=aDS.Tool().ShapeType();
|
|
//
|
|
// if (aT1==TopAbs_SHELL && aT2==TopAbs_SOLID) {
|
|
// if (myOperation==BOP_FUSE || myOperation==BOP_CUT21) {
|
|
// return bFlag;
|
|
// }
|
|
// }
|
|
// //
|
|
// if (aT1==TopAbs_SOLID && aT2==TopAbs_SHELL) {
|
|
// if (myOperation==BOP_FUSE || myOperation==BOP_CUT) {
|
|
// return bFlag;
|
|
// }
|
|
// }
|
|
//
|
|
// return !bFlag;
|
|
return CheckArgTypes(aT1, aT2, myOperation);
|
|
}
|
|
|
|
|
|
|
|
//=======================================================================
|
|
// function: DoInternalVertices
|
|
// purpose:
|
|
//=======================================================================
|
|
void BOP_ShellSolid::DoInternalVertices(const Standard_Integer nF1,
|
|
const TopTools_ListOfShape& aListOfFaces)
|
|
{
|
|
|
|
const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
|
|
BOPTools_InterferencePool* pIntrPool=(BOPTools_InterferencePool*)&myDSFiller->InterfPool();
|
|
BOPTools_CArray1OfVSInterference& aVFs=pIntrPool->VSInterferences();
|
|
BOPTools_CArray1OfESInterference& aEFs=pIntrPool->ESInterferences();
|
|
BOPTools_CArray1OfSSInterference& aFFs=pIntrPool->SSInterferences();
|
|
|
|
BOPTools_PaveFiller* pPaveFiller=(BOPTools_PaveFiller*) &(myDSFiller->PaveFiller());
|
|
//
|
|
Standard_Integer i, j, nF, aNbFF, aNbVF, aWhat, aWith;
|
|
Standard_Integer nV, iRankF, nE, aNbE, nFx, iOppositeRank, iFlag, iBreakFlag ;
|
|
Standard_Integer aNbEF, nVx1, nVx2, aWh, aWt, aNbC, k;
|
|
Standard_Real U, V;
|
|
//
|
|
|
|
nF=nF1;
|
|
iRankF=aDS.Rank(nF);
|
|
iOppositeRank=(iRankF==1) ? 2 : 1;
|
|
TopTools_IndexedDataMapOfShapeListOfShape aVEMap, aVFMap, aEFMap;
|
|
const TopoDS_Shape& aS=(iRankF==1) ? myShape2 : myShape1;
|
|
TopExp::MapShapesAndAncestors (aS, TopAbs_VERTEX, TopAbs_EDGE, aVEMap);
|
|
TopExp::MapShapesAndAncestors (aS, TopAbs_VERTEX, TopAbs_FACE, aVFMap);
|
|
TopExp::MapShapesAndAncestors (aS, TopAbs_EDGE , TopAbs_FACE, aEFMap);
|
|
|
|
TopTools_ListIteratorOfListOfShape anIt;
|
|
///////////////////////////////////////////////////////////////
|
|
//
|
|
// VF interferences processing
|
|
aNbVF=aVFs.Extent();
|
|
for (i=1; i<=aNbVF; i++) {
|
|
iBreakFlag=0;
|
|
|
|
BOPTools_VSInterference& aVF=aVFs(i);
|
|
|
|
aWhat=aVF.Index1();
|
|
aWith=aVF.Index2();
|
|
|
|
if (aWhat==nF || aWith==nF) {
|
|
TColStd_ListOfInteger aLs;
|
|
|
|
nV=aVF.OppositeIndex(nF);
|
|
|
|
Standard_Integer iRankV;
|
|
iRankV=aDS.Rank(nV);
|
|
|
|
const TopoDS_Vertex& aV=TopoDS::Vertex(aDS.Shape(nV));
|
|
|
|
if (aVEMap.Contains(aV)) {
|
|
const TopTools_ListOfShape& aLE=aVEMap.FindFromKey(aV);
|
|
|
|
anIt.Initialize (aLE);
|
|
for (; anIt.More() && !iBreakFlag; anIt.Next()) {
|
|
const TopoDS_Shape& aE=anIt.Value();
|
|
|
|
nE=aDS.ShapeIndex(aE, iRankV);
|
|
//
|
|
aLs.Clear();
|
|
//
|
|
pPaveFiller->SplitsInFace(nE, nF, aLs);
|
|
aNbE=aLs.Extent();
|
|
if (aNbE) {
|
|
iBreakFlag=1; // next i
|
|
//
|
|
break;
|
|
//
|
|
}
|
|
}
|
|
}
|
|
if (iBreakFlag) {
|
|
continue;
|
|
}
|
|
//
|
|
if (aVFMap.Contains(aV)) {
|
|
const TopTools_ListOfShape& aLF=aVFMap.FindFromKey(aV);
|
|
|
|
anIt.Initialize (aLF);
|
|
for (; anIt.More()&& !iBreakFlag; anIt.Next()) {
|
|
const TopoDS_Shape& aFx=anIt.Value();
|
|
|
|
nFx=aDS.ShapeIndex(aFx, iRankV);
|
|
|
|
aNbFF=aFFs.Extent();
|
|
for (j=1; j<=aNbFF && !iBreakFlag ; j++) {
|
|
BOPTools_SSInterference& aFF=aFFs(j);
|
|
|
|
aWh=aFF.Index1();
|
|
aWt=aFF.Index2();
|
|
if ((aWh==nF && aWt==nFx) || (aWh==nFx && aWt==nF)) {
|
|
BOPTools_SequenceOfCurves& aSCurves=aFF.Curves();
|
|
aNbC=aSCurves.Length();
|
|
for (k=1; k<=aNbC && !iBreakFlag; k++) {
|
|
const BOPTools_Curve& aC=aSCurves(k);
|
|
const BOPTools_ListOfPaveBlock& aLPB=aC.NewPaveBlocks();
|
|
BOPTools_ListIteratorOfListOfPaveBlock anItLPB;
|
|
anItLPB.Initialize (aLPB);
|
|
for (; anItLPB.More() && !iBreakFlag; anItLPB.Next()) {
|
|
const BOPTools_PaveBlock& aPB=anItLPB.Value();
|
|
//
|
|
nVx1=aPB.Pave1().Index();
|
|
nVx2=aPB.Pave1().Index();
|
|
if ((nVx1==nV) || (nVx2==nV)) {
|
|
iBreakFlag=1;
|
|
//
|
|
break;
|
|
//
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//
|
|
if (iBreakFlag) {
|
|
continue;
|
|
}
|
|
//
|
|
// Put Vertex nV on Face j from aListOfFaces
|
|
Standard_Boolean bIsPointInFace;
|
|
|
|
aVF.UV (U, V);
|
|
gp_Pnt2d aP2D (U, V);
|
|
|
|
TopoDS_Vertex aVInternal=aV;
|
|
aVInternal.Orientation(TopAbs_INTERNAL);
|
|
|
|
anIt.Initialize(aListOfFaces);
|
|
for (; anIt.More(); anIt.Next()) {
|
|
TopoDS_Face& aF=TopoDS::Face(anIt.Value());
|
|
//
|
|
IntTools_Context aCtx;
|
|
bIsPointInFace=aCtx.IsPointInFace(aF, aP2D);
|
|
//
|
|
if (bIsPointInFace) {
|
|
BRep_Builder aBB;
|
|
aBB.Add(aF, aVInternal);
|
|
break;
|
|
}
|
|
}
|
|
}// if (aWhat==nF || aWith==nF)
|
|
}// for (i=1; i<=aNbVF; i++)
|
|
///////////////////////////////////////////////////////////////
|
|
//
|
|
// EF interferences processing
|
|
aNbEF=aEFs.Extent();
|
|
|
|
for (i=1; i<=aNbEF; i++) {
|
|
iBreakFlag=0;
|
|
BOPTools_ESInterference& aEF=aEFs(i);
|
|
aWhat=aEF.Index1();
|
|
aWith=aEF.Index2();
|
|
//
|
|
if (aWhat!=nF) {
|
|
if (aWith!=nF) {
|
|
continue;
|
|
}
|
|
}
|
|
//
|
|
nE=aEF.OppositeIndex(nF);
|
|
|
|
const TopoDS_Edge& aE=TopoDS::Edge(aDS.Shape(nE));
|
|
|
|
nV=aEF.NewShape();
|
|
//
|
|
if(!nV){
|
|
continue;
|
|
}
|
|
//
|
|
const TopoDS_Shape& aV=aDS.Shape(nV);
|
|
//
|
|
if (aV.ShapeType()!=TopAbs_VERTEX) {
|
|
continue;
|
|
}
|
|
//
|
|
BOPTools_ListOfPaveBlock aLPBSplits;
|
|
//
|
|
// check split parts in2D for F1
|
|
pPaveFiller->SplitsInFace(nE, nF, aLPBSplits);
|
|
|
|
BOPTools_ListIteratorOfListOfPaveBlock anItx(aLPBSplits);
|
|
for (; anItx.More() && !iBreakFlag; anItx.Next()) {
|
|
const BOPTools_PaveBlock& aPB=anItx.Value();
|
|
nVx1=aPB.Pave1().Index();
|
|
nVx2=aPB.Pave2().Index();
|
|
if (nV==nVx1 || nV==nVx2) {
|
|
iBreakFlag=1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (iBreakFlag){
|
|
continue;
|
|
}
|
|
//
|
|
//
|
|
if (aEFMap.Contains(aE)) {
|
|
const TopTools_ListOfShape& aLF=aEFMap.FindFromKey(aE);
|
|
|
|
anIt.Initialize (aLF);
|
|
for (; anIt.More() && !iBreakFlag; anIt.Next()) {
|
|
const TopoDS_Shape& aFx=anIt.Value();
|
|
nFx=aDS.ShapeIndex(aFx, iOppositeRank);
|
|
|
|
aNbFF=aFFs.Extent();
|
|
for (j=1; j<=aNbFF&& !iBreakFlag; j++) {
|
|
BOPTools_SSInterference& aFF=aFFs(j);
|
|
|
|
aWh=aFF.Index1();
|
|
aWt=aFF.Index2();
|
|
if ((aWh==nF && aWt==nFx) || (aWt==nF && aWh==nFx)) {
|
|
BOPTools_SequenceOfCurves& aSCurves=aFF.Curves();
|
|
aNbC=aSCurves.Length();
|
|
for (k=1; k<=aNbC && !iBreakFlag; k++) {
|
|
const BOPTools_Curve& aC=aSCurves(k);
|
|
const BOPTools_ListOfPaveBlock& aLPB=aC.NewPaveBlocks();
|
|
BOPTools_ListIteratorOfListOfPaveBlock anItLPB;
|
|
anItLPB.Initialize (aLPB);
|
|
for (; anItLPB.More()&& !iBreakFlag; anItLPB.Next()) {
|
|
const BOPTools_PaveBlock& aPB=anItLPB.Value();
|
|
//
|
|
nVx1=aPB.Pave1().Index();
|
|
nVx2=aPB.Pave2().Index();
|
|
if (nV==nVx1 || nV==nVx2) {
|
|
iBreakFlag=1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (iBreakFlag){
|
|
continue;
|
|
}
|
|
}
|
|
//
|
|
// Put Vertex nV on Face j from aListOfFaces
|
|
TopoDS_Vertex aVInternal=TopoDS::Vertex(aV);
|
|
aVInternal.Orientation(TopAbs_INTERNAL);
|
|
TopTools_ListIteratorOfListOfShape anItF;
|
|
anItF.Initialize(aListOfFaces);
|
|
for (; anItF.More(); anItF.Next()) {
|
|
TopoDS_Face& aFx=TopoDS::Face(anItF.Value());
|
|
//
|
|
IntTools_Context aCtx;
|
|
iFlag=aCtx.ComputeVS(aVInternal, aFx, U, V);
|
|
//
|
|
if (!iFlag) {
|
|
BRep_Builder aBB;
|
|
aBB.Add(aFx, aVInternal);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//
|
|
// Alone Vertices' processing
|
|
//
|
|
Standard_Integer aNbVx, nVx;
|
|
aNbFF=aFFs.Extent();
|
|
for (i=1; i<=aNbFF; i++) {
|
|
BOPTools_SSInterference& aFF=aFFs(i);
|
|
aWh=aFF.Index1();
|
|
aWt=aFF.Index2();
|
|
if (aWh==nF || aWt==nF) {
|
|
TColStd_ListOfInteger& anAloneVertices=aFF.AloneVertices();
|
|
aNbVx=anAloneVertices.Extent();
|
|
if (aNbVx) {
|
|
TColStd_ListIteratorOfListOfInteger anItVx(anAloneVertices);
|
|
for (; anItVx.More(); anItVx.Next()) {
|
|
nVx=anItVx.Value();
|
|
const TopoDS_Vertex& aVx=TopoDS::Vertex(aDS.Shape(nVx));
|
|
//
|
|
TopoDS_Vertex aVInternal=aVx;
|
|
aVInternal.Orientation(TopAbs_INTERNAL);
|
|
//
|
|
anIt.Initialize(aListOfFaces);
|
|
for (; anIt.More(); anIt.Next()) {
|
|
TopoDS_Face& aF=TopoDS::Face(anIt.Value());
|
|
//
|
|
IntTools_Context aCtx;
|
|
iFlag=aCtx.ComputeVS (aVInternal, aF, U, V);
|
|
//
|
|
if (!iFlag) {
|
|
BRep_Builder aBB;
|
|
aBB.Add(aF, aVInternal);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//=======================================================================
|
|
// function: CollectInternals
|
|
// purpose:
|
|
//=======================================================================
|
|
void BOP_ShellSolid::CollectInternals()
|
|
{
|
|
Standard_Integer i, aNb, nSp;
|
|
TopAbs_ShapeEnum aType;
|
|
TopAbs_Orientation anOr;
|
|
TopTools_IndexedMapOfShape aMInternals;
|
|
|
|
const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
|
|
const BOPTools_SplitShapesPool& aSplitShapesPool=myDSFiller->SplitShapesPool();
|
|
|
|
aNb=aDS.NumberOfShapesOfTheObject()+aDS.NumberOfShapesOfTheTool();
|
|
for (i=1; i<= aNb; ++i) {
|
|
const TopoDS_Shape& aS=aDS.Shape(i);
|
|
aType=aS.ShapeType();
|
|
if (aType==TopAbs_EDGE || aType==TopAbs_VERTEX) {
|
|
anOr=aS.Orientation();
|
|
if (anOr==TopAbs_INTERNAL) {
|
|
//
|
|
aMInternals.Add(aS);
|
|
//
|
|
if (aType==TopAbs_EDGE) {
|
|
|
|
const BOPTools_ListOfPaveBlock& aSplits=aSplitShapesPool(aDS.RefEdge(i));
|
|
BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSplits);
|
|
for (; aPBIt.More(); aPBIt.Next()) {
|
|
BOPTools_PaveBlock& aPB=aPBIt.Value();
|
|
nSp=aPB.Edge();
|
|
const TopoDS_Shape& aSp=aDS.Shape(nSp);
|
|
//
|
|
aMInternals.Add(aSp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
aNb=aMInternals.Extent();
|
|
for (i=1; i<= aNb; ++i) {
|
|
const TopoDS_Shape& aS=aMInternals(i);
|
|
myInternals.Append(aS);
|
|
}
|
|
}
|
|
//=======================================================================
|
|
// function: Internals
|
|
// purpose:
|
|
//=======================================================================
|
|
const TopTools_ListOfShape& BOP_ShellSolid::Internals()const
|
|
{
|
|
return myInternals;
|
|
}
|
|
//=======================================================================
|
|
// function: FillSectionEdges
|
|
// purpose:
|
|
//=======================================================================
|
|
void BOP_ShellSolid::FillSectionEdges()
|
|
{
|
|
Standard_Integer i, j, nF1, nF2, aNbFFs, aNbS, aNbCurves, nSect;
|
|
//
|
|
const BooleanOperations_ShapesDataStructure& aDS=myDSFiller->DS();
|
|
const BOPTools_InterferencePool& anInterfPool=myDSFiller->InterfPool();
|
|
BOPTools_InterferencePool* pInterfPool=(BOPTools_InterferencePool*) &anInterfPool;
|
|
BOPTools_CArray1OfSSInterference& aFFs=pInterfPool->SSInterferences();
|
|
//
|
|
TopTools_IndexedMapOfShape aMap;
|
|
//
|
|
aNbFFs=aFFs.Extent();
|
|
for (i=1; i<=aNbFFs; ++i) {
|
|
BOPTools_SSInterference& aFFi=aFFs(i);
|
|
//
|
|
nF1=aFFi.Index1();
|
|
nF2=aFFi.Index2();
|
|
//
|
|
// Old Section Edges
|
|
const BOPTools_ListOfPaveBlock& aSectList=aFFi.PaveBlocks();
|
|
aNbS=aSectList.Extent();
|
|
BOPTools_ListIteratorOfListOfPaveBlock anIt(aSectList);
|
|
for (; anIt.More();anIt.Next()) {
|
|
const BOPTools_PaveBlock& aPB=anIt.Value();
|
|
nSect=aPB.Edge();
|
|
const TopoDS_Shape& aS=aDS.GetShape(nSect);
|
|
aMap.Add(aS);
|
|
}
|
|
//
|
|
// New Section Edges
|
|
BOPTools_SequenceOfCurves& aBCurves=aFFi.Curves();
|
|
aNbCurves=aBCurves.Length();
|
|
for (j=1; j<=aNbCurves; j++) {
|
|
BOPTools_Curve& aBC=aBCurves(j);
|
|
const BOPTools_ListOfPaveBlock& aSectEdges=aBC.NewPaveBlocks();
|
|
aNbS=aSectEdges.Extent();
|
|
|
|
BOPTools_ListIteratorOfListOfPaveBlock aPBIt(aSectEdges);
|
|
for (; aPBIt.More(); aPBIt.Next()) {
|
|
BOPTools_PaveBlock& aPB=aPBIt.Value();
|
|
nSect=aPB.Edge();
|
|
const TopoDS_Shape& aS=aDS.GetShape(nSect);
|
|
aMap.Add(aS);
|
|
}
|
|
}
|
|
}
|
|
//
|
|
mySectionEdges.Clear();
|
|
|
|
aNbS=aMap.Extent();
|
|
|
|
for (i=1; i<=aNbS; i++) {
|
|
const TopoDS_Shape& aS=aMap(i);
|
|
mySectionEdges.Append(aS);
|
|
}
|
|
}
|
|
|
|
void BOP_ShellSolid::SetHistoryCollector(const Handle(BOP_HistoryCollector)& theHistory)
|
|
{
|
|
if(theHistory.IsNull() ||
|
|
!theHistory->IsKind(STANDARD_TYPE(BOP_ShellSolidHistoryCollector)))
|
|
myHistory.Nullify();
|
|
else
|
|
myHistory = theHistory;
|
|
}
|
|
|
|
// -----------------------------------------------------------------
|
|
// static function: CheckSameDomainFaceInside
|
|
// purpose: Check if distance between several points of theFace1 and
|
|
// theFace2 is not more than sum of maximum of tolerances of
|
|
// theFace1's edges and tolerance of theFace2
|
|
// -----------------------------------------------------------------
|
|
Standard_Boolean CheckSameDomainFaceInside(const TopoDS_Face& theFace1,
|
|
const TopoDS_Face& theFace2) {
|
|
|
|
Standard_Real umin = 0., umax = 0., vmin = 0., vmax = 0.;
|
|
BRepTools::UVBounds(theFace1, umin, umax, vmin, vmax);
|
|
IntTools_Context aContext;
|
|
Handle(Geom_Surface) aSurface = BRep_Tool::Surface(theFace1);
|
|
Standard_Real aTolerance = BRep_Tool::Tolerance(theFace1);
|
|
|
|
TopExp_Explorer anExpE(theFace1, TopAbs_EDGE);
|
|
|
|
for(; anExpE.More(); anExpE.Next()) {
|
|
const TopoDS_Edge& anEdge = TopoDS::Edge(anExpE.Current());
|
|
Standard_Real anEdgeTol = BRep_Tool::Tolerance(anEdge);
|
|
aTolerance = (aTolerance < anEdgeTol) ? anEdgeTol : aTolerance;
|
|
}
|
|
aTolerance += BRep_Tool::Tolerance(theFace2);
|
|
|
|
Standard_Integer nbpoints = 5;
|
|
Standard_Real adeltau = (umax - umin) / (nbpoints + 1);
|
|
Standard_Real adeltav = (vmax - vmin) / (nbpoints + 1);
|
|
Standard_Real U = umin + adeltau;
|
|
GeomAPI_ProjectPointOnSurf& aProjector = aContext.ProjPS(theFace2);
|
|
|
|
for(Standard_Integer i = 1; i <= nbpoints; i++, U+=adeltau) {
|
|
Standard_Real V = vmin + adeltav;
|
|
|
|
for(Standard_Integer j = 1; j <= nbpoints; j++, V+=adeltav) {
|
|
gp_Pnt2d aPoint(U,V);
|
|
|
|
if(aContext.IsPointInFace(theFace1, aPoint)) {
|
|
gp_Pnt aP3d = aSurface->Value(U, V);
|
|
aProjector.Perform(aP3d);
|
|
|
|
if(aProjector.IsDone()) {
|
|
|
|
if(aProjector.LowerDistance() > aTolerance)
|
|
return Standard_False;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return Standard_True;
|
|
}
|
|
|