mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0030145: Modeling Algorithms - Boolean Operations on open solids
Provide possibility to perform Boolean operations on open solids. Implementation of the new method *BOPAlgo_Builder::BuildBOP* performing the construction of the result shape for the given type of Boolean operation. This approach does not rely on the splits of solid to be correct and looks for the faces with necessary state relatively opposite solids to build the result solid. The call to this method is performed from BOP algorithm in case there were open solids in the arguments. Implementation of the draw command *buildbop* performing a call to the method above.
This commit is contained in:
@@ -90,6 +90,7 @@ void BOPTest::ReportAlerts(const Handle(Message_Report)& theReport)
|
||||
{
|
||||
// first report warnings, then errors
|
||||
Message_Gravity anAlertTypes[2] = { Message_Warning, Message_Fail };
|
||||
TCollection_ExtendedString aMsgType[2] = { "Warning: ", "Error: " };
|
||||
for (int iGravity = 0; iGravity < 2; iGravity++)
|
||||
{
|
||||
// report shapes for the same type of alert together
|
||||
@@ -104,7 +105,7 @@ void BOPTest::ReportAlerts(const Handle(Message_Report)& theReport)
|
||||
|
||||
// get alert message
|
||||
Message_Msg aMsg (aIt.Value()->GetMessageKey());
|
||||
TCollection_ExtendedString aText = aMsg.Get();
|
||||
TCollection_ExtendedString aText = aMsgType[iGravity] + aMsg.Get();
|
||||
|
||||
// collect all shapes if any attached to this alert
|
||||
if (BOPTest_Objects::DrawWarnShapes())
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include <BOPAlgo_PaveFiller.hxx>
|
||||
#include <BOPAlgo_Section.hxx>
|
||||
#include <BOPAlgo_Splitter.hxx>
|
||||
#include <BOPDS_DS.hxx>
|
||||
#include <BOPTest.hxx>
|
||||
#include <BOPTest_DrawableShape.hxx>
|
||||
#include <BOPTest_Objects.hxx>
|
||||
@@ -29,6 +30,7 @@
|
||||
#include <DrawTrSurf.hxx>
|
||||
#include <OSD_Timer.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -38,6 +40,7 @@ static Standard_Integer bfillds (Draw_Interpretor&, Standard_Integer, const cha
|
||||
static Standard_Integer bbuild (Draw_Interpretor&, Standard_Integer, const char**);
|
||||
static Standard_Integer bbop (Draw_Interpretor&, Standard_Integer, const char**);
|
||||
static Standard_Integer bsplit (Draw_Interpretor&, Standard_Integer, const char**);
|
||||
static Standard_Integer buildbop (Draw_Interpretor&, Standard_Integer, const char**);
|
||||
|
||||
//=======================================================================
|
||||
//function : PartitionCommands
|
||||
@@ -55,6 +58,20 @@ void BOPTest::PartitionCommands(Draw_Interpretor& theCommands)
|
||||
theCommands.Add("bbuild" , "use bbuild r [-t]" , __FILE__, bbuild, g);
|
||||
theCommands.Add("bbop" , "use bbop r op [-t]", __FILE__, bbop, g);
|
||||
theCommands.Add("bsplit" , "use bsplit r [-t]" , __FILE__, bsplit, g);
|
||||
|
||||
theCommands.Add("buildbop", "Builds the result of BOP basing on the GF.\n"
|
||||
" The command uses classification approach for building the result of BOP\n"
|
||||
" (thus it operates on solids only and can be used on open solids):\n"
|
||||
" - FUSE is built from the faces OUT of all arguments\n"
|
||||
" - COMMON is built from the faces IN any of the object/tools\n"
|
||||
" - CUT is built from the objects faces OUT of the tools and tools faces IN the objects.\n"
|
||||
" Please note that history for solids will not be available.\n\n"
|
||||
" Usage: buildbop result -o s1 [s2 ...] -t s3 [s4 ...] -op operation (common/fuse/cut/tuc)\n"
|
||||
" Where:\n"
|
||||
" result - result shape of the operation\n"
|
||||
" s1 s2 s3 s4 - arguments (solids) of the GF operation\n"
|
||||
" operation - type of boolean operation",
|
||||
__FILE__, buildbop, g);
|
||||
}
|
||||
//=======================================================================
|
||||
//function : bfillds
|
||||
@@ -419,3 +436,157 @@ Standard_Integer bsplit(Draw_Interpretor& di,
|
||||
DBRep::Set(a[1], aR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : buildbop
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Integer buildbop(Draw_Interpretor& di,
|
||||
Standard_Integer n,
|
||||
const char** a)
|
||||
{
|
||||
if (n < 3)
|
||||
{
|
||||
di.PrintHelp(a[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOPDS_PDS pDS = BOPTest_Objects::PDS();
|
||||
if (!pDS)
|
||||
{
|
||||
di << "Error: perform intersection of arguments first";
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOPAlgo_Builder *pBuilder = &BOPTest_Objects::Builder();
|
||||
if (pBuilder->HasErrors())
|
||||
{
|
||||
di << "Error: there were problems during GF";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pBuilder->Arguments().IsEmpty() ||
|
||||
pBuilder->Shape().IsNull())
|
||||
{
|
||||
di << "Error: it seems the GF has not been yet performed";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get arguments and operation
|
||||
TopTools_ListOfShape aLObjects, aLTools;
|
||||
BOPAlgo_Operation anOp = BOPAlgo_UNKNOWN;
|
||||
|
||||
for (Standard_Integer i = 2; i < n; ++i)
|
||||
{
|
||||
if (!strcmp(a[i], "-o") || !strcmp(a[i], "-t"))
|
||||
{
|
||||
if (i == (n - 1))
|
||||
{
|
||||
di << "Error: shapes are expected after the key " << a[i];
|
||||
return 1;
|
||||
}
|
||||
|
||||
TopTools_ListOfShape& aList = !strcmp(a[i], "-o") ? aLObjects : aLTools;
|
||||
Standard_Integer j = i + 1;
|
||||
for (; j < n; ++j)
|
||||
{
|
||||
if (a[j][0] == '-')
|
||||
{
|
||||
// reached the following key
|
||||
i = j - 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get the shape
|
||||
TopoDS_Shape aS = DBRep::Get(a[j]);
|
||||
if (aS.IsNull())
|
||||
{
|
||||
di << "Error: " << a[j] << " is a null shape";
|
||||
return 1;
|
||||
}
|
||||
if (aS.ShapeType() != TopAbs_SOLID)
|
||||
{
|
||||
di << "Error: " << a[j] << " is not a solid";
|
||||
return 1;
|
||||
}
|
||||
if (pDS->Index(aS) < 0)
|
||||
{
|
||||
di << "Error: " << a[j] << " is not an argument of GF";
|
||||
return 1;
|
||||
}
|
||||
aList.Append(aS);
|
||||
}
|
||||
}
|
||||
// End of arguments is reached
|
||||
if (j == n) break;
|
||||
}
|
||||
else if (!strcmp(a[i], "-op"))
|
||||
{
|
||||
if (i == (n - 1))
|
||||
{
|
||||
di << "Error: operation type is expected after the key " << a[i];
|
||||
return 1;
|
||||
}
|
||||
|
||||
++i;
|
||||
if (!strcasecmp(a[i], "common"))
|
||||
anOp = BOPAlgo_COMMON;
|
||||
else if (!strcasecmp(a[i], "fuse"))
|
||||
anOp = BOPAlgo_FUSE;
|
||||
else if (!strcasecmp(a[i], "cut"))
|
||||
anOp = BOPAlgo_CUT;
|
||||
else if (!strcasecmp(a[i], "tuc"))
|
||||
anOp = BOPAlgo_CUT21;
|
||||
else
|
||||
{
|
||||
di << "Error: unknown operation type";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
di << "Error: " << a[i] << " invalid key";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (anOp == BOPAlgo_UNKNOWN)
|
||||
{
|
||||
di << "Error: operation has not been specified";
|
||||
return 1;
|
||||
}
|
||||
|
||||
Standard_Boolean hasObjects = !aLObjects.IsEmpty();
|
||||
Standard_Boolean hasTools = !aLTools.IsEmpty();
|
||||
if (!hasObjects && !hasTools)
|
||||
{
|
||||
di << "Error: no shapes are given";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create new report for the operation
|
||||
Handle(Message_Report) aReport = new Message_Report;
|
||||
|
||||
// Build specific operation
|
||||
pBuilder->BuildBOP(aLObjects, aLTools, anOp, aReport);
|
||||
|
||||
// Report alerts of the operation
|
||||
BOPTest::ReportAlerts(aReport);
|
||||
|
||||
if (!aReport->GetAlerts(Message_Fail).IsEmpty())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set history of Split operation into the session
|
||||
if (BRepTest_Objects::IsHistoryNeeded())
|
||||
BRepTest_Objects::SetHistory(pDS->Arguments(), *pBuilder);
|
||||
|
||||
// Result shape
|
||||
const TopoDS_Shape& aR = pBuilder->Shape();
|
||||
// Draw result shape
|
||||
DBRep::Set(a[1], aR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user