mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-04 18:06:22 +03:00
OSD_Parallel::ToUseOcctThreads() - new flag allowing to use OCCT threads implementation even when compiled with TBB (for testing). Added new command dparallel for managing default Thread Pool. OSD_Parallel::For() now avoid creation of universal iterator in simplest case. BOPTools_Parallel - eliminated redundant typedefs/explicit instantiations of templates. Added functor using array of per-thread context instead of a map.
758 lines
22 KiB
C++
758 lines
22 KiB
C++
// Created by: Peter KURNEV
|
|
// Copyright (c) 2010-2014 OPEN CASCADE SAS
|
|
// Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
|
|
// Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
|
|
// EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
//
|
|
#include <BOPAlgo_Builder.hxx>
|
|
//
|
|
#include <Precision.hxx>
|
|
//
|
|
#include <Bnd_Box.hxx>
|
|
#include <TopAbs_State.hxx>
|
|
//
|
|
#include <TopoDS.hxx>
|
|
#include <TopoDS_AlertWithShape.hxx>
|
|
#include <TopoDS_Iterator.hxx>
|
|
#include <TopoDS_Solid.hxx>
|
|
#include <TopoDS_Shape.hxx>
|
|
#include <TopoDS_Face.hxx>
|
|
#include <TopoDS_Edge.hxx>
|
|
#include <TopoDS_Solid.hxx>
|
|
#include <TopoDS_Shell.hxx>
|
|
#include <TopoDS_Compound.hxx>
|
|
//
|
|
#include <TopExp.hxx>
|
|
#include <TopExp_Explorer.hxx>
|
|
//
|
|
#include <BRep_Builder.hxx>
|
|
//
|
|
#include <BOPAlgo_Tools.hxx>
|
|
#include <BOPAlgo_BuilderSolid.hxx>
|
|
//
|
|
#include <IntTools_Context.hxx>
|
|
//
|
|
#include <BOPDS_DS.hxx>
|
|
#include <BOPDS_ShapeInfo.hxx>
|
|
//
|
|
#include <BOPTools_AlgoTools.hxx>
|
|
#include <BOPTools_MapOfSet.hxx>
|
|
#include <BOPTools_Set.hxx>
|
|
#include <BOPTools_Parallel.hxx>
|
|
//
|
|
#include <BOPAlgo_Tools.hxx>
|
|
#include <NCollection_Array1.hxx>
|
|
#include <NCollection_IncAllocator.hxx>
|
|
#include <NCollection_Vector.hxx>
|
|
|
|
#include <TopTools_IndexedMapOfShape.hxx>
|
|
#include <TopTools_MapOfShape.hxx>
|
|
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
|
#include <TopTools_IndexedDataMapOfShapeShape.hxx>
|
|
#include <TopTools_ListOfShape.hxx>
|
|
|
|
#include <algorithm>
|
|
|
|
static
|
|
void OwnInternalShapes(const TopoDS_Shape& ,
|
|
TopTools_IndexedMapOfShape& );
|
|
|
|
|
|
//=======================================================================
|
|
//function : FillImagesSolids
|
|
//purpose :
|
|
//=======================================================================
|
|
void BOPAlgo_Builder::FillImagesSolids()
|
|
{
|
|
Standard_Boolean bHasSolids;
|
|
Standard_Integer i, aNbS;
|
|
//
|
|
bHasSolids=Standard_False;
|
|
aNbS=myDS->NbSourceShapes();
|
|
for (i=0; i<aNbS; ++i) {
|
|
const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
|
|
if (aSI.ShapeType()==TopAbs_SOLID) {
|
|
bHasSolids=!bHasSolids;
|
|
break;
|
|
}
|
|
}
|
|
//
|
|
if (!bHasSolids) {
|
|
return;
|
|
}
|
|
|
|
// Draft solids
|
|
TopTools_DataMapOfShapeShape aDraftSolids;
|
|
// Find all IN faces for all IN faces
|
|
FillIn3DParts(aDraftSolids);
|
|
// Build split of the solids
|
|
BuildSplitSolids(aDraftSolids);
|
|
// Fill solids with internal parts
|
|
FillInternalShapes();
|
|
}
|
|
//=======================================================================
|
|
//function : FillIn3DParts
|
|
//purpose :
|
|
//=======================================================================
|
|
void BOPAlgo_Builder::FillIn3DParts(TopTools_DataMapOfShapeShape& theDraftSolids)
|
|
{
|
|
Handle(NCollection_BaseAllocator) anAlloc = new NCollection_IncAllocator;
|
|
|
|
// Find all faces that are IN solids
|
|
|
|
// Store boxes of the shapes into a map
|
|
TopTools_DataMapOfShapeBox aShapeBoxMap(1, anAlloc);
|
|
|
|
// Fence map
|
|
TopTools_MapOfShape aMFence(1, anAlloc);
|
|
|
|
// Get all faces
|
|
TopTools_ListOfShape aLFaces(anAlloc);
|
|
|
|
Standard_Integer i, aNbS = myDS->NbSourceShapes();
|
|
for (i = 0; i < aNbS; ++i)
|
|
{
|
|
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
|
|
if (aSI.ShapeType() != TopAbs_FACE)
|
|
continue;
|
|
|
|
const TopoDS_Shape& aS = aSI.Shape();
|
|
const TopTools_ListOfShape* pLSIm = myImages.Seek(aS);
|
|
|
|
if (pLSIm)
|
|
{
|
|
TopTools_ListIteratorOfListOfShape aItLSIm(*pLSIm);
|
|
for (; aItLSIm.More(); aItLSIm.Next())
|
|
{
|
|
const TopoDS_Shape& aSIm = aItLSIm.Value();
|
|
if (aMFence.Add(aSIm))
|
|
aLFaces.Append(aSIm);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
aLFaces.Append(aS);
|
|
aShapeBoxMap.Bind(aS, aSI.Box());
|
|
}
|
|
}
|
|
|
|
BRep_Builder aBB;
|
|
|
|
// Get all solids
|
|
TopTools_ListOfShape aLSolids(anAlloc);
|
|
// Keep INTERNAL faces of the solids
|
|
TopTools_DataMapOfShapeListOfShape aSolidsIF(1, anAlloc);
|
|
// Draft solids
|
|
TopTools_IndexedDataMapOfShapeShape aDraftSolid(1, anAlloc);
|
|
|
|
for (i = 0; i < aNbS; ++i)
|
|
{
|
|
BOPDS_ShapeInfo& aSI = myDS->ChangeShapeInfo(i);
|
|
if (aSI.ShapeType() != TopAbs_SOLID)
|
|
continue;
|
|
|
|
const TopoDS_Shape& aS = aSI.Shape();
|
|
const TopoDS_Solid& aSolid = (*(TopoDS_Solid*)(&aS));
|
|
//
|
|
// Bounding box for the solid aS
|
|
Bnd_Box& aBoxS = aSI.ChangeBox();
|
|
if (aBoxS.IsVoid())
|
|
myDS->BuildBndBoxSolid(i, aBoxS, myCheckInverted);
|
|
|
|
// Build Draft Solid
|
|
TopTools_ListOfShape aLIF;
|
|
TopoDS_Solid aSD;
|
|
aBB.MakeSolid(aSD);
|
|
BuildDraftSolid(aSolid, aSD, aLIF);
|
|
|
|
aLSolids.Append(aSD);
|
|
aSolidsIF.Bind(aSD, aLIF);
|
|
aShapeBoxMap.Bind(aSD, aBoxS);
|
|
aDraftSolid.Add(aS, aSD);
|
|
}
|
|
|
|
// Perform classification of the faces
|
|
TopTools_IndexedDataMapOfShapeListOfShape anInParts;
|
|
|
|
BOPAlgo_Tools::ClassifyFaces(aLFaces, aLSolids, myRunParallel,
|
|
myContext, anInParts, aShapeBoxMap, aSolidsIF);
|
|
|
|
// Analyze the results of classification
|
|
Standard_Integer aNbSol = aDraftSolid.Extent();
|
|
for (i = 1; i <= aNbSol; ++i)
|
|
{
|
|
const TopoDS_Solid& aSolid = TopoDS::Solid(aDraftSolid.FindKey(i));
|
|
const TopoDS_Solid& aSDraft = TopoDS::Solid(aDraftSolid(i));
|
|
const TopTools_ListOfShape& aLInFaces = anInParts.FindFromKey(aSDraft);
|
|
const TopTools_ListOfShape& aLInternal = aSolidsIF.Find(aSDraft);
|
|
|
|
Standard_Integer aNbIN = aLInFaces.Extent();
|
|
|
|
if (!aNbIN)
|
|
{
|
|
Standard_Boolean bHasImage = Standard_False;
|
|
// Check if the shells of the solid have image
|
|
for (TopoDS_Iterator it(aSolid); it.More() && !bHasImage; it.Next())
|
|
bHasImage = myImages.IsBound(it.Value());
|
|
|
|
if (!bHasImage)
|
|
// no need to split the solid
|
|
continue;
|
|
}
|
|
|
|
theDraftSolids.Bind(aSolid, aSDraft);
|
|
|
|
Standard_Integer aNbInt = aLInternal.Extent();
|
|
if (aNbInt || aNbIN)
|
|
{
|
|
// Combine the lists
|
|
TopTools_ListOfShape *pLIN = myInParts.Bound(aSolid, TopTools_ListOfShape());
|
|
|
|
TopTools_ListIteratorOfListOfShape aItLS(aLInFaces);
|
|
for (; aItLS.More(); aItLS.Next())
|
|
pLIN->Append(aItLS.Value());
|
|
|
|
aItLS.Initialize(aLInternal);
|
|
for (; aItLS.More(); aItLS.Next())
|
|
pLIN->Append(aItLS.Value());
|
|
}
|
|
}
|
|
}
|
|
//=======================================================================
|
|
//function : BuildDraftSolid
|
|
//purpose :
|
|
//=======================================================================
|
|
void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid,
|
|
TopoDS_Shape& theDraftSolid,
|
|
TopTools_ListOfShape& theLIF)
|
|
{
|
|
Standard_Boolean bToReverse;
|
|
Standard_Integer iFlag;
|
|
TopAbs_Orientation aOrF, aOrSh, aOrSd;
|
|
TopoDS_Iterator aIt1, aIt2;
|
|
TopoDS_Shell aShD;
|
|
TopoDS_Shape aFx;
|
|
BRep_Builder aBB;
|
|
TopTools_ListIteratorOfListOfShape aItS;
|
|
//
|
|
aOrSd=theSolid.Orientation();
|
|
theDraftSolid.Orientation(aOrSd);
|
|
//
|
|
aIt1.Initialize(theSolid);
|
|
for (; aIt1.More(); aIt1.Next()) {
|
|
const TopoDS_Shape& aSh=aIt1.Value();
|
|
if(aSh.ShapeType()!=TopAbs_SHELL) {
|
|
continue; // mb internal edges,vertices
|
|
}
|
|
//
|
|
aOrSh=aSh.Orientation();
|
|
aBB.MakeShell(aShD);
|
|
aShD.Orientation(aOrSh);
|
|
iFlag=0;
|
|
//
|
|
aIt2.Initialize(aSh);
|
|
for (; aIt2.More(); aIt2.Next()) {
|
|
const TopoDS_Shape& aF=aIt2.Value();
|
|
aOrF=aF.Orientation();
|
|
//
|
|
if (myImages.IsBound(aF)) {
|
|
const TopTools_ListOfShape& aLSp=myImages.Find(aF);
|
|
aItS.Initialize(aLSp);
|
|
for (; aItS.More(); aItS.Next()) {
|
|
aFx=aItS.Value();
|
|
//
|
|
if (myShapesSD.IsBound(aFx)) {
|
|
//
|
|
if (aOrF==TopAbs_INTERNAL) {
|
|
aFx.Orientation(aOrF);
|
|
theLIF.Append(aFx);
|
|
}
|
|
else {
|
|
bToReverse=BOPTools_AlgoTools::IsSplitToReverseWithWarn
|
|
(aFx, aF, myContext, myReport);
|
|
if (bToReverse) {
|
|
aFx.Reverse();
|
|
}
|
|
//
|
|
iFlag=1;
|
|
aBB.Add(aShD, aFx);
|
|
}
|
|
}//if (myShapesSD.IsBound(aFx)) {
|
|
else {
|
|
aFx.Orientation(aOrF);
|
|
if (aOrF==TopAbs_INTERNAL) {
|
|
theLIF.Append(aFx);
|
|
}
|
|
else{
|
|
iFlag=1;
|
|
aBB.Add(aShD, aFx);
|
|
}
|
|
}
|
|
}
|
|
} // if (myImages.IsBound(aF)) {
|
|
//
|
|
else {
|
|
if (aOrF==TopAbs_INTERNAL) {
|
|
theLIF.Append(aF);
|
|
}
|
|
else{
|
|
iFlag=1;
|
|
aBB.Add(aShD, aF);
|
|
}
|
|
}
|
|
} //for (; aIt2.More(); aIt2.Next()) {
|
|
//
|
|
if (iFlag) {
|
|
aShD.Closed (BRep_Tool::IsClosed (aShD));
|
|
aBB.Add(theDraftSolid, aShD);
|
|
}
|
|
} //for (; aIt1.More(); aIt1.Next()) {
|
|
}
|
|
|
|
//=======================================================================
|
|
|
|
//=======================================================================
|
|
//class : BOPAlgo_SplitSolid
|
|
//purpose : Auxiliary class to extend the BOPAlgo_BuilderSolid with the solid to split
|
|
//=======================================================================
|
|
class BOPAlgo_SplitSolid : public BOPAlgo_BuilderSolid
|
|
{
|
|
public:
|
|
//! Sets the solid
|
|
void SetSolid(const TopoDS_Solid& theSolid) { mySolid = theSolid; }
|
|
|
|
//! Returns the solid
|
|
const TopoDS_Solid& Solid() const { return mySolid; }
|
|
|
|
private:
|
|
TopoDS_Solid mySolid; //!< Solid to split
|
|
};
|
|
|
|
// Vector of Solid Builders
|
|
typedef NCollection_Vector<BOPAlgo_SplitSolid> BOPAlgo_VectorOfBuilderSolid;
|
|
|
|
//=======================================================================
|
|
//function : BuildSplitSolids
|
|
//purpose :
|
|
//=======================================================================
|
|
void BOPAlgo_Builder::BuildSplitSolids(TopTools_DataMapOfShapeShape& theDraftSolids)
|
|
{
|
|
Standard_Boolean bFlagSD;
|
|
Standard_Integer i, aNbS;
|
|
TopExp_Explorer aExp;
|
|
TopTools_ListIteratorOfListOfShape aIt;
|
|
//
|
|
Handle(NCollection_BaseAllocator) aAlr0;
|
|
aAlr0=NCollection_BaseAllocator::CommonBaseAllocator();
|
|
//
|
|
TopTools_ListOfShape aSFS(aAlr0), aLSEmpty(aAlr0);
|
|
TopTools_MapOfShape aMFence(100, aAlr0);
|
|
BOPTools_MapOfSet aMST(100, aAlr0);
|
|
BOPAlgo_VectorOfBuilderSolid aVBS;
|
|
//
|
|
// 0. Find same domain solids for non-interfered solids
|
|
aNbS=myDS->NbSourceShapes();
|
|
for (i=0; i<aNbS; ++i) {
|
|
const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
|
|
//
|
|
if (aSI.ShapeType()!=TopAbs_SOLID) {
|
|
continue;
|
|
}
|
|
//
|
|
const TopoDS_Shape& aS=aSI.Shape();
|
|
if (!aMFence.Add(aS)) {
|
|
continue;
|
|
}
|
|
if(theDraftSolids.IsBound(aS)) {
|
|
continue;
|
|
}
|
|
//
|
|
BOPTools_Set aST;
|
|
//
|
|
aST.Add(aS, TopAbs_FACE);
|
|
aMST.Add(aST);
|
|
//
|
|
} //for (i=1; i<=aNbS; ++i)
|
|
//
|
|
// Build temporary map of solids images to avoid rebuilding
|
|
// of the solids without internal faces
|
|
TopTools_IndexedDataMapOfShapeListOfShape aSolidsIm;
|
|
// 1. Build solids for interfered source solids
|
|
for (i = 0; i < aNbS; ++i) {
|
|
const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
|
|
if (aSI.ShapeType() != TopAbs_SOLID)
|
|
continue;
|
|
|
|
const TopoDS_Shape& aS = aSI.Shape();
|
|
const TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aS));
|
|
if (!theDraftSolids.IsBound(aS))
|
|
continue;
|
|
|
|
const TopoDS_Shape& aSD = theDraftSolids.Find(aS);
|
|
const TopTools_ListOfShape* pLFIN = myInParts.Seek(aS);
|
|
if (!pLFIN || pLFIN->IsEmpty())
|
|
{
|
|
aSolidsIm(aSolidsIm.Add(aS, TopTools_ListOfShape())).Append(aSD);
|
|
continue;
|
|
}
|
|
|
|
aSFS.Clear();
|
|
//
|
|
// 1.1 Fill Shell Faces Set
|
|
aExp.Init(aSD, TopAbs_FACE);
|
|
for (; aExp.More(); aExp.Next()) {
|
|
const TopoDS_Shape& aF = aExp.Current();
|
|
aSFS.Append(aF);
|
|
}
|
|
//
|
|
// 1.2 Fill internal faces
|
|
aIt.Initialize(*pLFIN);
|
|
for (; aIt.More(); aIt.Next()) {
|
|
TopoDS_Shape aF = aIt.Value();
|
|
//
|
|
aF.Orientation(TopAbs_FORWARD);
|
|
aSFS.Append(aF);
|
|
aF.Orientation(TopAbs_REVERSED);
|
|
aSFS.Append(aF);
|
|
}
|
|
//
|
|
// 1.3 Build new solids
|
|
BOPAlgo_SplitSolid& aBS=aVBS.Appended();
|
|
aBS.SetSolid(aSolid);
|
|
aBS.SetShapes(aSFS);
|
|
aBS.SetRunParallel(myRunParallel);
|
|
aBS.SetProgressIndicator(myProgressIndicator);
|
|
}//for (i=0; i<aNbS; ++i) {
|
|
//
|
|
Standard_Integer k, aNbBS;
|
|
//
|
|
aNbBS=aVBS.Length();
|
|
//
|
|
//===================================================
|
|
BOPTools_Parallel::Perform (myRunParallel, aVBS);
|
|
//===================================================
|
|
//
|
|
for (k = 0; k < aNbBS; ++k)
|
|
{
|
|
BOPAlgo_SplitSolid& aBS = aVBS(k);
|
|
aSolidsIm.Add(aBS.Solid(), aBS.Areas());
|
|
|
|
// Merge BuilderSolid's report into main report,
|
|
// assigning the solid with the warnings/errors which
|
|
// have been generated for it.
|
|
// Convert all errors of BuilderSolid into warnings for main report.
|
|
const Handle(Message_Report)& aBSReport = aBS.GetReport();
|
|
Message_Gravity anAlertTypes[2] = { Message_Warning, Message_Fail };
|
|
for (Standard_Integer iGravity = 0; iGravity < 2; iGravity++)
|
|
{
|
|
const Message_ListOfAlert& anLAlerts = aBSReport->GetAlerts(anAlertTypes[iGravity]);
|
|
for (Message_ListOfAlert::Iterator itA(anLAlerts); itA.More(); itA.Next())
|
|
{
|
|
Handle(Message_Alert) anAlert = itA.Value();
|
|
|
|
Handle(TopoDS_AlertWithShape) anAlertWithShape = Handle(TopoDS_AlertWithShape)::DownCast(itA.Value());
|
|
if (!anAlertWithShape.IsNull())
|
|
{
|
|
TopoDS_Shape aWarnShape;
|
|
BRep_Builder().MakeCompound(TopoDS::Compound(aWarnShape));
|
|
BRep_Builder().Add(aWarnShape, aBS.Solid());
|
|
BRep_Builder().Add(aWarnShape, anAlertWithShape->GetShape());
|
|
|
|
anAlertWithShape->SetShape(aWarnShape);
|
|
AddWarning(anAlertWithShape);
|
|
}
|
|
else
|
|
AddWarning(anAlert);
|
|
}
|
|
}
|
|
}
|
|
//
|
|
// Add new solids to images map
|
|
aNbBS = aSolidsIm.Extent();
|
|
for (k = 1; k <= aNbBS; ++k)
|
|
{
|
|
const TopoDS_Shape& aS = aSolidsIm.FindKey(k);
|
|
const TopTools_ListOfShape& aLSR = aSolidsIm(k);
|
|
//
|
|
if (!myImages.IsBound(aS)) {
|
|
TopTools_ListOfShape* pLSx = myImages.Bound(aS, TopTools_ListOfShape());
|
|
//
|
|
aIt.Initialize(aLSR);
|
|
for (; aIt.More(); aIt.Next()) {
|
|
BOPTools_Set aST;
|
|
//
|
|
const TopoDS_Shape& aSR=aIt.Value();
|
|
aST.Add(aSR, TopAbs_FACE);
|
|
//
|
|
bFlagSD=aMST.Contains(aST);
|
|
//
|
|
const BOPTools_Set& aSTx=aMST.Added(aST);
|
|
const TopoDS_Shape& aSx=aSTx.Shape();
|
|
pLSx->Append(aSx);
|
|
//
|
|
TopTools_ListOfShape* pLOr = myOrigins.ChangeSeek(aSx);
|
|
if (!pLOr) {
|
|
pLOr = myOrigins.Bound(aSx, TopTools_ListOfShape());
|
|
}
|
|
pLOr->Append(aS);
|
|
//
|
|
if (bFlagSD) {
|
|
myShapesSD.Bind(aSR, aSx);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//=======================================================================
|
|
//function :FillInternalShapes
|
|
//purpose :
|
|
//=======================================================================
|
|
void BOPAlgo_Builder::FillInternalShapes()
|
|
{
|
|
Standard_Integer i, j, aNbS, aNbSI, aNbSx;
|
|
TopAbs_ShapeEnum aType;
|
|
TopAbs_State aState;
|
|
TopoDS_Iterator aItS;
|
|
BRep_Builder aBB;
|
|
TopTools_ListIteratorOfListOfShape aIt, aIt1;
|
|
//
|
|
Handle(NCollection_BaseAllocator) aAllocator;
|
|
//-----------------------------------------------------scope f
|
|
aAllocator=NCollection_BaseAllocator::CommonBaseAllocator();
|
|
//
|
|
TopTools_IndexedDataMapOfShapeListOfShape aMSx(100, aAllocator);
|
|
TopTools_IndexedMapOfShape aMx(100, aAllocator);
|
|
TopTools_IndexedMapOfShape aMSI(100, aAllocator);
|
|
TopTools_MapOfShape aMFence(100, aAllocator);
|
|
TopTools_MapOfShape aMSOr(100, aAllocator);
|
|
TopTools_ListOfShape aLSd(aAllocator);
|
|
TopTools_ListOfShape aLArgs(aAllocator);
|
|
TopTools_ListOfShape aLSC(aAllocator);
|
|
TopTools_ListOfShape aLSI(aAllocator);
|
|
//
|
|
// 1. Shapes to process
|
|
//
|
|
// 1.1 Shapes from pure arguments aMSI
|
|
// 1.1.1 vertex, edge, wire
|
|
//
|
|
const TopTools_ListOfShape& aArguments=myDS->Arguments();
|
|
aIt.Initialize(aArguments);
|
|
for (; aIt.More(); aIt.Next()) {
|
|
const TopoDS_Shape& aS=aIt.Value();
|
|
BOPAlgo_Tools::TreatCompound(aS, aMFence, aLSC);
|
|
}
|
|
aIt.Initialize(aLSC);
|
|
for (; aIt.More(); aIt.Next()) {
|
|
const TopoDS_Shape& aS=aIt.Value();
|
|
aType=aS.ShapeType();
|
|
if (aType==TopAbs_WIRE) {
|
|
aItS.Initialize(aS);
|
|
for(; aItS.More(); aItS.Next()) {
|
|
const TopoDS_Shape& aE=aItS.Value();
|
|
if (aMFence.Add(aE)) {
|
|
aLArgs.Append(aE);
|
|
}
|
|
}
|
|
}
|
|
else if (aType==TopAbs_VERTEX || aType==TopAbs_EDGE){
|
|
aLArgs.Append(aS);
|
|
}
|
|
}
|
|
aMFence.Clear();
|
|
//
|
|
aIt.Initialize(aLArgs);
|
|
for (; aIt.More(); aIt.Next()) {
|
|
const TopoDS_Shape& aS=aIt.Value();
|
|
aType=aS.ShapeType();
|
|
if (aType==TopAbs_VERTEX ||
|
|
aType==TopAbs_EDGE ||
|
|
aType==TopAbs_WIRE) {
|
|
if (aMFence.Add(aS)) {
|
|
if (myImages.IsBound(aS)) {
|
|
const TopTools_ListOfShape &aLSp=myImages.Find(aS);
|
|
aIt1.Initialize(aLSp);
|
|
for (; aIt1.More(); aIt1.Next()) {
|
|
const TopoDS_Shape& aSp=aIt1.Value();
|
|
aMSI.Add(aSp);
|
|
}
|
|
}
|
|
else {
|
|
aMSI.Add(aS);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
aNbSI=aMSI.Extent();
|
|
//
|
|
// 2. Internal vertices, edges from source solids
|
|
aMFence.Clear();
|
|
aLSd.Clear();
|
|
//
|
|
aNbS=myDS->NbSourceShapes();
|
|
for (i=0; i<aNbS; ++i) {
|
|
const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
|
|
//
|
|
if (aSI.ShapeType()!=TopAbs_SOLID) {
|
|
continue;
|
|
}
|
|
//
|
|
UserBreak();
|
|
//
|
|
const TopoDS_Shape& aS=aSI.Shape();
|
|
//
|
|
aMx.Clear();
|
|
OwnInternalShapes(aS, aMx);
|
|
//
|
|
aNbSx=aMx.Extent();
|
|
for (j=1; j<=aNbSx; ++j) {
|
|
const TopoDS_Shape& aSi=aMx(j);
|
|
if (myImages.IsBound(aSi)) {
|
|
const TopTools_ListOfShape &aLSp=myImages.Find(aSi);
|
|
aIt1.Initialize(aLSp);
|
|
for (; aIt1.More(); aIt1.Next()) {
|
|
const TopoDS_Shape& aSp=aIt1.Value();
|
|
aMSI.Add(aSp);
|
|
}
|
|
}
|
|
else {
|
|
aMSI.Add(aSi);
|
|
}
|
|
}
|
|
//
|
|
// build aux map from splits of solids
|
|
if (myImages.IsBound(aS)) {
|
|
const TopTools_ListOfShape &aLSp=myImages.Find(aS);
|
|
aIt.Initialize(aLSp);
|
|
for (; aIt.More(); aIt.Next()) {
|
|
const TopoDS_Shape& aSp=aIt.Value();
|
|
if (aMFence.Add(aSp)) {
|
|
TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
|
|
TopExp::MapShapesAndAncestors(aSp, TopAbs_VERTEX, TopAbs_FACE, aMSx);
|
|
TopExp::MapShapesAndAncestors(aSp, TopAbs_EDGE , TopAbs_FACE, aMSx);
|
|
aLSd.Append(aSp);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if (aMFence.Add(aS)) {
|
|
TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aMSx);
|
|
TopExp::MapShapesAndAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aMSx);
|
|
TopExp::MapShapesAndAncestors(aS, TopAbs_EDGE , TopAbs_FACE, aMSx);
|
|
aLSd.Append(aS);
|
|
aMSOr.Add(aS);
|
|
}
|
|
}
|
|
}// for (i=0; i<aNbS; ++i) {
|
|
//
|
|
// 3. Some shapes of aMSI can be already tied with faces of
|
|
// split solids
|
|
aNbSI = aMSI.Extent();
|
|
for (i = 1; i <= aNbSI; ++i) {
|
|
const TopoDS_Shape& aSI = aMSI(i);
|
|
if (aMSx.Contains(aSI)) {
|
|
const TopTools_ListOfShape &aLSx=aMSx.FindFromKey(aSI);
|
|
aNbSx = aLSx.Extent();
|
|
if (!aNbSx) {
|
|
aLSI.Append(aSI);
|
|
}
|
|
}
|
|
else {
|
|
aLSI.Append(aSI);
|
|
}
|
|
}
|
|
//
|
|
// 4. Just check it
|
|
aNbSI = aLSI.Extent();
|
|
if (!aNbSI) {
|
|
return;
|
|
}
|
|
//
|
|
// 5 Settle internal vertices and edges into solids
|
|
aMx.Clear();
|
|
aIt.Initialize(aLSd);
|
|
for (; aIt.More(); aIt.Next()) {
|
|
TopoDS_Solid aSd=TopoDS::Solid(aIt.Value());
|
|
//
|
|
aIt1.Initialize(aLSI);
|
|
for (; aIt1.More();) {
|
|
TopoDS_Shape aSI = aIt1.Value();
|
|
aSI.Orientation(TopAbs_INTERNAL);
|
|
//
|
|
aState=BOPTools_AlgoTools::ComputeStateByOnePoint
|
|
(aSI, aSd, 1.e-11, myContext);
|
|
//
|
|
if (aState != TopAbs_IN) {
|
|
aIt1.Next();
|
|
continue;
|
|
}
|
|
//
|
|
if (aMSOr.Contains(aSd)) {
|
|
// make new solid
|
|
TopoDS_Solid aSdx;
|
|
//
|
|
aBB.MakeSolid(aSdx);
|
|
aItS.Initialize(aSd);
|
|
for (; aItS.More(); aItS.Next()) {
|
|
const TopoDS_Shape& aSh=aItS.Value();
|
|
aBB.Add(aSdx, aSh);
|
|
}
|
|
//
|
|
aBB.Add(aSdx, aSI);
|
|
//
|
|
// no need to check for images of aSd as aMSOr contains only original solids
|
|
TopTools_ListOfShape* pLS = myImages.Bound(aSd, TopTools_ListOfShape());
|
|
pLS->Append(aSdx);
|
|
//
|
|
TopTools_ListOfShape* pLOr = myOrigins.Bound(aSdx, TopTools_ListOfShape());
|
|
pLOr->Append(aSd);
|
|
//
|
|
aMSOr.Remove(aSd);
|
|
aSd=aSdx;
|
|
}
|
|
else {
|
|
aBB.Add(aSd, aSI);
|
|
}
|
|
//
|
|
aLSI.Remove(aIt1);
|
|
}//for (; aIt1.More();) {
|
|
}//for (; aIt.More(); aIt.Next()) {
|
|
//
|
|
//-----------------------------------------------------scope t
|
|
aLArgs.Clear();
|
|
aLSd.Clear();
|
|
aMSOr.Clear();
|
|
aMFence.Clear();
|
|
aMSI.Clear();
|
|
aMx.Clear();
|
|
aMSx.Clear();
|
|
}
|
|
//=======================================================================
|
|
//function : OwnInternalShapes
|
|
//purpose :
|
|
//=======================================================================
|
|
void OwnInternalShapes(const TopoDS_Shape& theS,
|
|
TopTools_IndexedMapOfShape& theMx)
|
|
{
|
|
TopoDS_Iterator aIt;
|
|
//
|
|
aIt.Initialize(theS);
|
|
for (; aIt.More(); aIt.Next()) {
|
|
const TopoDS_Shape& aSx=aIt.Value();
|
|
if (aSx.ShapeType()!=TopAbs_SHELL) {
|
|
theMx.Add(aSx);
|
|
}
|
|
}
|
|
}
|