diff --git a/doc/salome/examples/boolean_operations_ex01.py b/doc/salome/examples/boolean_operations_ex01.py
index 01809955e..7c365d7eb 100644
--- a/doc/salome/examples/boolean_operations_ex01.py
+++ b/doc/salome/examples/boolean_operations_ex01.py
@@ -20,22 +20,32 @@ cylinder = geompy.MakeCylinder(p1, v, radius1, height)
# create a sphere
sphere = geompy.MakeSphereR(40)
+# create a box
+box = geompy.MakeBoxDXDYDZ(80, 80, 80)
+
# fuse
fuse1 = geompy.MakeFuse(cylinder, sphere)
fuse2 = geompy.MakeBoolean(cylinder, sphere, 3)
+fuse3 = geompy.MakeFuseList([cylinder, sphere, box])
# add objects in the study
id_cylinder = geompy.addToStudy(cylinder, "Cylinder")
id_sphere = geompy.addToStudy(sphere, "Sphere")
+id_box = geompy.addToStudy(box, "Box")
id_fuse1 = geompy.addToStudy(fuse1, "Fuse_1")
id_fuse2 = geompy.addToStudy(fuse2, "Fuse_2")
+id_fuse3 = geompy.addToStudy(fuse3, "Fuse_3")
# display results
gg.createAndDisplayGO(id_cylinder)
gg.setDisplayMode(id_cylinder,1)
gg.createAndDisplayGO(id_sphere)
gg.setDisplayMode(id_sphere,1)
+gg.createAndDisplayGO(id_box)
+gg.setDisplayMode(id_box,1)
gg.createAndDisplayGO(id_fuse1)
gg.setDisplayMode(id_fuse1,1)
gg.createAndDisplayGO(id_fuse2)
gg.setDisplayMode(id_fuse2,1)
+gg.createAndDisplayGO(id_fuse3)
+gg.setDisplayMode(id_fuse3,1)
diff --git a/doc/salome/examples/boolean_operations_ex02.py b/doc/salome/examples/boolean_operations_ex02.py
index 90317ba93..212e313d4 100644
--- a/doc/salome/examples/boolean_operations_ex02.py
+++ b/doc/salome/examples/boolean_operations_ex02.py
@@ -20,12 +20,28 @@ cylinder = geompy.MakeCylinder(p1, v, radius1, height)
# create a sphere
sphere = geompy.MakeSphereR(40)
+# create a box
+box = geompy.MakeBoxDXDYDZ(80, 80, 80)
+
# make common
-common = geompy.MakeCommon(cylinder, sphere)
+common1 = geompy.MakeCommon(cylinder, sphere)
+common2 = geompy.MakeCommonList([cylinder, sphere, box])
# add objects in the study
-id_common = geompy.addToStudy(common, "Common")
+id_cylinder = geompy.addToStudy(cylinder, "Cylinder")
+id_sphere = geompy.addToStudy(sphere, "Sphere")
+id_box = geompy.addToStudy(box, "Box")
+id_common1 = geompy.addToStudy(common1, "Common_1")
+id_common2 = geompy.addToStudy(common2, "Common_2")
# display the results
-gg.createAndDisplayGO(id_common)
-gg.setDisplayMode(id_common,1)
+gg.createAndDisplayGO(id_cylinder)
+gg.setDisplayMode(id_cylinder,1)
+gg.createAndDisplayGO(id_sphere)
+gg.setDisplayMode(id_sphere,1)
+gg.createAndDisplayGO(id_box)
+gg.setDisplayMode(id_box,1)
+gg.createAndDisplayGO(id_common1)
+gg.setDisplayMode(id_common1,1)
+gg.createAndDisplayGO(id_common2)
+gg.setDisplayMode(id_common2,1)
diff --git a/doc/salome/examples/boolean_operations_ex03.py b/doc/salome/examples/boolean_operations_ex03.py
index 7c97b09f0..fdb7545f1 100644
--- a/doc/salome/examples/boolean_operations_ex03.py
+++ b/doc/salome/examples/boolean_operations_ex03.py
@@ -20,12 +20,28 @@ cylinder = geompy.MakeCylinder(p1, v, radius1, height)
# create a sphere
sphere = geompy.MakeSphereR(40)
+# create a box
+box = geompy.MakeBoxDXDYDZ(80, 80, 80)
+
#cut
-cut = geompy.MakeCut(cylinder, sphere)
+cut1 = geompy.MakeCut(cylinder, sphere)
+cut2 = geompy.MakeCutList(cylinder, [sphere, box])
# add objects in the study
-id_cut = geompy.addToStudy(cut, "Cut")
+id_cylinder = geompy.addToStudy(cylinder, "Cylinder")
+id_sphere = geompy.addToStudy(sphere, "Sphere")
+id_box = geompy.addToStudy(box, "Box")
+id_cut1 = geompy.addToStudy(cut1, "Cut_1")
+id_cut2 = geompy.addToStudy(cut2, "Cut_2")
# display the results
-gg.createAndDisplayGO(id_cut)
-gg.setDisplayMode(id_cut,1)
+gg.createAndDisplayGO(id_cylinder)
+gg.setDisplayMode(id_cylinder,1)
+gg.createAndDisplayGO(id_sphere)
+gg.setDisplayMode(id_sphere,1)
+gg.createAndDisplayGO(id_box)
+gg.setDisplayMode(id_box,1)
+gg.createAndDisplayGO(id_cut1)
+gg.setDisplayMode(id_cut1,1)
+gg.createAndDisplayGO(id_cut2)
+gg.setDisplayMode(id_cut2,1)
diff --git a/doc/salome/gui/GEOM/input/common_operation.doc b/doc/salome/gui/GEOM/input/common_operation.doc
index f6903e24c..e24645f31 100644
--- a/doc/salome/gui/GEOM/input/common_operation.doc
+++ b/doc/salome/gui/GEOM/input/common_operation.doc
@@ -2,23 +2,23 @@
\page common_operation_page Common
-For detail description of the Boolean operations please refer to
-this document.
-It provides a general review of the Partition and Boolean
-operations algorithms, describes the usage methodology and highlighs
-major limitations of these operations.
-
To produce a \b Common operation in the Main Menu select Operations - > Boolean - > Common
-This operation cuts the common part of two shapes and transforms it into an independent geometrical object.
+This operation cuts the common part of a list of shapes and transforms it into an independent geometrical object.
-The \b Result will be any \b GEOM_Object.
-TUI Command:geompy.MakeCommon(s1, s2)
-Arguments: Name + 2 shapes.
+The \b Result will be a \b GEOM_Object.
+
+TUI Command:geompy.MakeCommonList(theShapesList)\n
+Arguments: Name + a list of shapes.\n
Advanced option:
\ref restore_presentation_parameters_page "Set presentation parameters and sub-shapes from arguments".
-\image html bool2.png
+\image html bool2.png "Common dialog"
+
+For a particular case with two shapes for the Common operation there is the following TUI command:
+
+TUI Command:geompy.MakeCommon(s1, s2)\n
+Arguments: Name + 2 shapes.
Example:
@@ -29,4 +29,12 @@ The \b Result will be any \b GEOM_Object.
Our TUI Scripts provide you with useful examples of the use of
\ref tui_common "Boolean Operations".
+ More details
+
+For a detailed description of the Boolean operations please refer to
+this document.
+It provides a general review of the Partition and Boolean
+operations algorithms, describes the usage methodology and highlights
+major limitations of these operations.
+
*/
diff --git a/doc/salome/gui/GEOM/input/cut_operation.doc b/doc/salome/gui/GEOM/input/cut_operation.doc
index 5ea6c5dfc..d00c587eb 100644
--- a/doc/salome/gui/GEOM/input/cut_operation.doc
+++ b/doc/salome/gui/GEOM/input/cut_operation.doc
@@ -2,23 +2,23 @@
\page cut_operation_page Cut
-For detail description of the Boolean operations please refer to
-this document.
-It provides a general review of the Partition and Boolean
-operations algorithms, describes the usage methodology and highlighs
-major limitations of these operations.
-
To produce a \b Cut operation in the Main Menu select Operations - > Boolean - > Cut
-This operation cuts a shape with another one.
-The \b Result will be any \b GEOM_Object.
-Arguments: Name + 2 shapes.
+This operation cuts a shape with a list of other shapes.
+
+The \b Result will be a \b GEOM_Object.
+
+TUI Command:geompy.MakeCutList(theMainShape, theShapesList)\n
+Arguments: Name + a main shape + a list of other shapes.\n
Advanced option:
\ref restore_presentation_parameters_page "Set presentation parameters and sub-shapes from arguments".
-Dialog Box:
+\image html bool3.png "Cut dialog"
-\image html bool3.png
+For a particular case with two shapes (object and tool) for the Cut operation there is the following TUI command:
+
+TUI Command:geompy.MakeCut(s1, s2)\n
+Arguments: Name + the object + the tool.
Example:
@@ -29,4 +29,12 @@ The \b Result will be any \b GEOM_Object.
Our TUI Scripts provide you with useful examples of the use of
\ref tui_cut "Boolean Operations".
+ More details
+
+For a detailed description of the Boolean operations please refer to
+this document.
+It provides a general review of the Partition and Boolean
+operations algorithms, describes the usage methodology and highlights
+major limitations of these operations.
+
*/
diff --git a/doc/salome/gui/GEOM/input/fuse_operation.doc b/doc/salome/gui/GEOM/input/fuse_operation.doc
index df13c732e..b45e580a8 100644
--- a/doc/salome/gui/GEOM/input/fuse_operation.doc
+++ b/doc/salome/gui/GEOM/input/fuse_operation.doc
@@ -5,8 +5,21 @@
To produce a \b Fuse operation in the Main Menu select
Operations - > Boolean - > Fuse.
-This operation creates one shape from two shapes.
-The \b Result will be any \b GEOM_Object.
+This operation creates one shape from a list of shapes.
+
+The \b Result will be a \b GEOM_Object.
+
+TUI Command:geompy.MakeFuseList(theShapesList)\n
+Arguments: Name + a list of shapes.\n
+Advanced option:
+\ref restore_presentation_parameters_page "Set presentation parameters and sub-shapes from arguments".
+
+\image html bool1.png "Fuse dialog"
+
+For a particular case with two shapes to be fused there is the following TUI command:
+
+TUI Command:geompy.MakeFuse(s1, s2)\n
+Arguments: Name + 2 shapes.
Example:
@@ -14,13 +27,6 @@ The \b Result will be any \b GEOM_Object.
\image html fusesn2.png "The resulting fuse"
-TUI Command:geompy.MakeFuse(s1, s2)\n
-Arguments: Name + 2 shapes.\n
-Advanced option:
-\ref restore_presentation_parameters_page "Set presentation parameters and sub-shapes from arguments".
-
-\image html bool1.png
-
Our TUI Scripts provide you with useful examples of the use of
\ref tui_fuse "Boolean Operations".
diff --git a/doc/salome/gui/GEOM/input/section_operation.doc b/doc/salome/gui/GEOM/input/section_operation.doc
index 383f1c5de..5d60cf433 100644
--- a/doc/salome/gui/GEOM/input/section_operation.doc
+++ b/doc/salome/gui/GEOM/input/section_operation.doc
@@ -2,24 +2,19 @@
\page section_opeartion_page Section
-For detail description of the Boolean operations please refer to
-this document.
-It provides a general review of the Partition and Boolean
-operations algorithms, describes the usage methodology and highlighs
-major limitations of these operations.
-
To produce a \b Section operation in the Main Menu select
Operations - > Boolean - > Section
This operation creates the section between 2 shapes.
The \b Result will be any \b GEOM_Object (EDGE or WIRE).
-TUI Command:geompy.MakeSection(s1, s2)
-Arguments: Name + 2 shapes.
+
+TUI Command:geompy.MakeSection(s1, s2)\n
+Arguments: Name + 2 shapes.\n
Advanced option:
\ref restore_presentation_parameters_page "Set presentation parameters and sub-shapes from arguments".
-\image html neo-section.png
+\image html neo-section.png "Section dialog"
Example:
@@ -30,4 +25,12 @@ The \b Result will be any \b GEOM_Object (EDGE or WIRE).
Our TUI Scripts provide you with useful examples of the use of
\ref tui_section "Boolean Operations".
+ More details
+
+For a detailed description of the Boolean operations please refer to
+this document.
+It provides a general review of the Partition and Boolean
+operations algorithms, describes the usage methodology and highlights
+major limitations of these operations.
+
*/
diff --git a/doc/salome/gui/GEOM/input/using_boolean_operations.doc b/doc/salome/gui/GEOM/input/using_boolean_operations.doc
index d0bca5b6a..84301523e 100644
--- a/doc/salome/gui/GEOM/input/using_boolean_operations.doc
+++ b/doc/salome/gui/GEOM/input/using_boolean_operations.doc
@@ -12,16 +12,35 @@ You can use the following boolean operations for construction of more
complex geometrical objects (2D & 3D elements):
-
\subpage fuse_operation_page "Fuse" - creates a shape from two shapes.
+
\subpage fuse_operation_page "Fuse" - creates a shape from a list of shapes.
\subpage common_operation_page "Common" - transforms the common part
-of two objects into an independent object.
+of a list of objects into an independent object.
\subpage cut_operation_page "Cut" - cuts one shape with
-another.
+a list of others.
\subpage section_opeartion_page "Section" - creates a section between two shapes.
-There is a general TUI command covering all these operations, which
-can be used alongside with separate commands for each operation.
+You can use advanced TUI commands performing these operations
+independently from each other:
+\par
+geompy.MakeFuseList(theShapesList), where \em theShapesList is
+the list of shapes for Fuse operation;
+\par
+geompy.MakeCommonList(theShapesList), where \em theShapesList is
+the list of shapes for Common operation;
+\par
+geompy.MakeCutList(theMainShape, theShapesList), where \em
+theMainShape is the object of the operation and \em theShapesList is
+the list of tools for Cut operation;
+\par
+geompy.MakeSection(Shape1, Shape2), where \em Shape1 is the first
+argument and \em Shape2 is the second argument of Section operation;
+
+
+There are several TUI commands that can be used to perform boolean operations
+with only two arguments. There is a general TUI command covering these
+operations, which can be used alongside with separate commands for each
+operation.
\par
geompy.MakeBoolean(Shape1, Shape2, Operation), where \em
Shape1 is the first argument and \em Shape2 is the second argument of
@@ -32,17 +51,14 @@ Boolean operation, \em Operation is a type of the Boolean operation (1
Besides, you can use advanced TUI commands performing these operations
independently from each other:
\par
-geompy.MakeFuse(Shape1, Shape2), where \em Shape1 and \em
-Shape2 is the second argument of Fuse operation;
+geompy.MakeFuse(Shape1, Shape2), where \em Shape1 is the first
+argument and \em Shape2 is the second argument of Fuse operation;
\par
-geompy.MakeCommon(Shape1, Shape2), where \em Shape1 and \em
-Shape2 is the second argument of Common operation;
+geompy.MakeCommon(Shape1, Shape2), where \em Shape1 is the first
+argument and \em Shape2 is the second argument of Common operation;
\par
-geompy.MakeCut(Shape1, Shape2), where \em Shape1 and \em
-Shape2 is the second argument of Cut operation;
-\par
-geompy.MakeSection(Shape1, Shape2), where \em Shape1 and \em
-Shape2 is the second argument of Section operation;
+geompy.MakeCut(Shape1, Shape2), where \em Shape1 is the first
+argument and \em Shape2 is the second argument of Cut operation;
Our TUI Scripts provide you with useful examples of the use of
\ref tui_boolean_operations_page "Boolean Operations".
diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl
index b3b95cedb..1395c5859 100644
--- a/idl/GEOM_Gen.idl
+++ b/idl/GEOM_Gen.idl
@@ -2675,6 +2675,29 @@ module GEOM
in GEOM_Object theShape2,
in long theOperation);
+ /*!
+ * \brief Perform fusion boolean operation on list of objects.
+ * \param theShapes Shapes to be fused.
+ * \return New GEOM_Object, containing the result shape.
+ */
+ GEOM_Object MakeFuseList (in ListOfGO theShapes);
+
+ /*!
+ * \brief Perform common boolean operation on list of objects.
+ * \param theShapes Shapes for common operation.
+ * \return New GEOM_Object, containing the result shape.
+ */
+ GEOM_Object MakeCommonList (in ListOfGO theShapes);
+
+ /*!
+ * \brief Perform cutting of list of objects from theMainShape.
+ * \param theMainShape the object for cut operation.
+ * \param theShapes Shapes to be cut from theMainShape (tools).
+ * \return New GEOM_Object, containing the result shape.
+ */
+ GEOM_Object MakeCutList (in GEOM_Object theMainShape,
+ in ListOfGO theShapes);
+
/*!
* \brief Perform partition operation.
*
diff --git a/src/BooleanGUI/BooleanGUI_Dialog.cxx b/src/BooleanGUI/BooleanGUI_Dialog.cxx
index 1ee191665..b312686e3 100644
--- a/src/BooleanGUI/BooleanGUI_Dialog.cxx
+++ b/src/BooleanGUI/BooleanGUI_Dialog.cxx
@@ -35,6 +35,7 @@
#include
#include
#include
+#include
// VSR 22/08/2012: issue 0021787: remove "Preview" button from BOP and Partition operations
// Comment next line to enable preview in BOP dialog box
@@ -95,19 +96,27 @@ BooleanGUI_Dialog::BooleanGUI_Dialog (const int theOperation, GeometryGUI* theGe
myGroup = new DlgRef_2Sel(centralWidget());
myGroup->GroupBox1->setTitle(tr("GEOM_ARGUMENTS"));
- if (myOperation != BooleanGUI::CUT) {
+ if (myOperation == BooleanGUI::CUT) {
+ myGroup->TextLabel1->setText(tr("GEOM_MAIN_OBJECT"));
+ myGroup->TextLabel2->setText(tr("GEOM_TOOL_OBJECTS"));
+ }
+ else if (myOperation == BooleanGUI::SECTION) {
myGroup->TextLabel1->setText(tr("GEOM_OBJECT_I").arg(1));
myGroup->TextLabel2->setText(tr("GEOM_OBJECT_I").arg(2));
- }
- else {
- myGroup->TextLabel1->setText(tr("GEOM_MAIN_OBJECT"));
- myGroup->TextLabel2->setText(tr("GEOM_TOOL_OBJECT"));
+ } else { // Fuse or Common
+ myGroup->TextLabel1->setText(tr( "GEOM_SELECTED_OBJECTS" ));
+ myGroup->TextLabel2->hide();
+ myGroup->PushButton2->hide();
+ myGroup->LineEdit2->hide();
}
myGroup->PushButton1->setIcon(image1);
- myGroup->PushButton2->setIcon(image1);
myGroup->LineEdit1->setReadOnly(true);
- myGroup->LineEdit2->setReadOnly(true);
+
+ if (myOperation != BooleanGUI::FUSE && myOperation != BooleanGUI::COMMON) {
+ myGroup->PushButton2->setIcon(image1);
+ myGroup->LineEdit2->setReadOnly(true);
+ }
QVBoxLayout* layout = new QVBoxLayout(centralWidget());
layout->setMargin(0); layout->setSpacing(6);
@@ -144,14 +153,17 @@ void BooleanGUI_Dialog::Init()
myGroup->LineEdit1->setText("");
myGroup->LineEdit2->setText("");
myObject1.nullify();
- myObject2.nullify();
+ reset();
// signals and slots connections
connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk()));
connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
connect(myGroup->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
- connect(myGroup->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
+
+ if (!myGroup->PushButton2->isHidden()) {
+ connect(myGroup->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
+ }
connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(),
SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
@@ -198,10 +210,20 @@ bool BooleanGUI_Dialog::ClickOnApply()
}
//=================================================================================
-// function : SelectionIntoArgument()
-// purpose : Called when selection is changed or on dialog initialization or activation
+// function : reset()
+// purpose :
//=================================================================================
-void BooleanGUI_Dialog::SelectionIntoArgument()
+void BooleanGUI_Dialog::reset()
+{
+ myObjects = new GEOM::ListOfGO;
+ myObjects->length( 0 );
+}
+
+//=================================================================================
+// function : singleSelection
+// purpose : Performs single selection. Called from SelectionIntoArgument()
+//=================================================================================
+void BooleanGUI_Dialog::singleSelection()
{
myEditCurrentArgument->setText("");
@@ -219,19 +241,67 @@ void BooleanGUI_Dialog::SelectionIntoArgument()
if (myEditCurrentArgument == myGroup->LineEdit1) {
myObject1 = aSelectedObject;
- if (!myObject2)
+ if (!myGroup->PushButton2->isHidden() && !myObjects->length())
myGroup->PushButton2->click();
}
else if (myEditCurrentArgument == myGroup->LineEdit2) {
- myObject2 = aSelectedObject;
+ myObjects->length(1);
+ myObjects[0] = aSelectedObject.get();
if (!myObject1)
myGroup->PushButton1->click();
}
}
else {
if (myEditCurrentArgument == myGroup->LineEdit1) myObject1.nullify();
- else if (myEditCurrentArgument == myGroup->LineEdit2) myObject2.nullify();
+ else if (myEditCurrentArgument == myGroup->LineEdit2) reset();
}
+}
+
+//=================================================================================
+// function : multipleSelection
+// purpose : Performs multiple selection. Called from SelectionIntoArgument()
+//=================================================================================
+void BooleanGUI_Dialog::multipleSelection()
+{
+ myEditCurrentArgument->setText( "" );
+ reset();
+
+ LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
+ SALOME_ListIO aSelList;
+ aSelMgr->selectedObjects(aSelList);
+ myObjects->length(aSelList.Extent());
+
+ int i = 0;
+ for (SALOME_ListIteratorOfListIO anIt (aSelList); anIt.More(); anIt.Next()) {
+ GEOM::GEOM_Object_var aSelectedObject = GEOMBase::ConvertIOinGEOMObject( anIt.Value() );
+
+ if ( !CORBA::is_nil( aSelectedObject ) ) {
+ myObjects[i++] = aSelectedObject;
+ }
+ }
+
+ myObjects->length( i );
+ if ( i == 1 ) {
+ myEditCurrentArgument->setText( GEOMBase::GetName( myObjects[0] ) );
+ } else if ( i > 0 ) {
+ myEditCurrentArgument->setText( QString::number( i ) + "_" + tr( "GEOM_OBJECTS" ) );
+ }
+}
+
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose : Called when selection is changed or on dialog initialization or activation
+//=================================================================================
+void BooleanGUI_Dialog::SelectionIntoArgument()
+{
+ if ( myOperation == BooleanGUI::SECTION ||
+ (myOperation == BooleanGUI::CUT &&
+ myEditCurrentArgument == myGroup->LineEdit1)) {
+ singleSelection();
+ } else {
+ multipleSelection();
+ }
+
processPreview();
}
@@ -246,8 +316,10 @@ void BooleanGUI_Dialog::SetEditCurrentArgument()
if (send == myGroup->PushButton1) {
myEditCurrentArgument = myGroup->LineEdit1;
- myGroup->PushButton2->setDown(false);
- myGroup->LineEdit2->setEnabled(false);
+ if (!myGroup->PushButton2->isHidden()) {
+ myGroup->PushButton2->setDown(false);
+ myGroup->LineEdit2->setEnabled(false);
+ }
}
else if (send == myGroup->PushButton2) {
myEditCurrentArgument = myGroup->LineEdit2;
@@ -301,7 +373,24 @@ GEOM::GEOM_IOperations_ptr BooleanGUI_Dialog::createOperation()
//=================================================================================
bool BooleanGUI_Dialog::isValid (QString&)
{
- return myObject1 && myObject2;
+ bool isOK = false;
+
+ switch (myOperation) {
+ case BooleanGUI::FUSE:
+ case BooleanGUI::COMMON:
+ isOK = myObjects->length() > 1;
+ break;
+ case BooleanGUI::CUT:
+ isOK = myObject1 && myObjects->length();
+ break;
+ case BooleanGUI::SECTION:
+ isOK = myObject1 && (myObjects->length() == 1);
+ break;
+ default:
+ break;
+ }
+
+ return isOK;
}
//=================================================================================
@@ -313,7 +402,24 @@ bool BooleanGUI_Dialog::execute (ObjectList& objects)
GEOM::GEOM_Object_var anObj;
GEOM::GEOM_IBooleanOperations_var anOper = GEOM::GEOM_IBooleanOperations::_narrow(getOperation());
- anObj = anOper->MakeBoolean(myObject1.get(), myObject2.get(), myOperation);
+
+ switch (myOperation) {
+ case BooleanGUI::FUSE:
+ anObj = anOper->MakeFuseList(myObjects);
+ break;
+ case BooleanGUI::COMMON:
+ anObj = anOper->MakeCommonList(myObjects);
+ break;
+ case BooleanGUI::CUT:
+ anObj = anOper->MakeCutList(myObject1.get(), myObjects);
+ break;
+ case BooleanGUI::SECTION:
+ anObj = anOper->MakeBoolean(myObject1.get(), myObjects[0], myOperation);
+ break;
+ default:
+ break;
+ }
+
if (!anObj->_is_nil())
objects.push_back(anObj._retn());
diff --git a/src/BooleanGUI/BooleanGUI_Dialog.h b/src/BooleanGUI/BooleanGUI_Dialog.h
index 4601cc97d..14d84ffd9 100644
--- a/src/BooleanGUI/BooleanGUI_Dialog.h
+++ b/src/BooleanGUI/BooleanGUI_Dialog.h
@@ -55,12 +55,15 @@ protected:
private:
void Init();
void enterEvent( QEvent* );
+ void reset();
+ void singleSelection();
+ void multipleSelection();
private:
int myOperation;
GEOM::GeomObjPtr myObject1;
- GEOM::GeomObjPtr myObject2;
+ GEOM::ListOfGO_var myObjects;
DlgRef_2Sel* myGroup;
diff --git a/src/GEOMGUI/GEOM_msg_en.ts b/src/GEOMGUI/GEOM_msg_en.ts
index a853aa998..2d94e74b7 100644
--- a/src/GEOMGUI/GEOM_msg_en.ts
+++ b/src/GEOMGUI/GEOM_msg_en.ts
@@ -439,7 +439,7 @@ Please, select face, shell or solid and try again
- Common Of Two Objects
+ Common Of Objects
@@ -507,7 +507,7 @@ Please, select face, shell or solid and try again
- Cut Of Two Objects
+ Cut Of Objects
@@ -836,7 +836,7 @@ Please, select face, shell or solid and try again
- Fuse Two Objects
+ Fuse Objects
@@ -2142,10 +2142,6 @@ Please, select face, shell or solid and try again
Vertex :
-
-
- Tool Object
- Tool Objects
diff --git a/src/GEOMGUI/GEOM_msg_fr.ts b/src/GEOMGUI/GEOM_msg_fr.ts
index f8dd0ec20..3676d3905 100644
--- a/src/GEOMGUI/GEOM_msg_fr.ts
+++ b/src/GEOMGUI/GEOM_msg_fr.ts
@@ -439,7 +439,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau
- Intersection de deux objets
+ Intersection des objets
@@ -507,7 +507,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau
- Découpe de deux objets
+ Découpe des objets
@@ -836,7 +836,7 @@ Choisissez une face, une coque ou un solide et essayez de nouveau
- Réunir deux objets
+ Réunir des objets
@@ -2142,10 +2142,6 @@ Choisissez une face, une coque ou un solide et essayez de nouveau
Point:
-
-
- Objet outil
- Objets outils
diff --git a/src/GEOMImpl/GEOMImpl_BooleanDriver.cxx b/src/GEOMImpl/GEOMImpl_BooleanDriver.cxx
index a0af1efd6..8cc9f8bfd 100644
--- a/src/GEOMImpl/GEOMImpl_BooleanDriver.cxx
+++ b/src/GEOMImpl/GEOMImpl_BooleanDriver.cxx
@@ -41,7 +41,6 @@
#include
#include
-#include
#include
#include
#include
@@ -87,124 +86,166 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const
TopoDS_Shape aShape;
- Handle(GEOM_Function) aRefShape1 = aCI.GetShape1();
- Handle(GEOM_Function) aRefShape2 = aCI.GetShape2();
- TopoDS_Shape aShape1 = aRefShape1->GetValue();
- TopoDS_Shape aShape2 = aRefShape2->GetValue();
+ switch (aType) {
+ case BOOLEAN_COMMON:
+ case BOOLEAN_CUT:
+ case BOOLEAN_FUSE:
+ case BOOLEAN_SECTION:
+ {
+ Handle(GEOM_Function) aRefShape1 = aCI.GetShape1();
+ Handle(GEOM_Function) aRefShape2 = aCI.GetShape2();
+ TopoDS_Shape aShape1 = aRefShape1->GetValue();
+ TopoDS_Shape aShape2 = aRefShape2->GetValue();
- if (!aShape1.IsNull() && !aShape2.IsNull()) {
- // check arguments for Mantis issue 0021019
- BRepCheck_Analyzer ana (aShape1, Standard_True);
- if (!ana.IsValid())
- StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
- ana.Init(aShape2);
- if (!ana.IsValid())
- StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
+ if (!aShape1.IsNull() && !aShape2.IsNull()) {
+ // check arguments for Mantis issue 0021019
+ BRepCheck_Analyzer ana (aShape1, Standard_True);
+ if (!ana.IsValid())
+ StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
+ ana.Init(aShape2);
+ if (!ana.IsValid())
+ StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
- // perform COMMON operation
- if (aType == BOOLEAN_COMMON) {
- BRep_Builder B;
- TopoDS_Compound C;
- B.MakeCompound(C);
+ aShape = performOperation (aShape1, aShape2, aType);
- TopTools_ListOfShape listShape1, listShape2;
- GEOMUtils::AddSimpleShapes(aShape1, listShape1);
- GEOMUtils::AddSimpleShapes(aShape2, listShape2);
-
- Standard_Boolean isCompound =
- (listShape1.Extent() > 1 || listShape2.Extent() > 1);
-
- TopTools_ListIteratorOfListOfShape itSub1 (listShape1);
- for (; itSub1.More(); itSub1.Next()) {
- TopoDS_Shape aValue1 = itSub1.Value();
- TopTools_ListIteratorOfListOfShape itSub2 (listShape2);
- for (; itSub2.More(); itSub2.Next()) {
- TopoDS_Shape aValue2 = itSub2.Value();
- BRepAlgoAPI_Common BO (aValue1, aValue2);
- if (!BO.IsDone()) {
- StdFail_NotDone::Raise("Common operation can not be performed on the given shapes");
- }
- if (isCompound) {
- TopoDS_Shape aStepResult = BO.Shape();
-
- // check result of this step: if it is a compound (boolean operations
- // allways return a compound), we add all sub-shapes of it.
- // This allows to avoid adding empty compounds,
- // resulting from COMMON on two non-intersecting shapes.
- if (aStepResult.ShapeType() == TopAbs_COMPOUND) {
- TopoDS_Iterator aCompIter (aStepResult);
- for (; aCompIter.More(); aCompIter.Next()) {
- // add shape in a result
- B.Add(C, aCompIter.Value());
- }
- }
- else {
- // add shape in a result
- B.Add(C, aStepResult);
- }
- }
- else
- aShape = BO.Shape();
- }
- }
-
- if (isCompound) {
- /*
- TopTools_ListOfShape listShapeC;
- GEOMUtils::AddSimpleShapes(C, listShapeC);
- TopTools_ListIteratorOfListOfShape itSubC (listShapeC);
- bool isOnlySolids = true;
- for (; itSubC.More(); itSubC.Next()) {
- TopoDS_Shape aValueC = itSubC.Value();
- if (aValueC.ShapeType() != TopAbs_SOLID) isOnlySolids = false;
- }
- if (isOnlySolids)
- aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion());
- else
- aShape = C;
- */
-
- // As GlueFaces has been improved to keep all kind of shapes
- TopExp_Explorer anExp (C, TopAbs_VERTEX);
- if (anExp.More())
- aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
- else
- aShape = C;
+ if (aShape.IsNull())
+ return 0;
}
}
+ break;
+ case BOOLEAN_COMMON_LIST:
+ case BOOLEAN_FUSE_LIST:
+ {
+ Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
+ const Standard_Integer nbShapes = aShapes->Length();
+ Standard_Integer i;
+ Handle(GEOM_Function) aRefShape;
+ TopoDS_Shape aShape2;
+ Standard_Integer aSimpleType =
+ (aType == BOOLEAN_FUSE_LIST ? BOOLEAN_FUSE : BOOLEAN_COMMON);
- // perform CUT operation
- else if (aType == BOOLEAN_CUT) {
- BRep_Builder B;
- TopoDS_Compound C;
- B.MakeCompound(C);
+ if (nbShapes > 0) {
+ aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(1));
+ aShape = aRefShape->GetValue();
- TopTools_ListOfShape listShapes, listTools;
- GEOMUtils::AddSimpleShapes(aShape1, listShapes);
- GEOMUtils::AddSimpleShapes(aShape2, listTools);
+ if (!aShape.IsNull()) {
+ BRepCheck_Analyzer anAna (aShape, Standard_True);
- Standard_Boolean isCompound = (listShapes.Extent() > 1);
-
- TopTools_ListIteratorOfListOfShape itSub1 (listShapes);
- for (; itSub1.More(); itSub1.Next()) {
- TopoDS_Shape aCut = itSub1.Value();
- // tools
- TopTools_ListIteratorOfListOfShape itSub2 (listTools);
- for (; itSub2.More(); itSub2.Next()) {
- TopoDS_Shape aTool = itSub2.Value();
- BRepAlgoAPI_Cut BO (aCut, aTool);
- if (!BO.IsDone()) {
- StdFail_NotDone::Raise("Cut operation can not be performed on the given shapes");
+ if (!anAna.IsValid()) {
+ StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
}
- aCut = BO.Shape();
+
+ for (i = 2; i <= nbShapes; i++) {
+ aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(i));
+ aShape2 = aRefShape->GetValue();
+ anAna.Init(aShape2);
+
+ if (!anAna.IsValid()) {
+ StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
+ }
+
+ aShape = performOperation (aShape, aShape2, aSimpleType);
+
+ if (aShape.IsNull()) {
+ return 0;
+ }
+ }
+ }
+ }
+ }
+ break;
+ case BOOLEAN_CUT_LIST:
+ {
+ Handle(GEOM_Function) aRefObject = aCI.GetShape1();
+
+ aShape = aRefObject->GetValue();
+
+ if (!aShape.IsNull()) {
+ // check arguments for Mantis issue 0021019
+ BRepCheck_Analyzer anAna (aShape, Standard_True);
+
+ if (!anAna.IsValid()) {
+ StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
+ }
+
+ Handle(TColStd_HSequenceOfTransient) aTools = aCI.GetShapes();
+ const Standard_Integer nbShapes = aTools->Length();
+ Standard_Integer i;
+ Handle(GEOM_Function) aRefTool;
+ TopoDS_Shape aTool;
+
+ for (i = 1; i <= nbShapes; i++) {
+ aRefTool = Handle(GEOM_Function)::DownCast(aTools->Value(i));
+ aTool = aRefTool->GetValue();
+ anAna.Init(aTool);
+
+ if (!anAna.IsValid()) {
+ StdFail_NotDone::Raise("Boolean operation will not be performed, because argument shape is not valid");
+ }
+
+ aShape = performOperation (aShape, aTool, BOOLEAN_CUT);
+
+ if (aShape.IsNull()) {
+ return 0;
+ }
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ aFunction->SetValue(aShape);
+
+ log.SetTouched(Label());
+
+ return 1;
+}
+
+//=======================================================================
+//function : performOperation
+//purpose :
+//=======================================================================
+TopoDS_Shape GEOMImpl_BooleanDriver::performOperation
+ (const TopoDS_Shape theShape1,
+ const TopoDS_Shape theShape2,
+ const Standard_Integer theType)const
+{
+ TopoDS_Shape aShape;
+
+ // perform COMMON operation
+ if (theType == BOOLEAN_COMMON) {
+ BRep_Builder B;
+ TopoDS_Compound C;
+ B.MakeCompound(C);
+
+ TopTools_ListOfShape listShape1, listShape2;
+ GEOMUtils::AddSimpleShapes(theShape1, listShape1);
+ GEOMUtils::AddSimpleShapes(theShape2, listShape2);
+
+ Standard_Boolean isCompound =
+ (listShape1.Extent() > 1 || listShape2.Extent() > 1);
+
+ TopTools_ListIteratorOfListOfShape itSub1 (listShape1);
+ for (; itSub1.More(); itSub1.Next()) {
+ TopoDS_Shape aValue1 = itSub1.Value();
+ TopTools_ListIteratorOfListOfShape itSub2 (listShape2);
+ for (; itSub2.More(); itSub2.Next()) {
+ TopoDS_Shape aValue2 = itSub2.Value();
+ BRepAlgoAPI_Common BO (aValue1, aValue2);
+ if (!BO.IsDone()) {
+ StdFail_NotDone::Raise("Common operation can not be performed on the given shapes");
}
if (isCompound) {
+ TopoDS_Shape aStepResult = BO.Shape();
+
// check result of this step: if it is a compound (boolean operations
// allways return a compound), we add all sub-shapes of it.
// This allows to avoid adding empty compounds,
- // resulting from CUT of parts
- if (aCut.ShapeType() == TopAbs_COMPOUND) {
- TopoDS_Iterator aCompIter (aCut);
+ // resulting from COMMON on two non-intersecting shapes.
+ if (aStepResult.ShapeType() == TopAbs_COMPOUND) {
+ TopoDS_Iterator aCompIter (aStepResult);
for (; aCompIter.More(); aCompIter.Next()) {
// add shape in a result
B.Add(C, aCompIter.Value());
@@ -212,200 +253,163 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const
}
else {
// add shape in a result
- B.Add(C, aCut);
+ B.Add(C, aStepResult);
}
}
else
- aShape = aCut;
- }
-
- if (isCompound) {
- /*
- TopTools_ListOfShape listShapeC;
- GEOMUtils::AddSimpleShapes(C, listShapeC);
- TopTools_ListIteratorOfListOfShape itSubC (listShapeC);
- bool isOnlySolids = true;
- for (; itSubC.More(); itSubC.Next()) {
- TopoDS_Shape aValueC = itSubC.Value();
- if (aValueC.ShapeType() != TopAbs_SOLID) isOnlySolids = false;
- }
- if (isOnlySolids)
- aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion());
- else
- aShape = C;
- */
-
- // As GlueFaces has been improved to keep all kind of shapes
- TopExp_Explorer anExp (C, TopAbs_VERTEX);
- if (anExp.More())
- aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
- else
- aShape = C;
+ aShape = BO.Shape();
}
}
- // perform FUSE operation
- else if (aType == BOOLEAN_FUSE) {
- /* Fix for NPAL15379: refused
- // Check arguments
- TopTools_ListOfShape listShape1, listShape2;
- GEOMUtils::AddSimpleShapes(aShape1, listShape1);
- GEOMUtils::AddSimpleShapes(aShape2, listShape2);
-
- Standard_Boolean isIntersect = Standard_False;
-
- if (listShape1.Extent() > 1 && !isIntersect) {
- // check intersections inside the first compound
- TopTools_ListIteratorOfListOfShape it1 (listShape1);
- for (; it1.More() && !isIntersect; it1.Next()) {
- TopoDS_Shape aValue1 = it1.Value();
- TopTools_ListIteratorOfListOfShape it2 (listShape1);
- for (; it2.More() && !isIntersect; it2.Next()) {
- TopoDS_Shape aValue2 = it2.Value();
- if (aValue2 != aValue1) {
- BRepAlgoAPI_Section BO (aValue1, aValue2);
- if (BO.IsDone()) {
- TopoDS_Shape aSect = BO.Shape();
- TopExp_Explorer anExp (aSect, TopAbs_EDGE);
- if (anExp.More()) {
- isIntersect = Standard_True;
- }
- }
- }
- }
- }
- }
-
- if (listShape2.Extent() > 1 && !isIntersect) {
- // check intersections inside the second compound
- TopTools_ListIteratorOfListOfShape it1 (listShape2);
- for (; it1.More() && !isIntersect; it1.Next()) {
- TopoDS_Shape aValue1 = it1.Value();
- TopTools_ListIteratorOfListOfShape it2 (listShape2);
- for (; it2.More() && !isIntersect; it2.Next()) {
- TopoDS_Shape aValue2 = it2.Value();
- if (aValue2 != aValue1) {
- BRepAlgoAPI_Section BO (aValue1, aValue2);
- if (BO.IsDone()) {
- TopoDS_Shape aSect = BO.Shape();
- TopExp_Explorer anExp (aSect, TopAbs_EDGE);
- if (anExp.More()) {
- isIntersect = Standard_True;
- }
- }
- }
- }
- }
- }
-
- if (isIntersect) {
- // have intersections inside compounds
- // check intersections between compounds
- TopTools_ListIteratorOfListOfShape it1 (listShape1);
- for (; it1.More(); it1.Next()) {
- TopoDS_Shape aValue1 = it1.Value();
- TopTools_ListIteratorOfListOfShape it2 (listShape2);
- for (; it2.More(); it2.Next()) {
- TopoDS_Shape aValue2 = it2.Value();
- if (aValue2 != aValue1) {
- BRepAlgoAPI_Section BO (aValue1, aValue2);
- if (BO.IsDone()) {
- TopoDS_Shape aSect = BO.Shape();
- TopExp_Explorer anExp (aSect, TopAbs_EDGE);
- if (anExp.More()) {
- StdFail_NotDone::Raise("Bad argument for Fuse: compound with intersecting sub-shapes");
- }
- }
- }
- }
- }
- }
- */
-
- // Perform
- BRepAlgoAPI_Fuse BO (aShape1, aShape2);
- if (!BO.IsDone()) {
- StdFail_NotDone::Raise("Fuse operation can not be performed on the given shapes");
- }
- aShape = BO.Shape();
- }
-
- // perform SECTION operation
- else if (aType == BOOLEAN_SECTION) {
- BRep_Builder B;
- TopoDS_Compound C;
- B.MakeCompound(C);
-
- TopTools_ListOfShape listShape1, listShape2;
- GEOMUtils::AddSimpleShapes(aShape1, listShape1);
- GEOMUtils::AddSimpleShapes(aShape2, listShape2);
-
- Standard_Boolean isCompound =
- (listShape1.Extent() > 1 || listShape2.Extent() > 1);
-
- TopTools_ListIteratorOfListOfShape itSub1 (listShape1);
- for (; itSub1.More(); itSub1.Next()) {
- TopoDS_Shape aValue1 = itSub1.Value();
- TopTools_ListIteratorOfListOfShape itSub2 (listShape2);
- for (; itSub2.More(); itSub2.Next()) {
- TopoDS_Shape aValue2 = itSub2.Value();
- BRepAlgoAPI_Section BO (aValue1, aValue2, Standard_False);
- // Set approximation to have an attached 3D BSpline geometry to each edge,
- // where analytic curve is not possible. Without this flag in some cases
- // we obtain BSpline curve of degree 1 (C0), which is slowly
- // processed by some algorithms (Partition for example).
- BO.Approximation(Standard_True);
- //modified by NIZNHY-PKV Tue Oct 18 14:34:16 2011f
- BO.ComputePCurveOn1(Standard_True);
- BO.ComputePCurveOn2(Standard_True);
- //modified by NIZNHY-PKV Tue Oct 18 14:34:18 2011t
-
- BO.Build();
- if (!BO.IsDone()) {
- StdFail_NotDone::Raise("Section operation can not be performed on the given shapes");
- }
- if (isCompound) {
- TopoDS_Shape aStepResult = BO.Shape();
-
- // check result of this step: if it is a compound (boolean operations
- // allways return a compound), we add all sub-shapes of it.
- // This allows to avoid adding empty compounds,
- // resulting from SECTION on two non-intersecting shapes.
- if (aStepResult.ShapeType() == TopAbs_COMPOUND) {
- TopoDS_Iterator aCompIter (aStepResult);
- for (; aCompIter.More(); aCompIter.Next()) {
- // add shape in a result
- B.Add(C, aCompIter.Value());
- }
- }
- else {
- // add shape in a result
- B.Add(C, aStepResult);
- }
- }
- else
- aShape = BO.Shape();
- }
- }
-
- if (isCompound) {
- //aShape = C;
-
- // As GlueFaces has been improved to keep all kind of shapes
- TopExp_Explorer anExp (C, TopAbs_VERTEX);
- if (anExp.More())
- aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
- else
- aShape = C;
- }
- }
-
- // UNKNOWN operation
- else {
+ if (isCompound) {
+ // As GlueFaces has been improved to keep all kind of shapes
+ TopExp_Explorer anExp (C, TopAbs_VERTEX);
+ if (anExp.More())
+ aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
+ else
+ aShape = C;
}
}
- if (aShape.IsNull()) return 0;
+ // perform CUT operation
+ else if (theType == BOOLEAN_CUT) {
+ BRep_Builder B;
+ TopoDS_Compound C;
+ B.MakeCompound(C);
+
+ TopTools_ListOfShape listShapes, listTools;
+ GEOMUtils::AddSimpleShapes(theShape1, listShapes);
+ GEOMUtils::AddSimpleShapes(theShape2, listTools);
+
+ Standard_Boolean isCompound = (listShapes.Extent() > 1);
+
+ TopTools_ListIteratorOfListOfShape itSub1 (listShapes);
+ for (; itSub1.More(); itSub1.Next()) {
+ TopoDS_Shape aCut = itSub1.Value();
+ // tools
+ TopTools_ListIteratorOfListOfShape itSub2 (listTools);
+ for (; itSub2.More(); itSub2.Next()) {
+ TopoDS_Shape aTool = itSub2.Value();
+ BRepAlgoAPI_Cut BO (aCut, aTool);
+ if (!BO.IsDone()) {
+ StdFail_NotDone::Raise("Cut operation can not be performed on the given shapes");
+ }
+ aCut = BO.Shape();
+ }
+ if (isCompound) {
+ // check result of this step: if it is a compound (boolean operations
+ // allways return a compound), we add all sub-shapes of it.
+ // This allows to avoid adding empty compounds,
+ // resulting from CUT of parts
+ if (aCut.ShapeType() == TopAbs_COMPOUND) {
+ TopoDS_Iterator aCompIter (aCut);
+ for (; aCompIter.More(); aCompIter.Next()) {
+ // add shape in a result
+ B.Add(C, aCompIter.Value());
+ }
+ }
+ else {
+ // add shape in a result
+ B.Add(C, aCut);
+ }
+ }
+ else
+ aShape = aCut;
+ }
+
+ if (isCompound) {
+ // As GlueFaces has been improved to keep all kind of shapes
+ TopExp_Explorer anExp (C, TopAbs_VERTEX);
+ if (anExp.More())
+ aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
+ else
+ aShape = C;
+ }
+ }
+
+ // perform FUSE operation
+ else if (theType == BOOLEAN_FUSE) {
+ // Perform
+ BRepAlgoAPI_Fuse BO (theShape1, theShape2);
+ if (!BO.IsDone()) {
+ StdFail_NotDone::Raise("Fuse operation can not be performed on the given shapes");
+ }
+ aShape = BO.Shape();
+ }
+
+ // perform SECTION operation
+ else if (theType == BOOLEAN_SECTION) {
+ BRep_Builder B;
+ TopoDS_Compound C;
+ B.MakeCompound(C);
+
+ TopTools_ListOfShape listShape1, listShape2;
+ GEOMUtils::AddSimpleShapes(theShape1, listShape1);
+ GEOMUtils::AddSimpleShapes(theShape2, listShape2);
+
+ Standard_Boolean isCompound =
+ (listShape1.Extent() > 1 || listShape2.Extent() > 1);
+
+ TopTools_ListIteratorOfListOfShape itSub1 (listShape1);
+ for (; itSub1.More(); itSub1.Next()) {
+ TopoDS_Shape aValue1 = itSub1.Value();
+ TopTools_ListIteratorOfListOfShape itSub2 (listShape2);
+ for (; itSub2.More(); itSub2.Next()) {
+ TopoDS_Shape aValue2 = itSub2.Value();
+ BRepAlgoAPI_Section BO (aValue1, aValue2, Standard_False);
+ // Set approximation to have an attached 3D BSpline geometry to each edge,
+ // where analytic curve is not possible. Without this flag in some cases
+ // we obtain BSpline curve of degree 1 (C0), which is slowly
+ // processed by some algorithms (Partition for example).
+ BO.Approximation(Standard_True);
+ //modified by NIZNHY-PKV Tue Oct 18 14:34:16 2011f
+ BO.ComputePCurveOn1(Standard_True);
+ BO.ComputePCurveOn2(Standard_True);
+ //modified by NIZNHY-PKV Tue Oct 18 14:34:18 2011t
+
+ BO.Build();
+ if (!BO.IsDone()) {
+ StdFail_NotDone::Raise("Section operation can not be performed on the given shapes");
+ }
+ if (isCompound) {
+ TopoDS_Shape aStepResult = BO.Shape();
+
+ // check result of this step: if it is a compound (boolean operations
+ // allways return a compound), we add all sub-shapes of it.
+ // This allows to avoid adding empty compounds,
+ // resulting from SECTION on two non-intersecting shapes.
+ if (aStepResult.ShapeType() == TopAbs_COMPOUND) {
+ TopoDS_Iterator aCompIter (aStepResult);
+ for (; aCompIter.More(); aCompIter.Next()) {
+ // add shape in a result
+ B.Add(C, aCompIter.Value());
+ }
+ }
+ else {
+ // add shape in a result
+ B.Add(C, aStepResult);
+ }
+ }
+ else
+ aShape = BO.Shape();
+ }
+ }
+
+ if (isCompound) {
+ // As GlueFaces has been improved to keep all kind of shapes
+ TopExp_Explorer anExp (C, TopAbs_VERTEX);
+ if (anExp.More())
+ aShape = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
+ else
+ aShape = C;
+ }
+ }
+
+ // UNKNOWN operation
+ else {
+ }
+
+ if (aShape.IsNull()) return aShape;
// as boolean operations always produce compound, lets simplify it
// for the case, if it contains only one sub-shape
@@ -413,7 +417,7 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const
GEOMUtils::AddSimpleShapes(aShape, listShapeRes);
if (listShapeRes.Extent() == 1) {
aShape = listShapeRes.First();
- if (aShape.IsNull()) return 0;
+ if (aShape.IsNull()) return aShape;
}
// 08.07.2008 skl for bug 19761 from Mantis
@@ -430,9 +434,6 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const
if (!ana.IsValid())
Standard_ConstructionError::Raise("Boolean operation aborted : non valid shape result");
}
- //if (!BRepAlgo::IsValid(aShape)) {
- // Standard_ConstructionError::Raise("Boolean operation aborted : non valid shape result");
- //}
// BEGIN: Mantis issue 0021060: always limit tolerance of BOP result
// 1. Get shape parameters for comparison
@@ -506,24 +507,9 @@ Standard_Integer GEOMImpl_BooleanDriver::Execute (TFunction_Logbook& log) const
}
// END: Mantis issue 0021060
- //Alternative case to check shape result Mantis 0020604: EDF 1172
-/* TopoDS_Iterator It (aShape, Standard_True, Standard_True);
- int nbSubshapes=0;
- for (; It.More(); It.Next())
- nbSubshapes++;
- if (!nbSubshapes)
- Standard_ConstructionError::Raise("Boolean operation aborted : result object is empty compound");*/
- //end of 0020604: EDF 1172
- //! the changes temporary commented because of customer needs (see the same mantis bug)
-
- aFunction->SetValue(aShape);
-
- log.SetTouched(Label());
-
- return 1;
+ return aShape;
}
-
//=======================================================================
//function : GEOMImpl_BooleanDriver_Type_
//purpose :
diff --git a/src/GEOMImpl/GEOMImpl_BooleanDriver.hxx b/src/GEOMImpl/GEOMImpl_BooleanDriver.hxx
index 80e57116c..6bc1af7f2 100644
--- a/src/GEOMImpl/GEOMImpl_BooleanDriver.hxx
+++ b/src/GEOMImpl/GEOMImpl_BooleanDriver.hxx
@@ -51,6 +51,11 @@
#include
#endif
+#ifndef _TopoDS_Shape_HeaderFile
+#include
+#endif
+
+
class Standard_Transient;
class Handle_Standard_Type;
class Handle(TFunction_Driver);
@@ -156,6 +161,12 @@ Standard_EXPORT const Handle(Standard_Type)& DynamicType() const { return STAND
Standard_EXPORT Standard_Boolean IsKind(const Handle(Standard_Type)& AType) const { return (STANDARD_TYPE(GEOMImpl_BooleanDriver) == AType || TFunction_Driver::IsKind(AType)); }
+private:
+
+ TopoDS_Shape performOperation(const TopoDS_Shape theShape1,
+ const TopoDS_Shape theShape2,
+ const Standard_Integer theType) const;
+
};
#endif
diff --git a/src/GEOMImpl/GEOMImpl_IBoolean.hxx b/src/GEOMImpl/GEOMImpl_IBoolean.hxx
index 54c246740..46d5c8e48 100644
--- a/src/GEOMImpl/GEOMImpl_IBoolean.hxx
+++ b/src/GEOMImpl/GEOMImpl_IBoolean.hxx
@@ -23,9 +23,11 @@
//NOTE: This is an intreface to a function for the Common, Cut and Fuse creation.
//
#include "GEOM_Function.hxx"
+#include "TColStd_HSequenceOfTransient.hxx"
#define BOOL_ARG_SHAPE1 1
#define BOOL_ARG_SHAPE2 2
+#define BOOL_ARG_SHAPES 3
class GEOMImpl_IBoolean
{
@@ -35,9 +37,13 @@ class GEOMImpl_IBoolean
void SetShape1(Handle(GEOM_Function) theRef) { _func->SetReference(BOOL_ARG_SHAPE1, theRef); }
void SetShape2(Handle(GEOM_Function) theRef) { _func->SetReference(BOOL_ARG_SHAPE2, theRef); }
+ void SetShapes(const Handle(TColStd_HSequenceOfTransient)& theShapes)
+ { _func->SetReferenceList(BOOL_ARG_SHAPES, theShapes); }
Handle(GEOM_Function) GetShape1() { return _func->GetReference(BOOL_ARG_SHAPE1); }
Handle(GEOM_Function) GetShape2() { return _func->GetReference(BOOL_ARG_SHAPE2); }
+ Handle(TColStd_HSequenceOfTransient) GetShapes()
+ { return _func->GetReferenceList(BOOL_ARG_SHAPES); }
private:
diff --git a/src/GEOMImpl/GEOMImpl_IBooleanOperations.cxx b/src/GEOMImpl/GEOMImpl_IBooleanOperations.cxx
index 3db2537ec..a96b1810b 100644
--- a/src/GEOMImpl/GEOMImpl_IBooleanOperations.cxx
+++ b/src/GEOMImpl/GEOMImpl_IBooleanOperations.cxx
@@ -139,6 +139,185 @@ Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeBoolean (Handle(GEOM_Object
return aBool;
}
+//=============================================================================
+/*!
+ * MakeFuseList
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeFuseList
+ (const Handle(TColStd_HSequenceOfTransient)& theShapes)
+{
+ SetErrorCode(KO);
+
+ if (theShapes.IsNull()) return NULL;
+
+ //Add a new Boolean object
+ Handle(GEOM_Object) aBool = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
+
+ //Add a new Boolean function
+ Handle(GEOM_Function) aFunction =
+ aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_FUSE_LIST);
+
+ if (aFunction.IsNull()) return NULL;
+
+ //Check if the function is set correctly
+ if (aFunction->GetDriverGUID() != GEOMImpl_BooleanDriver::GetID()) return NULL;
+
+ GEOMImpl_IBoolean aCI (aFunction);
+
+ TCollection_AsciiString aDescription;
+ Handle(TColStd_HSequenceOfTransient) aShapesSeq =
+ getShapeFunctions(theShapes, aDescription);
+
+ if (aShapesSeq.IsNull()) return NULL;
+
+ aCI.SetShapes(aShapesSeq);
+
+ //Compute the Boolean value
+ try {
+#if OCC_VERSION_LARGE > 0x06010000
+ OCC_CATCH_SIGNALS;
+#endif
+ if (!GetSolver()->ComputeFunction(aFunction)) {
+ SetErrorCode("Boolean driver failed");
+ return NULL;
+ }
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return NULL;
+ }
+
+ //Make a Python command
+ GEOM::TPythonDump(aFunction) << aBool <<
+ " = geompy.MakeFuseList([" << aDescription.ToCString() << "])";
+
+ SetErrorCode(OK);
+ return aBool;
+}
+
+//=============================================================================
+/*!
+ * MakeCommonList
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeCommonList
+ (const Handle(TColStd_HSequenceOfTransient)& theShapes)
+{
+ SetErrorCode(KO);
+
+ if (theShapes.IsNull()) return NULL;
+
+ //Add a new Boolean object
+ Handle(GEOM_Object) aBool = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
+
+ //Add a new Boolean function
+ Handle(GEOM_Function) aFunction =
+ aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_COMMON_LIST);
+
+ if (aFunction.IsNull()) return NULL;
+
+ //Check if the function is set correctly
+ if (aFunction->GetDriverGUID() != GEOMImpl_BooleanDriver::GetID()) return NULL;
+
+ GEOMImpl_IBoolean aCI (aFunction);
+
+ TCollection_AsciiString aDescription;
+ Handle(TColStd_HSequenceOfTransient) aShapesSeq =
+ getShapeFunctions(theShapes, aDescription);
+
+ if (aShapesSeq.IsNull()) return NULL;
+
+ aCI.SetShapes(aShapesSeq);
+
+ //Compute the Boolean value
+ try {
+#if OCC_VERSION_LARGE > 0x06010000
+ OCC_CATCH_SIGNALS;
+#endif
+ if (!GetSolver()->ComputeFunction(aFunction)) {
+ SetErrorCode("Boolean driver failed");
+ return NULL;
+ }
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return NULL;
+ }
+
+ //Make a Python command
+ GEOM::TPythonDump(aFunction) << aBool <<
+ " = geompy.MakeCommonList([" << aDescription.ToCString() << "])";
+
+ SetErrorCode(OK);
+ return aBool;
+}
+
+//=============================================================================
+/*!
+ * MakeCutList
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeCutList
+ (Handle(GEOM_Object) theMainShape,
+ const Handle(TColStd_HSequenceOfTransient)& theShapes)
+{
+ SetErrorCode(KO);
+
+ if (theShapes.IsNull()) return NULL;
+
+ //Add a new Boolean object
+ Handle(GEOM_Object) aBool = GetEngine()->AddObject(GetDocID(), GEOM_BOOLEAN);
+
+ //Add a new Boolean function
+ Handle(GEOM_Function) aFunction =
+ aBool->AddFunction(GEOMImpl_BooleanDriver::GetID(), BOOLEAN_CUT_LIST);
+
+ if (aFunction.IsNull()) return NULL;
+
+ //Check if the function is set correctly
+ if (aFunction->GetDriverGUID() != GEOMImpl_BooleanDriver::GetID()) return NULL;
+
+ GEOMImpl_IBoolean aCI (aFunction);
+ Handle(GEOM_Function) aMainRef = theMainShape->GetLastFunction();
+
+ if (aMainRef.IsNull()) return NULL;
+
+ TCollection_AsciiString aDescription;
+ Handle(TColStd_HSequenceOfTransient) aShapesSeq =
+ getShapeFunctions(theShapes, aDescription);
+
+ if (aShapesSeq.IsNull()) return NULL;
+
+ aCI.SetShape1(aMainRef);
+ aCI.SetShapes(aShapesSeq);
+
+ //Compute the Boolean value
+ try {
+#if OCC_VERSION_LARGE > 0x06010000
+ OCC_CATCH_SIGNALS;
+#endif
+ if (!GetSolver()->ComputeFunction(aFunction)) {
+ SetErrorCode("Boolean driver failed");
+ return NULL;
+ }
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return NULL;
+ }
+
+ //Make a Python command
+ GEOM::TPythonDump(aFunction) << aBool << " = geompy.MakeCutList("
+ << theMainShape << ", [" << aDescription.ToCString() << "])";
+
+ SetErrorCode(OK);
+ return aBool;
+}
+
//=============================================================================
/*!
* MakePartition
@@ -173,85 +352,47 @@ Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakePartition
GEOMImpl_IPartition aCI (aFunction);
- Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
- Handle(TColStd_HSequenceOfTransient) aToolsSeq = new TColStd_HSequenceOfTransient;
- Handle(TColStd_HSequenceOfTransient) aKeepInsSeq = new TColStd_HSequenceOfTransient;
- Handle(TColStd_HSequenceOfTransient) aRemInsSeq = new TColStd_HSequenceOfTransient;
-
- Standard_Integer ind, aLen;
- TCollection_AsciiString anEntry;
+ Handle(TColStd_HSequenceOfTransient) aShapesSeq;
+ Handle(TColStd_HSequenceOfTransient) aToolsSeq;
+ Handle(TColStd_HSequenceOfTransient) aKeepInsSeq;
+ Handle(TColStd_HSequenceOfTransient) aRemInsSeq;
TCollection_AsciiString aShapesDescr, aToolsDescr, aKeepInsDescr, aRemoveInsDescr;
// Shapes
- aLen = theShapes->Length();
- for (ind = 1; ind <= aLen; ind++) {
- Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theShapes->Value(ind));
- Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
- if (aRefSh.IsNull()) {
- SetErrorCode("NULL shape for Partition");
- return NULL;
- }
- aShapesSeq->Append(aRefSh);
+ aShapesSeq = getShapeFunctions(theShapes, aShapesDescr);
- // For Python command
- TDF_Tool::Entry(anObj->GetEntry(), anEntry);
- if (ind > 1) aShapesDescr += ", ";
- aShapesDescr += anEntry;
+ if (aShapesSeq.IsNull()) {
+ SetErrorCode("NULL shape for Partition");
+ return NULL;
}
- aCI.SetShapes(aShapesSeq);
// Tools
- aLen = theTools->Length();
- for (ind = 1; ind <= aLen; ind++) {
- Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theTools->Value(ind));
- Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
- if (aRefSh.IsNull()) {
- SetErrorCode("NULL tool shape for Partition");
- return NULL;
- }
- aToolsSeq->Append(aRefSh);
+ aToolsSeq = getShapeFunctions(theTools, aToolsDescr);
- // For Python command
- TDF_Tool::Entry(anObj->GetEntry(), anEntry);
- if (ind > 1) aToolsDescr += ", ";
- aToolsDescr += anEntry;
+ if (aToolsSeq.IsNull()) {
+ SetErrorCode("NULL tool shape for Partition");
+ return NULL;
}
- aCI.SetTools(aToolsSeq);
// Keep Inside
- aLen = theKeepIns->Length();
- for (ind = 1; ind <= aLen; ind++) {
- Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theKeepIns->Value(ind));
- Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
- if (aRefSh.IsNull()) {
- SetErrorCode("NULL shape for Partition");
- return NULL;
- }
- aKeepInsSeq->Append(aRefSh);
+ aKeepInsSeq = getShapeFunctions(theKeepIns, aKeepInsDescr);
- // For Python command
- TDF_Tool::Entry(anObj->GetEntry(), anEntry);
- if (ind > 1) aKeepInsDescr += ", ";
- aKeepInsDescr += anEntry;
+ if (aKeepInsSeq.IsNull()) {
+ SetErrorCode("NULL shape for Partition");
+ return NULL;
}
- aCI.SetKeepIns(aKeepInsSeq);
// Remove Inside
- aLen = theRemoveIns->Length();
- for (ind = 1; ind <= aLen; ind++) {
- Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(theRemoveIns->Value(ind));
- Handle(GEOM_Function) aRefSh = anObj->GetLastFunction();
- if (aRefSh.IsNull()) {
- SetErrorCode("NULL shape for Partition");
- return NULL;
- }
- aRemInsSeq->Append(aRefSh);
+ aRemInsSeq = getShapeFunctions(theRemoveIns, aRemoveInsDescr);
- // For Python command
- TDF_Tool::Entry(anObj->GetEntry(), anEntry);
- if (ind > 1) aRemoveInsDescr += ", ";
- aRemoveInsDescr += anEntry;
+ if (aRemInsSeq.IsNull()) {
+ SetErrorCode("NULL shape for Partition");
+ return NULL;
}
+
+ aCI.SetShapes(aShapesSeq);
+ aCI.SetTools(aToolsSeq);
+ aCI.SetKeepIns(aKeepInsSeq);
aCI.SetRemoveIns(aRemInsSeq);
// Limit
@@ -370,3 +511,46 @@ Handle(GEOM_Object) GEOMImpl_IBooleanOperations::MakeHalfPartition
SetErrorCode(OK);
return aPart;
}
+
+//=============================================================================
+/*!
+ * getShapeFunctions
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient)
+ GEOMImpl_IBooleanOperations::getShapeFunctions
+ (const Handle(TColStd_HSequenceOfTransient)& theObjects,
+ TCollection_AsciiString &theDescription)
+{
+ Handle(TColStd_HSequenceOfTransient) aResult =
+ new TColStd_HSequenceOfTransient;
+ Standard_Integer aNbObjects = theObjects->Length();
+ Standard_Integer i;
+ TCollection_AsciiString anEntry;
+ Handle(GEOM_Object) anObj;
+ Handle(GEOM_Function) aRefObj;
+
+ // Shapes
+ for (i = 1; i <= aNbObjects; i++) {
+ anObj = Handle(GEOM_Object)::DownCast(theObjects->Value(i));
+ aRefObj = anObj->GetLastFunction();
+
+ if (aRefObj.IsNull()) {
+ aResult.Nullify();
+ break;
+ }
+
+ aResult->Append(aRefObj);
+
+ // For Python command
+ TDF_Tool::Entry(anObj->GetEntry(), anEntry);
+
+ if (i > 1) {
+ theDescription += ", ";
+ }
+
+ theDescription += anEntry;
+ }
+
+ return aResult;
+}
diff --git a/src/GEOMImpl/GEOMImpl_IBooleanOperations.hxx b/src/GEOMImpl/GEOMImpl_IBooleanOperations.hxx
index ff93dcc89..c1c492c47 100644
--- a/src/GEOMImpl/GEOMImpl_IBooleanOperations.hxx
+++ b/src/GEOMImpl/GEOMImpl_IBooleanOperations.hxx
@@ -40,6 +40,16 @@ class GEOMImpl_IBooleanOperations : public GEOM_IOperations {
Handle(GEOM_Object) theShape2,
Standard_Integer theOp);
+ Standard_EXPORT Handle(GEOM_Object) MakeFuseList
+ (const Handle(TColStd_HSequenceOfTransient)& theShapes);
+
+ Standard_EXPORT Handle(GEOM_Object) MakeCommonList
+ (const Handle(TColStd_HSequenceOfTransient)& theShapes);
+
+ Standard_EXPORT Handle(GEOM_Object) MakeCutList
+ (Handle(GEOM_Object) theMainShape,
+ const Handle(TColStd_HSequenceOfTransient)& theShapes);
+
Standard_EXPORT Handle(GEOM_Object) MakePartition
(const Handle(TColStd_HSequenceOfTransient)& theShapes,
const Handle(TColStd_HSequenceOfTransient)& theTools,
@@ -53,6 +63,13 @@ class GEOMImpl_IBooleanOperations : public GEOM_IOperations {
Standard_EXPORT Handle(GEOM_Object) MakeHalfPartition (Handle(GEOM_Object) theShape,
Handle(GEOM_Object) thePlane);
+
+private:
+
+ Handle(TColStd_HSequenceOfTransient) getShapeFunctions
+ (const Handle(TColStd_HSequenceOfTransient)& theObjects,
+ TCollection_AsciiString &theDescription);
+
};
#endif
diff --git a/src/GEOMImpl/GEOMImpl_Types.hxx b/src/GEOMImpl/GEOMImpl_Types.hxx
index 8f85c2ac4..b00671937 100755
--- a/src/GEOMImpl/GEOMImpl_Types.hxx
+++ b/src/GEOMImpl/GEOMImpl_Types.hxx
@@ -229,10 +229,13 @@
#define THRUSECTIONS_RULED 1
#define THRUSECTIONS_SMOOTHED 2
-#define BOOLEAN_COMMON 1
-#define BOOLEAN_CUT 2
-#define BOOLEAN_FUSE 3
-#define BOOLEAN_SECTION 4
+#define BOOLEAN_COMMON 1
+#define BOOLEAN_CUT 2
+#define BOOLEAN_FUSE 3
+#define BOOLEAN_SECTION 4
+#define BOOLEAN_COMMON_LIST 5
+#define BOOLEAN_CUT_LIST 6
+#define BOOLEAN_FUSE_LIST 7
#define PARTITION_PARTITION 1
#define PARTITION_HALF 2
diff --git a/src/GEOM_I/GEOM_IBooleanOperations_i.cc b/src/GEOM_I/GEOM_IBooleanOperations_i.cc
index 6afade797..2cad84b5d 100644
--- a/src/GEOM_I/GEOM_IBooleanOperations_i.cc
+++ b/src/GEOM_I/GEOM_IBooleanOperations_i.cc
@@ -85,6 +85,100 @@ GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakeBoolean
return GetObject(anObject);
}
+//=============================================================================
+/*!
+ * MakeFuseList
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakeFuseList
+ (const GEOM::ListOfGO& theShapes)
+{
+ GEOM::GEOM_Object_var aGEOMObject;
+
+ //Set a not done flag
+ GetOperations()->SetNotDone();
+
+ Handle(TColStd_HSequenceOfTransient) aShapes =
+ GetListOfObjectsImpl(theShapes);
+
+ if (aShapes.IsNull()) {
+ return aGEOMObject._retn();
+ }
+
+ // Make fusion
+ Handle(GEOM_Object) anObject = GetOperations()->MakeFuseList(aShapes);
+
+ if (!GetOperations()->IsDone() || anObject.IsNull())
+ return aGEOMObject._retn();
+
+ return GetObject(anObject);
+}
+
+//=============================================================================
+/*!
+ * MakeCommonList
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakeCommonList
+ (const GEOM::ListOfGO& theShapes)
+{
+ GEOM::GEOM_Object_var aGEOMObject;
+
+ //Set a not done flag
+ GetOperations()->SetNotDone();
+
+ Handle(TColStd_HSequenceOfTransient) aShapes =
+ GetListOfObjectsImpl(theShapes);
+
+ if (aShapes.IsNull()) {
+ return aGEOMObject._retn();
+ }
+
+ // Make fusion
+ Handle(GEOM_Object) anObject = GetOperations()->MakeCommonList(aShapes);
+
+ if (!GetOperations()->IsDone() || anObject.IsNull())
+ return aGEOMObject._retn();
+
+ return GetObject(anObject);
+}
+
+//=============================================================================
+/*!
+ * MakeCutList
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakeCutList
+ (GEOM::GEOM_Object_ptr theMainShape,
+ const GEOM::ListOfGO& theShapes)
+{
+ GEOM::GEOM_Object_var aGEOMObject;
+
+ //Set a not done flag
+ GetOperations()->SetNotDone();
+
+ Handle(GEOM_Object) aMainShape = GetObjectImpl(theMainShape);
+
+ if (aMainShape.IsNull()) {
+ return aGEOMObject._retn();
+ }
+
+ Handle(TColStd_HSequenceOfTransient) aShapes =
+ GetListOfObjectsImpl(theShapes);
+
+ if (aShapes.IsNull()) {
+ return aGEOMObject._retn();
+ }
+
+ // Make fusion
+ Handle(GEOM_Object) anObject = GetOperations()->MakeCutList(aMainShape, aShapes);
+
+ if (!GetOperations()->IsDone() || anObject.IsNull())
+ return aGEOMObject._retn();
+
+ return GetObject(anObject);
+}
+
//=============================================================================
/*!
* MakePartition
@@ -105,47 +199,20 @@ GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakePartition
//Set a not done flag
GetOperations()->SetNotDone();
- int ind, aLen;
- Handle(TColStd_HSequenceOfTransient) aShapes = new TColStd_HSequenceOfTransient;
- Handle(TColStd_HSequenceOfTransient) aTools = new TColStd_HSequenceOfTransient;
- Handle(TColStd_HSequenceOfTransient) aKeepIns = new TColStd_HSequenceOfTransient;
- Handle(TColStd_HSequenceOfTransient) aRemIns = new TColStd_HSequenceOfTransient;
+ Handle(TColStd_HSequenceOfTransient) aShapes = GetListOfObjectsImpl(theShapes);
+ Handle(TColStd_HSequenceOfTransient) aTools = GetListOfObjectsImpl(theTools);
+ Handle(TColStd_HSequenceOfTransient) aKeepIns = GetListOfObjectsImpl(theKeepIns);
+ Handle(TColStd_HSequenceOfTransient) aRemIns = GetListOfObjectsImpl(theRemoveIns);
Handle(TColStd_HArray1OfInteger) aMaterials;
- //Get the shapes
- aLen = theShapes.length();
- for (ind = 0; ind < aLen; ind++) {
- Handle(GEOM_Object) aSh = GetObjectImpl(theShapes[ind]);
- if (aSh.IsNull()) return aGEOMObject._retn();
- aShapes->Append(aSh);
- }
-
- //Get the tools
- aLen = theTools.length();
- for (ind = 0; ind < aLen; ind++) {
- Handle(GEOM_Object) aSh = GetObjectImpl(theTools[ind]);
- if (aSh.IsNull()) return aGEOMObject._retn();
- aTools->Append(aSh);
- }
-
- //Get the keep inside shapes
- aLen = theKeepIns.length();
- for (ind = 0; ind < aLen; ind++) {
- Handle(GEOM_Object) aSh = GetObjectImpl(theKeepIns[ind]);
- if (aSh.IsNull()) return aGEOMObject._retn();
- aKeepIns->Append(aSh);
- }
-
- //Get the remove inside shapes
- aLen = theRemoveIns.length();
- for (ind = 0; ind < aLen; ind++) {
- Handle(GEOM_Object) aSh = GetObjectImpl(theRemoveIns[ind]);
- if (aSh.IsNull()) return aGEOMObject._retn();
- aRemIns->Append(aSh);
+ if (aShapes.IsNull() || aTools.IsNull() ||
+ aKeepIns.IsNull() || aRemIns.IsNull()) {
+ return aGEOMObject._retn();
}
//Get the materials
- aLen = theMaterials.length();
+ int ind;
+ int aLen = theMaterials.length();
if ( aLen ) {
aMaterials = new TColStd_HArray1OfInteger (1, aLen);
for (ind = 0; ind < aLen; ind++) {
@@ -185,47 +252,20 @@ GEOM::GEOM_Object_ptr GEOM_IBooleanOperations_i::MakePartitionNonSelfIntersected
//Set a not done flag
GetOperations()->SetNotDone();
- int ind, aLen;
- Handle(TColStd_HSequenceOfTransient) aShapes = new TColStd_HSequenceOfTransient;
- Handle(TColStd_HSequenceOfTransient) aTools = new TColStd_HSequenceOfTransient;
- Handle(TColStd_HSequenceOfTransient) aKeepIns = new TColStd_HSequenceOfTransient;
- Handle(TColStd_HSequenceOfTransient) aRemIns = new TColStd_HSequenceOfTransient;
+ Handle(TColStd_HSequenceOfTransient) aShapes = GetListOfObjectsImpl(theShapes);
+ Handle(TColStd_HSequenceOfTransient) aTools = GetListOfObjectsImpl(theTools);
+ Handle(TColStd_HSequenceOfTransient) aKeepIns = GetListOfObjectsImpl(theKeepIns);
+ Handle(TColStd_HSequenceOfTransient) aRemIns = GetListOfObjectsImpl(theRemoveIns);
Handle(TColStd_HArray1OfInteger) aMaterials;
- //Get the shapes
- aLen = theShapes.length();
- for (ind = 0; ind < aLen; ind++) {
- Handle(GEOM_Object) aSh = GetObjectImpl(theShapes[ind]);
- if (aSh.IsNull()) return aGEOMObject._retn();
- aShapes->Append(aSh);
- }
-
- //Get the tools
- aLen = theTools.length();
- for (ind = 0; ind < aLen; ind++) {
- Handle(GEOM_Object) aSh = GetObjectImpl(theTools[ind]);
- if (aSh.IsNull()) return aGEOMObject._retn();
- aTools->Append(aSh);
- }
-
- //Get the keep inside shapes
- aLen = theKeepIns.length();
- for (ind = 0; ind < aLen; ind++) {
- Handle(GEOM_Object) aSh = GetObjectImpl(theKeepIns[ind]);
- if (aSh.IsNull()) return aGEOMObject._retn();
- aKeepIns->Append(aSh);
- }
-
- //Get the remove inside shapes
- aLen = theRemoveIns.length();
- for (ind = 0; ind < aLen; ind++) {
- Handle(GEOM_Object) aSh = GetObjectImpl(theRemoveIns[ind]);
- if (aSh.IsNull()) return aGEOMObject._retn();
- aRemIns->Append(aSh);
+ if (aShapes.IsNull() || aTools.IsNull() ||
+ aKeepIns.IsNull() || aRemIns.IsNull()) {
+ return aGEOMObject._retn();
}
//Get the materials
- aLen = theMaterials.length();
+ int ind;
+ int aLen = theMaterials.length();
if ( aLen ) {
aMaterials = new TColStd_HArray1OfInteger (1, aLen);
for (ind = 0; ind < aLen; ind++) {
diff --git a/src/GEOM_I/GEOM_IBooleanOperations_i.hh b/src/GEOM_I/GEOM_IBooleanOperations_i.hh
index 81885d879..3150fcd56 100644
--- a/src/GEOM_I/GEOM_IBooleanOperations_i.hh
+++ b/src/GEOM_I/GEOM_IBooleanOperations_i.hh
@@ -46,6 +46,13 @@ class GEOM_I_EXPORT GEOM_IBooleanOperations_i :
GEOM::GEOM_Object_ptr theShape2,
CORBA::Long theOp);
+ GEOM::GEOM_Object_ptr MakeFuseList (const GEOM::ListOfGO& theShapes);
+
+ GEOM::GEOM_Object_ptr MakeCommonList (const GEOM::ListOfGO& theShapes);
+
+ GEOM::GEOM_Object_ptr MakeCutList (GEOM::GEOM_Object_ptr theMainShape,
+ const GEOM::ListOfGO& theShapes);
+
GEOM::GEOM_Object_ptr MakePartition (const GEOM::ListOfGO& theShapes,
const GEOM::ListOfGO& theTools,
const GEOM::ListOfGO& theKeepInside,
diff --git a/src/GEOM_I/GEOM_IOperations_i.cc b/src/GEOM_I/GEOM_IOperations_i.cc
index 090bf8e82..059e751ae 100644
--- a/src/GEOM_I/GEOM_IOperations_i.cc
+++ b/src/GEOM_I/GEOM_IOperations_i.cc
@@ -160,6 +160,34 @@ Handle(GEOM_Object) GEOM_IOperations_i::GetObjectImpl(GEOM::GEOM_Object_ptr theO
return anImpl;
}
+//=============================================================================
+/*!
+ * GetListOfObjectsImpl
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOM_IOperations_i::GetListOfObjectsImpl
+ (const GEOM::ListOfGO& theObjects)
+{
+ Handle(TColStd_HSequenceOfTransient) aResult =
+ new TColStd_HSequenceOfTransient;
+
+ int i;
+ int aNbObj = theObjects.length();
+
+ for (i = 0; i < aNbObj; i++) {
+ Handle(GEOM_Object) anObj = GetObjectImpl(theObjects[i]);
+
+ if (anObj.IsNull()) {
+ aResult.Nullify();
+ break;
+ }
+
+ aResult->Append(anObj);
+ }
+
+ return aResult;
+}
+
//=============================================================================
/*!
* UpdateGUIForObject
diff --git a/src/GEOM_I/GEOM_IOperations_i.hh b/src/GEOM_I/GEOM_IOperations_i.hh
index 8fa579842..4d8757cd8 100644
--- a/src/GEOM_I/GEOM_IOperations_i.hh
+++ b/src/GEOM_I/GEOM_IOperations_i.hh
@@ -50,6 +50,9 @@ class GEOM_I_EXPORT GEOM_IOperations_i : public virtual POA_GEOM::GEOM_IOperatio
virtual GEOM::GEOM_Object_ptr GetObject(Handle(GEOM_Object) theObject);
virtual Handle(GEOM_Object) GetObjectImpl(GEOM::GEOM_Object_ptr theObject);
+ virtual Handle(TColStd_HSequenceOfTransient)
+ GetListOfObjectsImpl(const GEOM::ListOfGO& theObjects);
+
virtual void StartOperation();
virtual void FinishOperation();
diff --git a/src/GEOM_SWIG/GEOM_TestOthers.py b/src/GEOM_SWIG/GEOM_TestOthers.py
index 8fa5964b5..0a8ab0413 100644
--- a/src/GEOM_SWIG/GEOM_TestOthers.py
+++ b/src/GEOM_SWIG/GEOM_TestOthers.py
@@ -163,17 +163,29 @@ def TestOtherOperations (geompy, math):
id_Orientation = geompy.addToStudy(Orientation, "OrientationChange")
# MakeCommon, MakeCut, MakeFuse, MakeSection
+ p1 = geompy.MakeVertex(60, 120, 0)
+ p2 = geompy.MakeVertex( 0, 0, 0)
+ v = geompy.MakeVector(p1, p2)
+ height = 90
+ radius1 = 50
+ cylinder = geompy.MakeCylinder(p1, v, radius1, height)
Sphere = geompy.MakeSphereR(100)
- Common = geompy.MakeCommon (Box, Sphere)
- Cut = geompy.MakeCut (Box, Sphere)
- Fuse = geompy.MakeFuse (Box, Sphere)
- Section = geompy.MakeSection(Box, Sphere)
+ Common1 = geompy.MakeCommon (Box, Sphere)
+ Cut1 = geompy.MakeCut (Box, Sphere)
+ Fuse1 = geompy.MakeFuse (Box, Sphere)
+ Section = geompy.MakeSection (Box, Sphere)
+ Common2 = geompy.MakeCommonList([Box, Sphere, cylinder])
+ Cut2 = geompy.MakeCutList (Box, [Sphere, cylinder])
+ Fuse2 = geompy.MakeFuseList ([Box, Sphere, cylinder])
- id_Common = geompy.addToStudy(Common, "Common")
- id_Cut = geompy.addToStudy(Cut, "Cut")
- id_Fuse = geompy.addToStudy(Fuse, "Fuse")
+ id_Common1 = geompy.addToStudy(Common1, "Common_1")
+ id_Cut1 = geompy.addToStudy(Cut1, "Cut_1")
+ id_Fuse1 = geompy.addToStudy(Fuse1, "Fuse_1")
id_Section = geompy.addToStudy(Section, "Section")
+ id_Common2 = geompy.addToStudy(Common2, "Common_2")
+ id_Cut2 = geompy.addToStudy(Cut2, "Cut_2")
+ id_Fuse2 = geompy.addToStudy(Fuse2, "Fuse_2")
# Partition
p100 = geompy.MakeVertex(100, 100, 100)
@@ -713,10 +725,9 @@ def TestOtherOperations (geompy, math):
sph2 = geompy.MakeSphere(50, 50, -50, 40)
pcyl = geompy.MakeVertex(50, 50, -50)
cyli = geompy.MakeCylinder(pcyl, vz, 40, 100)
- fuse = geompy.MakeFuse(sph1, cyli)
- sh_1 = geompy.MakeFuse(fuse, sph2)
+ sh_1 = geompy.MakeFuseList([sph1, cyli, sph2])
# As after Fuse we have a compound, we need to obtain a solid from it
- #shsh = geompy.SubShapeAll(fuse, geompy.ShapeType["SOLID"])
+ #shsh = geompy.SubShapeAll(sh_1, geompy.ShapeType["SOLID"])
#sh_1 = shsh[0]
geompy.addToStudy(sh_1, "sh_1")
diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py
index 6b9058dbd..28dab6b5e 100644
--- a/src/GEOM_SWIG/geomBuilder.py
+++ b/src/GEOM_SWIG/geomBuilder.py
@@ -6637,6 +6637,98 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
# note: auto-publishing is done in self.MakeBoolean()
return self.MakeBoolean(theShape1, theShape2, 4, theName)
+ ## Perform Fuse boolean operation on the list of shapes.
+ # @param theShapesList Shapes to be fused.
+ # @param theName Object name; when specified, this parameter is used
+ # for result publication in the study. Otherwise, if automatic
+ # publication is switched on, default value is used for result name.
+ #
+ # @return New GEOM.GEOM_Object, containing the result shape.
+ #
+ # @ref tui_fuse "Example 1"
+ # \n @ref swig_MakeCommon "Example 2"
+ def MakeFuseList(self, theShapesList, theName=None):
+ """
+ Perform Fuse boolean operation on the list of shapes.
+
+ Parameters:
+ theShapesList Shapes to be fused.
+ theName Object name; when specified, this parameter is used
+ for result publication in the study. Otherwise, if automatic
+ publication is switched on, default value is used for result name.
+
+ Returns:
+ New GEOM.GEOM_Object, containing the result shape.
+
+ """
+ # Example: see GEOM_TestOthers.py
+ anObj = self.BoolOp.MakeFuseList(theShapesList)
+ RaiseIfFailed("MakeFuseList", self.BoolOp)
+ self._autoPublish(anObj, theName, "fuse")
+ return anObj
+
+ ## Perform Common boolean operation on the list of shapes.
+ # @param theShapesList Shapes for Common operation.
+ # @param theName Object name; when specified, this parameter is used
+ # for result publication in the study. Otherwise, if automatic
+ # publication is switched on, default value is used for result name.
+ #
+ # @return New GEOM.GEOM_Object, containing the result shape.
+ #
+ # @ref tui_common "Example 1"
+ # \n @ref swig_MakeCommon "Example 2"
+ def MakeCommonList(self, theShapesList, theName=None):
+ """
+ Perform Common boolean operation on the list of shapes.
+
+ Parameters:
+ theShapesList Shapes for Common operation.
+ theName Object name; when specified, this parameter is used
+ for result publication in the study. Otherwise, if automatic
+ publication is switched on, default value is used for result name.
+
+ Returns:
+ New GEOM.GEOM_Object, containing the result shape.
+
+ """
+ # Example: see GEOM_TestOthers.py
+ anObj = self.BoolOp.MakeCommonList(theShapesList)
+ RaiseIfFailed("MakeCommonList", self.BoolOp)
+ self._autoPublish(anObj, theName, "common")
+ return anObj
+
+ ## Perform Cut boolean operation on one object and the list of tools.
+ # @param theMainShape The object of the operation.
+ # @param theShapesList The list of tools of the operation.
+ # @param theName Object name; when specified, this parameter is used
+ # for result publication in the study. Otherwise, if automatic
+ # publication is switched on, default value is used for result name.
+ #
+ # @return New GEOM.GEOM_Object, containing the result shape.
+ #
+ # @ref tui_cut "Example 1"
+ # \n @ref swig_MakeCommon "Example 2"
+ def MakeCutList(self, theMainShape, theShapesList, theName=None):
+ """
+ Perform Cut boolean operation on one object and the list of tools.
+
+ Parameters:
+ theMainShape The object of the operation.
+ theShapesList The list of tools of the operation.
+ theName Object name; when specified, this parameter is used
+ for result publication in the study. Otherwise, if automatic
+ publication is switched on, default value is used for result name.
+
+ Returns:
+ New GEOM.GEOM_Object, containing the result shape.
+
+ """
+ # Example: see GEOM_TestOthers.py
+ anObj = self.BoolOp.MakeCutList(theMainShape, theShapesList)
+ RaiseIfFailed("MakeCutList", self.BoolOp)
+ self._autoPublish(anObj, theName, "cut")
+ return anObj
+
# end of l3_boolean
## @}