Loading files
4f95ecaa3This file is pinned to the selected release. Download the original to open it in your design tool.
// 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.
#include <BRepAlgoAPI_BooleanOperation.hxx>
#include <BOPAlgo_Alerts.hxx>
#include <BOPAlgo_BOP.hxx>
#include <BOPAlgo_PaveFiller.hxx>
#include <BOPAlgo_Section.hxx>
#include <BRepAlgoAPI_Check.hxx>
#include <BRepTools.hxx>
#include <OSD_Environment.hxx>
#include <OSD_File.hxx>
#include <TCollection_AsciiString.hxx>
#include <cstdio>
//=======================================================================
// class : BRepAlgoAPI_DumpOper
// purpose : Dumps the arguments ad script to perform operation in DRAW
//=======================================================================
class BRepAlgoAPI_DumpOper
{
public:
BRepAlgoAPI_DumpOper()
: myIsDump(false),
myIsDumpArgs(false),
myIsDumpRes(false)
{
OSD_Environment env("CSF_DEBUG_BOP");
TCollection_AsciiString pathdump = env.Value();
myIsDump = (!pathdump.IsEmpty());
myPath = pathdump.ToCString();
};
//
virtual ~BRepAlgoAPI_DumpOper() = default;
//
bool IsDump() const { return myIsDump; };
//
void SetIsDumpArgs(const bool bFlag) { myIsDumpArgs = bFlag; }
//
bool IsDumpArgs() const { return myIsDumpArgs; };
//
void SetIsDumpRes(const bool bFlag) { myIsDumpRes = bFlag; };
//
bool IsDumpRes() const { return myIsDumpRes; };
//
void Dump(const TopoDS_Shape& theShape1,
const TopoDS_Shape& theShape2,
const TopoDS_Shape& theResult,
BOPAlgo_Operation theOperation);
//
protected:
bool myIsDump;
bool myIsDumpArgs;
bool myIsDumpRes;
const char* myPath;
};
//=================================================================================================
BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation()
: myOperation(BOPAlgo_UNKNOWN)
{
}
//=================================================================================================
BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation(const BOPAlgo_PaveFiller& thePF)
: BRepAlgoAPI_BuilderAlgo(thePF),
myOperation(BOPAlgo_UNKNOWN)
{
}
//=================================================================================================
BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation(const TopoDS_Shape& theS1,
const TopoDS_Shape& theS2,
const BOPAlgo_Operation theOp)
: myOperation(theOp)
{
myArguments.Append(theS1);
myTools.Append(theS2);
}
//=================================================================================================
BRepAlgoAPI_BooleanOperation::BRepAlgoAPI_BooleanOperation(const TopoDS_Shape& theS1,
const TopoDS_Shape& theS2,
const BOPAlgo_PaveFiller& thePF,
const BOPAlgo_Operation theOp)
: BRepAlgoAPI_BuilderAlgo(thePF),
myOperation(theOp)
{
myArguments.Append(theS1);
myTools.Append(theS2);
}
//=================================================================================================
void BRepAlgoAPI_BooleanOperation::Build(const Message_ProgressRange& theRange)
{
// Set Not Done status by default
NotDone();
// Clear from previous runs
Clear();
// Check for availability of arguments and tools
// Both should be present
if (myArguments.IsEmpty() || myTools.IsEmpty())
{
AddError(new BOPAlgo_AlertTooFewArguments);
return;
}
// Check if the operation is set
if (myOperation == BOPAlgo_UNKNOWN)
{
AddError(new BOPAlgo_AlertBOPNotSet);
return;
}
// DEBUG option for dumping shapes and scripts
BRepAlgoAPI_DumpOper aDumpOper;
{
if (aDumpOper.IsDump())
{
BRepAlgoAPI_Check aChekArgs(myArguments.First(), myTools.First(), myOperation);
aDumpOper.SetIsDumpArgs(!aChekArgs.IsValid());
}
}
TCollection_AsciiString aPSName;
switch (myOperation)
{
case BOPAlgo_COMMON:
aPSName = "Performing COMMON operation";
break;
case BOPAlgo_FUSE:
aPSName = "Performing FUSE operation";
break;
case BOPAlgo_CUT:
case BOPAlgo_CUT21:
aPSName = "Performing CUT operation";
break;
case BOPAlgo_SECTION:
aPSName = "Performing SECTION operation";
break;
default:
return;
}
Message_ProgressScope aPS(theRange, aPSName, myIsIntersectionNeeded ? 100 : 30);
// If necessary perform intersection of the argument shapes
if (myIsIntersectionNeeded)
{
// Combine Objects and Tools into a single list for intersection
NCollection_List<TopoDS_Shape> aLArgs = myArguments;
for (NCollection_List<TopoDS_Shape>::Iterator it(myTools); it.More(); it.Next())
{
aLArgs.Append(it.Value());
}
// Perform intersection
IntersectShapes(aLArgs, aPS.Next(70));
if (HasErrors())
{
if (aDumpOper.IsDump())
{
aDumpOper.SetIsDumpRes(false);
aDumpOper.Dump(myArguments.First(), myTools.First(), TopoDS_Shape(), myOperation);
}
return;
}
}
// Builder Initialization
if (myOperation == BOPAlgo_SECTION)
{
myBuilder = new BOPAlgo_Section(myAllocator);
myBuilder->SetArguments(myDSFiller->Arguments());
}
else
{
myBuilder = new BOPAlgo_BOP(myAllocator);
myBuilder->SetArguments(myArguments);
((BOPAlgo_BOP*)myBuilder)->SetTools(myTools);
((BOPAlgo_BOP*)myBuilder)->SetOperation(myOperation);
}
// Build the result
BuildResult(aPS.Next(30));
if (HasErrors())
{
return;
}
if (aDumpOper.IsDump())
{
bool isDumpRes = myShape.IsNull() || !BRepAlgoAPI_Check(myShape).IsValid();
aDumpOper.SetIsDumpRes(isDumpRes);
aDumpOper.Dump(myArguments.First(), myTools.First(), myShape, myOperation);
}
}
//=======================================================================
// function : Dump
// purpose : DEBUG: Dumping the shapes and script of the operation
//=======================================================================
void BRepAlgoAPI_DumpOper::Dump(const TopoDS_Shape& theShape1,
const TopoDS_Shape& theShape2,
const TopoDS_Shape& theResult,
BOPAlgo_Operation theOperation)
{
if (!(myIsDumpArgs && myIsDumpRes))
{
return;
}
//
TCollection_AsciiString aPath(myPath);
aPath += "/";
int aNumOper = 1;
bool isExist = true;
TCollection_AsciiString aFileName;
while (isExist)
{
aFileName = aPath + "BO_" + TCollection_AsciiString(aNumOper) + ".tcl";
OSD_File aScript(aFileName);
isExist = aScript.Exists();
if (isExist)
{
aNumOper++;
}
}
FILE* afile = fopen(aFileName.ToCString(), "w+");
if (!afile)
{
return;
}
if (myIsDumpArgs)
{
fprintf(afile, "%s\n", "# Arguments are invalid");
}
TCollection_AsciiString aName1;
TCollection_AsciiString aName2;
TCollection_AsciiString aNameRes;
if (!theShape1.IsNull())
{
aName1 = aPath + "Arg1_" + TCollection_AsciiString(aNumOper) + ".brep";
BRepTools::Write(theShape1, aName1.ToCString());
}
else
{
fprintf(afile, "%s\n", "# First argument is Null ");
}
if (!theShape2.IsNull())
{
aName2 = aPath + "Arg2_" + TCollection_AsciiString(aNumOper) + ".brep";
BRepTools::Write(theShape2, aName2.ToCString());
}
else
{
fprintf(afile, "%s\n", "# Second argument is Null ");
}
if (!theResult.IsNull())
{
aNameRes = aPath + "Result_" + TCollection_AsciiString(aNumOper) + ".brep";
BRepTools::Write(theResult, aNameRes.ToCString());
}
else
{
fprintf(afile, "%s\n", "# Result is Null ");
}
fprintf(afile, "%s %s %s\n", "restore", aName1.ToCString(), "arg1");
fprintf(afile, "%s %s %s\n", "restore", aName2.ToCString(), "arg2");
TCollection_AsciiString aBopString;
switch (theOperation)
{
case BOPAlgo_COMMON:
aBopString += "bcommon Res ";
break;
case BOPAlgo_FUSE:
aBopString += "bfuse Res ";
break;
case BOPAlgo_CUT:
case BOPAlgo_CUT21:
aBopString += "bcut Res ";
break;
case BOPAlgo_SECTION:
aBopString += "bsection Res ";
break;
default:
break;
};
aBopString += ("arg1 arg2");
if (theOperation == BOPAlgo_CUT21)
{
aBopString += " 1";
}
fprintf(afile, "%s\n", aBopString.ToCString());
fclose(afile);
}