# built documents.
#
# The short X.Y version.
-version = u'3.0.0'
+version = u'9.2.0'
# The full version, including alpha/beta/rc tags.
-release = u'3.0.0'
+release = u'9.2.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
{
data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
}
-
-//=================================================================================================
-void BuildPlugin_CompSolid::execute()
-{
- // all the needed checkings are in validator, so, here just make and store result
- ListOfShape anOriginalShapes;
- AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
- for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
- AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
- GeomShapePtr aShape = aSelection->value();
- if (!aShape.get())
- aShape = aSelection->context()->shape();
- anOriginalShapes.push_back(aShape);
- }
- std::shared_ptr<GeomAlgoAPI_MakeVolume> anAlgo(
- new GeomAlgoAPI_MakeVolume(anOriginalShapes, false));
- GeomShapePtr aVolumeRes = anAlgo->shape();
-
- // check and process result of volume maker
- GeomShapePtr aResShape = getSingleSubshape(aVolumeRes);
- storeResult(anOriginalShapes, aResShape, anAlgo);
-}
/// Request for initialization of data model of the feature: adding all attributes.
BUILDPLUGIN_EXPORT virtual void initAttributes();
-
- /// Creates a new part document if needed.
- BUILDPLUGIN_EXPORT virtual void execute();
};
#endif
int anIndexToRemove = 0;
if (aCopyCompound) {
ResultBodyPtr aResultBody = document()->createBody(data(), anIndexToRemove++);
- aResultBody->store(aCopyCompound);
+ aResultBody->storeModified(anOriginalShapes, aCopyCompound, aCopyAlgo);
aResultBody->loadModifiedShapes(aCopyAlgo, aCompound, GeomAPI_Shape::VERTEX);
aResultBody->loadModifiedShapes(aCopyAlgo, aCompound, GeomAPI_Shape::EDGE);
aResultBody->loadModifiedShapes(aCopyAlgo, aCompound, GeomAPI_Shape::FACE);
// Store result.
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
- aResultBody->storeModified(aShape, aCopyAlgo->shape());
+
+ ListOfShape aBaseShapes;
+ aBaseShapes.push_back(aShape);
+ aResultBody->storeModified(aBaseShapes, aCopyAlgo->shape(), aCopyAlgo);
aResultBody->loadModifiedShapes(aCopyAlgo, aShape, GeomAPI_Shape::VERTEX);
setResult(aResultBody, aResultIndex);
#include <GeomAPI_Pln.h>
#include <GeomAPI_ShapeExplorer.h>
+#include <GeomAlgoAPI_MakeShapeList.h>
#include <GeomAlgoAPI_ShapeTools.h>
#include <GeomAlgoAPI_SketchBuilder.h>
#include <GeomAlgoAPI_Copy.h>
// Collect base shapes.
ListOfShape anEdges;
ListOfShape anOriginalFaces;
+ ListOfShape aContexts;
+ getOriginalShapesAndContexts(BASE_OBJECTS_ID(), anOriginalFaces, aContexts);
+ anOriginalFaces.clear();
std::list< std::shared_ptr<GeomAPI_Dir> > aListOfNormals;
for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
// Build faces by edges.
ListOfShape aFaces;
+ GeomMakeShapePtr aFaceBuilder;
if (!anEdges.empty())
- buildFacesByEdges(anEdges, aListOfNormals, aFaces);
+ buildFacesByEdges(anEdges, aListOfNormals, aFaces, aFaceBuilder);
+ int aNbFacesFromEdges = (int)aFaces.size();
// Add faces selected by user.
aFaces.insert(aFaces.end(), anOriginalFaces.begin(), anOriginalFaces.end());
// Store result.
int anIndex = 0;
for(ListOfShape::const_iterator anIt = aFaces.cbegin(); anIt != aFaces.cend(); ++anIt) {
- ResultBodyPtr aResultBody = document()->createBody(data(), anIndex);
- GeomShapePtr aShape = *anIt;
- GeomAlgoAPI_Copy aCopy(aShape);
- aShape = aCopy.shape();
- aResultBody->store(aShape);
-
- // Store edges.
- int anEdgeIndex = 1;
- for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
- GeomShapePtr anEdge = anExp.current();
- aResultBody->generated(anEdge, "Edge_" + std::to_string((long long)anEdgeIndex));
- ++anEdgeIndex;
- }
+ std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList);
+ if (anIndex < aNbFacesFromEdges)
+ aMakeShapeList->appendAlgo(aFaceBuilder);
- setResult(aResultBody, anIndex);
- ++anIndex;
+ GeomShapePtr aShape = *anIt;
+ GeomMakeShapePtr aCopy(new GeomAlgoAPI_Copy(aShape));
+ aMakeShapeList->appendAlgo(aCopy);
+
+ ListOfShape aBaseShapes;
+ if (anIndex < aNbFacesFromEdges)
+ aBaseShapes = anEdges;
+ else
+ aBaseShapes.push_back(aShape);
+ storeResult(aMakeShapeList, aBaseShapes, aContexts, aCopy->shape(), anIndex++);
}
removeResults(anIndex);
void BuildPlugin_Face::buildFacesByEdges(
const ListOfShape& theEdges,
const std::list< std::shared_ptr<GeomAPI_Dir> >& theNormals,
- ListOfShape& theFaces) const
+ ListOfShape& theFaces,
+ std::shared_ptr<GeomAlgoAPI_MakeShape>& theBuilderAlgo) const
{
// Get plane.
std::shared_ptr<GeomAPI_Pln> aPln = GeomAlgoAPI_ShapeTools::findPlane(theEdges);
}
// Get faces.
- GeomAlgoAPI_SketchBuilder::createFaces(aPln->location(), aPln->xDirection(),
- aPln->direction(), theEdges, theFaces);
+ std::shared_ptr<GeomAlgoAPI_SketchBuilder> aSketchBuilder(
+ new GeomAlgoAPI_SketchBuilder(aPln, theEdges));
+ theFaces = aSketchBuilder->faces();
+ theBuilderAlgo = aSketchBuilder;
// Get wires from faces.
ListOfShape aWires;
#define BuildPlugin_Face_H_
#include "BuildPlugin.h"
-
-#include <ModelAPI_Feature.h>
+#include "BuildPlugin_Shape.h"
class GeomAPI_Dir;
class GeomAPI_Shape;
+class GeomAlgoAPI_MakeShape;
/// \class BuildPlugin_Face
/// \ingroup Plugins
/// \brief Feature for creation of face from sketch edges or existing wires.
-class BuildPlugin_Face: public ModelAPI_Feature
+class BuildPlugin_Face: public BuildPlugin_Shape
{
public:
/// Use plugin manager for features creation
/// Create faces basing on the list of edges
void buildFacesByEdges(const std::list< std::shared_ptr<GeomAPI_Shape> >& theEdges,
const std::list< std::shared_ptr<GeomAPI_Dir> >& theNormals,
- std::list< std::shared_ptr<GeomAPI_Shape> >& theFaces) const;
+ std::list< std::shared_ptr<GeomAPI_Shape> >& theFaces,
+ std::shared_ptr<GeomAlgoAPI_MakeShape>& theBuilderAlgo) const;
};
#endif
--- /dev/null
+// Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#include "BuildPlugin_Shape.h"
+
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_ResultBody.h>
+
+#include <GeomAlgoAPI_MakeShape.h>
+
+#include <GeomAPI_PlanarEdges.h>
+
+
+//=================================================================================================
+void BuildPlugin_Shape::storeResult(const GeomMakeShapePtr& theAlgorithm,
+ const ListOfShape& theOriginalShapes,
+ const ListOfShape& theOriginalSolids,
+ const GeomShapePtr& theResultShape,
+ const int theResultIndex)
+{
+ ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
+ aResultBody->storeModified(theOriginalSolids, theResultShape, theAlgorithm);
+
+ for (ListOfShape::const_iterator anIt = theOriginalShapes.cbegin();
+ anIt != theOriginalShapes.cend();
+ ++anIt)
+ {
+ GeomShapePtr aShape = *anIt;
+ aResultBody->loadModifiedShapes(theAlgorithm, aShape, GeomAPI_Shape::VERTEX);
+ aResultBody->loadModifiedShapes(theAlgorithm, aShape, GeomAPI_Shape::EDGE);
+ aResultBody->loadModifiedShapes(theAlgorithm, aShape, GeomAPI_Shape::FACE);
+ }
+ setResult(aResultBody, theResultIndex);
+}
+
+//=================================================================================================
+void BuildPlugin_Shape::getOriginalShapesAndContexts(const std::string& theSelectionListID,
+ ListOfShape& theShapes,
+ ListOfShape& theContexts)
+{
+ std::set<GeomShapePtr, GeomAPI_Shape::Comparator> aContexts;
+
+ AttributeSelectionListPtr aSelectionList = selectionList(theSelectionListID);
+ for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
+ AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
+ GeomShapePtr aShape = aSelection->value();
+ GeomShapePtr aContext = aSelection->context()->shape();
+ if (!aShape.get())
+ aShape = aContext;
+ theShapes.push_back(aShape);
+
+ // do not collect sketch faces, because they are stored as compounds
+ // and then are treated as modified by the algorithm
+ if (!std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aContext).get())
+ aContexts.insert(aContext);
+ }
+
+ std::set<GeomShapePtr, GeomAPI_Shape::Comparator>::const_iterator anIt = aContexts.begin();
+ for (; anIt != aContexts.end(); ++anIt)
+ theContexts.push_back(*anIt);
+}
--- /dev/null
+// Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef BuildPlugin_Shape_H_
+#define BuildPlugin_Shape_H_
+
+#include "BuildPlugin.h"
+
+#include <GeomAPI_Shape.h>
+
+#include <ModelAPI_Feature.h>
+
+class GeomAlgoAPI_MakeShape;
+
+/// \class BuildPlugin_Shape
+/// \ingroup Plugins
+/// \brief Base class containing common methods for shape creating operations.
+class BuildPlugin_Shape: public ModelAPI_Feature
+{
+protected:
+ /// Obtain list of selected shapes and their contexts
+ void getOriginalShapesAndContexts(const std::string& theSelectionListID,
+ ListOfShape& theShapes,
+ ListOfShape& theContexts);
+
+ /// Store result of algorithm
+ void storeResult(const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgorithm,
+ const ListOfShape& theOriginalShapes,
+ const ListOfShape& theOriginalContexts,
+ const GeomShapePtr& theResultShape,
+ const int theResultIndex = 0);
+};
+
+#endif
AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
// Collect base shapes.
- ListOfShape aShapes;
- for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
- AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
- GeomShapePtr aShape = aSelection->value();
- if(!aShape.get()) {
- aShape = aSelection->context()->shape();
- }
- aShapes.push_back(aShape);
- }
+ ListOfShape aShapes, aContexts;
+ getOriginalShapesAndContexts(BASE_OBJECTS_ID(), aShapes, aContexts);
// Sew faces.
GeomMakeShapePtr aSewingAlgo(new GeomAlgoAPI_Sewing(aShapes));
int anIndex = 0;
for(GeomAPI_ShapeExplorer anExp(aResult, GeomAPI_Shape::SHELL); anExp.more(); anExp.next()) {
GeomShapePtr aShell = anExp.current();
- ResultBodyPtr aResultBody = document()->createBody(data(), anIndex);
- aResultBody->store(aShell);
- for(ListOfShape::const_iterator anIt = aShapes.cbegin(); anIt != aShapes.cend(); ++anIt) {
- for (GeomAPI_ShapeExplorer aFaceExp(*anIt, GeomAPI_Shape::FACE);
- aFaceExp.more();
- aFaceExp.next())
- {
- GeomShapePtr aFace = aFaceExp.current();
- ListOfShape aHistory;
- aSewingAlgo->modified(aFace, aHistory);
- for (ListOfShape::const_iterator aHistoryIt = aHistory.cbegin();
- aHistoryIt != aHistory.cend();
- ++aHistoryIt)
- {
- GeomShapePtr aHistoryShape = *aHistoryIt;
- if (aShell->isSubShape(aHistoryShape, false)) {
- aResultBody->loadModifiedShapes(aSewingAlgo,
- aFace,
- GeomAPI_Shape::EDGE);
- aResultBody->loadModifiedShapes(aSewingAlgo,
- aFace,
- GeomAPI_Shape::FACE);
- break;
- }
- }
- }
- }
- setResult(aResultBody, anIndex);
- ++anIndex;
+ storeResult(aSewingAlgo, aShapes, aContexts, aShell, anIndex++);
}
removeResults(anIndex);
#define BuildPlugin_Shell_H_
#include "BuildPlugin.h"
-
-#include <ModelAPI_Feature.h>
+#include "BuildPlugin_Shape.h"
/// \class BuildPlugin_Shell
/// \ingroup Plugins
/// \brief Feature for creation of shell from faces and shells.
-class BuildPlugin_Shell: public ModelAPI_Feature
+class BuildPlugin_Shell: public BuildPlugin_Shape
{
public:
/// Use plugin manager for features creation
#include <ModelAPI_AttributeSelectionList.h>
#include <ModelAPI_ResultBody.h>
+#include <GeomAPI_ShapeExplorer.h>
#include <GeomAPI_ShapeIterator.h>
#include <GeomAlgoAPI_MakeVolume.h>
void BuildPlugin_Solid::execute()
{
// all the needed checkings are in validator, so, here just make and store result
- ListOfShape anOriginalShapes;
- AttributeSelectionListPtr aSelectionList = selectionList(BASE_OBJECTS_ID());
- for (int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
- AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
- GeomShapePtr aShape = aSelection->value();
- if (!aShape.get())
- aShape = aSelection->context()->shape();
- anOriginalShapes.push_back(aShape);
- }
+ ListOfShape anOriginalFaces;
+ ListOfShape anOriginalSolids;
+ getOriginalShapesAndContexts(BASE_OBJECTS_ID(), anOriginalFaces, anOriginalSolids);
+
std::shared_ptr<GeomAlgoAPI_MakeVolume> anAlgo(
- new GeomAlgoAPI_MakeVolume(anOriginalShapes, false));
+ new GeomAlgoAPI_MakeVolume(anOriginalFaces, false));
// check and process result of volume maker
GeomShapePtr aResShape = getSingleSubshape(anAlgo->shape());
- storeResult(anOriginalShapes, aResShape, anAlgo);
-}
-
-void BuildPlugin_Solid::storeResult(const ListOfShape& theOriginalShapes,
- const GeomShapePtr& theResultShape,
- const GeomMakeShapePtr& theAlgorithm)
-{
- ResultBodyPtr aResultBody = document()->createBody(data());
- aResultBody->store(theResultShape);
-
- // Store faces
- for (ListOfShape::const_iterator anIt = theOriginalShapes.cbegin();
- anIt != theOriginalShapes.cend();
- ++anIt)
- {
- GeomShapePtr aShape = *anIt;
- aResultBody->loadModifiedShapes(theAlgorithm, aShape, GeomAPI_Shape::FACE);
- }
- setResult(aResultBody);
+ storeResult(anAlgo, anOriginalFaces, anOriginalSolids, aResShape);
}
GeomShapePtr BuildPlugin_Solid::getSingleSubshape(const GeomShapePtr& theCompound)
#define BuildPlugin_Solid_H_
#include "BuildPlugin.h"
-
-#include <GeomAPI_Shape.h>
-#include <ModelAPI_Feature.h>
-
-class GeomAlgoAPI_MakeShape;
+#include "BuildPlugin_Shape.h"
/// \class BuildPlugin_Solid
/// \ingroup Plugins
/// \brief Feature for creation of solid from faces or shells.
-class BuildPlugin_Solid: public ModelAPI_Feature
+class BuildPlugin_Solid: public BuildPlugin_Shape
{
public:
/// Use plugin manager for features creation
BUILDPLUGIN_EXPORT virtual void execute();
protected:
- /// Store result of algorithm
- void storeResult(const ListOfShape& theOriginalShapes,
- const GeomShapePtr& theResultShape,
- const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgorithm);
-
/// Explode compound to get single shape
GeomShapePtr getSingleSubshape(const GeomShapePtr& theCompound);
};
}
// Check that selected objects have closed contours.
- ListOfShape aFaces;
- GeomAlgoAPI_SketchBuilder::createFaces(aPln->location(), aPln->xDirection(),
- aPln->direction(), anEdges, aFaces);
+ GeomAlgoAPI_SketchBuilder aBuilder(aPln, anEdges);
+ const ListOfShape& aFaces = aBuilder.faces();
if(aFaces.empty()) {
theError = "Selected objects do not generate closed contour.";
return false;
SET(PROJECT_HEADERS
BuildPlugin.h
BuildPlugin_Plugin.h
+ BuildPlugin_Shape.h
BuildPlugin_Vertex.h
BuildPlugin_Edge.h
BuildPlugin_Wire.h
SET(PROJECT_SOURCES
BuildPlugin_Plugin.cpp
+ BuildPlugin_Shape.cpp
BuildPlugin_Vertex.cpp
BuildPlugin_Edge.cpp
BuildPlugin_Wire.cpp
TestCompSolid.py
TestCompound.py
TestCompound_ErrorMsg.py
+ TestCompound_History.py
TestSubShapes.py
TestSubShapes_ErrorMsg.py
TestFilling.py
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test that the history of compound works correctly after movement of groups after this compound feature
+
+# -*- coding: utf-8 -*-
+
+from salome.shaper import model
+from ModelAPI import *
+from GeomAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(-19.03078817733991, 40.92241379310347)
+SketchLine_1 = Sketch_1.addLine(-0.7463054187192111, 38.55911330049261, -18.03571428571429, 28.48399014778325)
+SketchCircle_1 = Sketch_1.addCircle(-2.238916256157633, 23.13546798029557, 5.523556488740459)
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchPoint_1")])
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1")])
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f")], model.selection(), 10, 0)
+Group_1_objects = [model.selection("VERTEX", "Vertex_1_1"), model.selection("VERTEX", "Edge_1_1/Modified_Vertex&Sketch_1/SketchLine_1_EndVertex"), model.selection("VERTEX", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchCircle_1_2][Extrusion_1_1/To_Face]")]
+Group_1 = model.addGroup(Part_1_doc, Group_1_objects)
+Group_2 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Edge_1_1"), model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchCircle_1_2][Extrusion_1_1/To_Face]")])
+Group_3 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")])
+Compound_1_objects = [model.selection("VERTEX", "Vertex_1_1"), model.selection("EDGE", "Edge_1_1"), model.selection("SOLID", "Extrusion_1_1")]
+Compound_1 = model.addCompound(Part_1_doc, Compound_1_objects)
+model.do()
+# move groups after the compound
+Part_1_doc.moveFeature(Group_1.feature(), Compound_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
+model.end()
+
+# check groups are correct
+aFactory = ModelAPI_Session.get().validators()
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 3)
+assert(aFactory.validate(Group_1.feature()))
+for i in range(3):
+ assert(Group_1.groupList().value(i).value().shapeType() == GeomAPI_Shape.VERTEX)
+
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 2)
+assert(aFactory.validate(Group_2.feature()))
+for i in range(2):
+ assert(Group_2.groupList().value(i).value().shapeType() == GeomAPI_Shape.EDGE)
+
+selectionList = Group_3.feature().selectionList("group_list")
+assert(selectionList.size() == 1)
+assert(aFactory.validate(Group_3.feature()))
+assert(Group_3.groupList().value(0).value().shapeType() == GeomAPI_Shape.SOLID)
+
+assert(model.checkPythonDump())
CollectionPlugin_Field.h
CollectionPlugin_WidgetCreator.h
CollectionPlugin_WidgetField.h
- CollectionPlugin_Validators.h
+ CollectionPlugin_Validators.h
)
SET(PROJECT_MOC_HEADERS
CollectionPlugin_Field.cpp
CollectionPlugin_WidgetCreator.cpp
CollectionPlugin_WidgetField.cpp
- CollectionPlugin_Validators.cpp
+ CollectionPlugin_Validators.cpp
)
SET(XML_RESOURCES
TestGroup2.py
TestField.py
TestGroup1799.py
- TestGroupMove.py
- TestGroupMove2.py
- TestGroupMove3.py
+ TestGroupMove01.py
+ TestGroupMove02.py
+ TestGroupMove03.py
+ TestGroupMove04.py
+ TestGroupMove05.py
+ TestGroupMove06.py
+ TestGroupMove07.py
+ TestGroupMove08.py
+ TestGroupMove09.py
+ TestGroupMove10.py
+ TestGroupMove11.py
+ TestGroupMove12.py
+ TestGroupMove13.py
+ TestGroupMove14.py
+ TestGroupMove15.py
+ TestGroupMove16.py
+ TestGroupMove17.py
+ TestGroupMove18.py
+ TestGroupMove19.py
TestGroupShareTopology.py
)
+++ /dev/null
-# Copyright (C) 2014-2019 CEA/DEN, EDF R&D
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-#
-
-# Test that box partitioned is splitted: group with edge becomes 2 edges group,
-# group with not-touched vertex keeps this vertex.
-
-from salome.shaper import model
-from ModelAPI import *
-
-model.begin()
-partSet = model.moduleDocument()
-Part_1 = model.addPart(partSet)
-Part_1_doc = Part_1.document()
-Box_1 = model.addBox(Part_1_doc, 20, 10, 10)
-Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Back"), 10, True)
-Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]")])
-Group_2 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Top]")])
-Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Plane_1")])
-model.do()
-# move groups
-Part_1_doc.moveFeature(Group_1.feature(), Partition_1.feature())
-Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
-model.end()
-
-# Check groups
-aFactory = ModelAPI_Session.get().validators()
-selectionList = Group_1.feature().selectionList("group_list")
-assert(selectionList.size() == 2)
-assert(aFactory.validate(Group_1.feature()))
-
-selectionList = Group_2.feature().selectionList("group_list")
-assert(selectionList.size() == 1)
-assert(aFactory.validate(Group_2.feature()))
--- /dev/null
+# Copyright (C) 2014-2019 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+# Test that box partitioned is splitted: group with edge becomes 2 edges group,
+# group with not-touched vertex keeps this vertex.
+
+from salome.shaper import model
+from ModelAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 20, 10, 10)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Back"), 10, True)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]")])
+Group_2 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Top]")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Plane_1")])
+model.do()
+# move groups
+Part_1_doc.moveFeature(Group_1.feature(), Partition_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+model.end()
+
+# Check groups
+aFactory = ModelAPI_Session.get().validators()
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 2)
+assert(aFactory.validate(Group_1.feature()))
+
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 1)
+assert(aFactory.validate(Group_2.feature()))
--- /dev/null
+# Copyright (C) 2014-2019 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+# Test that removed vertex, selected in the group makes empty group => invalid one
+
+from salome.shaper import model
+from ModelAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 20)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Bottom]"))
+Group_1 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Top]")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Plane_1")])
+Remove_SubShapes_1 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPSOLID", "Partition_1_1"))
+Remove_SubShapes_1.setSubShapesToKeep([model.selection("SOLID", "Partition_1_1_2")])
+model.do()
+# move group
+Part_1_doc.moveFeature(Group_1.feature(), Remove_SubShapes_1.feature())
+model.end()
+
+# Check group
+aFactory = ModelAPI_Session.get().validators()
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 0)
+assert(aFactory.validate(Group_1.feature()) == False)
--- /dev/null
+# Copyright (C) 2014-2019 CEA/DEN, EDF R&D
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+# Test that partition divides cylinder into 4 faces, there is no edges in a group moved to the end
+# Based on the CEA report mail 04.12.2018, page 2
+
+from SketchAPI import *
+
+from ModelAPI import *
+from GeomAPI import *
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
+SketchArc_1 = Sketch_1.addArc(-1.103476974288834e-12, 24.99999999999979, 24.49489742783218, 30, 0, 50, False)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OZ"), False)
+SketchLine_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.result())
+SketchLine_2 = Sketch_1.addLine(0, 50, -10, 50)
+SketchLine_2.setAuxiliary(True)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_2.result())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_1.results()[1], SketchLine_2.result())
+SketchLine_3 = Sketch_1.addLine(24.49489742783218, 30, 24.49489742783218, 5)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(24.49489742783218, 5, 34.49489742783218, 5)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(34.49489742783218, 5, 34.49489742783218, 0)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_6 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(34.49489742783218, 0, 0, 0)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_7.endPoint())
+SketchLine_8 = Sketch_1.addLine(0, 50, 0, 0)
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_8.endPoint())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_4.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_5.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_4.result(), 10)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_5.result(), 5)
+SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_3.result(), 25)
+SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_8.result(), 50)
+SketchConstraintLength_5 = Sketch_1.setLength(SketchLine_2.result(), 10)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 25)
+model.do()
+Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchArc_1_2r-SketchLine_8f-SketchLine_7r-SketchLine_5r-SketchLine_4r-SketchLine_3r")], model.selection("EDGE", "PartSet/OZ"), 360, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Revolution_1_1/Generated_Face&Sketch_1/SketchLine_3")])
+Partition_1_objects = [model.selection("SOLID", "Revolution_1_1"), model.selection("FACE", "PartSet/XOZ"), model.selection("FACE", "PartSet/YOZ")]
+Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects)
+model.do()
+
+# move group
+Part_1_doc.moveFeature(Group_1.feature(), Partition_1.feature())
+model.end()
+
+# Check group: result must be four faces
+aFactory = ModelAPI_Session.get().validators()
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 4)
+assert(aFactory.validate(Group_1.feature()))
+for i in range(4):
+ assert(Group_1.groupList().value(i).value().shapeType() == GeomAPI_Shape.FACE)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test of deep nested results history. Cylinders divided to two by cut, then each divided to
+# two by partition by plane, then resulting compsolids are collected in compound.
+# Checking that group on initial extrusion moved to the end contains the corresponding
+# results, but divided.
+
+from salome.shaper import model
+from ModelAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_1.addCircle(-4.602216748768477, 10.94581280788177, 9.660420057801511)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")], model.selection(), 10, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchCircle_1_2")])
+Group_2 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")])
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/YOZ"), 1, True)
+Sketch_2 = model.addSketch(Part_1_doc, model.standardPlane("XOY"))
+SketchCircle_2 = Sketch_2.addCircle(-5.643073116097736, 11.91382008305256, 15.03576198961618)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_2_2r")], model.selection(), 2, -4)
+Cut_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], [model.selection("SOLID", "Extrusion_2_1")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("COMPOUND", "Cut_1_1"), model.selection("FACE", "Plane_1")])
+Compound_1 = model.addCompound(Part_1_doc, [model.selection("COMPSOLID", "Partition_1_1"), model.selection("COMPSOLID", "Partition_1_2")])
+model.do()
+# move groups to the end
+Part_1_doc.moveFeature(Group_1.feature(), Compound_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+model.end()
+
+aFactory = ModelAPI_Session.get().validators()
+# check group 1: cylindical face is divided to 6 (because of seam edge)
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 6)
+assert(aFactory.validate(Group_1.feature()))
+
+# check group 2: solid is divided to 4 solids
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 4)
+assert(aFactory.validate(Group_2.feature()))
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test of deep nested results history.
+# Faces and edges of a box has been collected to groups. After that, the box has been copied.
+# Check that groups moved to the end contain corresponding results.
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Box_1_1")])
+Group_2_objects = [model.selection("FACE", "Box_1_1/Back"), model.selection("FACE", "Box_1_1/Top"), model.selection("FACE", "Box_1_1/Right"), model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Front")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_3_objects = [model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 15, 2)
+model.do()
+# move groups to the end
+Part_1_doc.moveFeature(Group_1.feature(), LinearCopy_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
+model.end()
+
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+# check group 1: all solids in compound should be selected
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 2)
+assert(aFactory.validate(Group_1.feature()))
+# check group 2: number of faces is multiplied twice than original
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 12)
+assert(aFactory.validate(Group_2.feature()))
+# check group 3: number of edges is multiplied twice than original
+selectionList = Group_3.feature().selectionList("group_list")
+assert(selectionList.size() == 24)
+assert(aFactory.validate(Group_3.feature()))
+
+model.begin()
+LinearCopy_2 = model.addMultiTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_1_1")], model.selection("EDGE", "PartSet/OY"), 15, 2, model.selection("EDGE", "PartSet/OZ"), 15, 2)
+# move groups to the end
+Part_1_doc.moveFeature(Group_1.feature(), LinearCopy_2.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
+model.end()
+
+# check group 1: all solids in compound should be selected
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 8)
+assert(aFactory.validate(Group_1.feature()))
+# check group 2: number of faces is multiplied twice than original
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 48)
+assert(aFactory.validate(Group_2.feature()))
+# check group 3: number of edges is multiplied twice than original
+selectionList = Group_3.feature().selectionList("group_list")
+assert(selectionList.size() == 96)
+assert(aFactory.validate(Group_3.feature()))
+
+model.begin()
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "LinearCopy_2_1_1_1"), model.selection("SOLID", "LinearCopy_2_1_1_2")], model.selection("EDGE", "PartSet/OZ"), 2)
+# move groups to the end
+Part_1_doc.moveFeature(Group_1.feature(), AngularCopy_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
+model.end()
+
+# check group 1: all solids in compound should be selected
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 4)
+assert(aFactory.validate(Group_1.feature()))
+# check group 2: number of faces is multiplied twice than original
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 24)
+assert(aFactory.validate(Group_2.feature()))
+# check group 3: number of edges is multiplied twice than original
+selectionList = Group_3.feature().selectionList("group_list")
+assert(selectionList.size() == 48)
+assert(aFactory.validate(Group_3.feature()))
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test of deep nested results history.
+# Copied boxes are involved to Fill operation.
+# Check the groups of initial boxes moved to the end contain the corresponding
+# results, but divided.
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Axis_4 = model.addAxis(Part_1_doc, model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Top]"))
+LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "Axis_1"), 10, 2)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", "LinearCopy_1_1_1")])
+Group_2_objects = [model.selection("FACE", "LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Back"), model.selection("FACE", "LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Top"), model.selection("FACE", "LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Right"), model.selection("FACE", "LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Left"), model.selection("FACE", "LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Bottom"), model.selection("FACE", "LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Front")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_3_objects = [model.selection("EDGE", "[LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Back][LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Bottom]"), model.selection("EDGE", "[LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Back][LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Right]"), model.selection("EDGE", "[LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Back][LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Left]"), model.selection("EDGE", "[LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Back][LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Top]"), model.selection("EDGE", "[LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Right][LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Bottom]"), model.selection("EDGE", "[LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Left][LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Top]"), model.selection("EDGE", "[LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Left][LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Bottom]"), model.selection("EDGE", "[LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Right][LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Top]"), model.selection("EDGE", "[LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Front][LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Bottom]"), model.selection("EDGE", "[LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Front][LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Left]"), model.selection("EDGE", "[LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Front][LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Right]"), model.selection("EDGE", "[LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Front][LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Top]")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Group_4 = model.addGroup(Part_1_doc, [model.selection("SOLID", "LinearCopy_1_1_2")])
+Group_5_objects = [model.selection("FACE", "LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Back"), model.selection("FACE", "LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Top"), model.selection("FACE", "LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Right"), model.selection("FACE", "LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Left"), model.selection("FACE", "LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Bottom"), model.selection("FACE", "LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Front")]
+Group_5 = model.addGroup(Part_1_doc, Group_5_objects)
+Group_6_objects = [model.selection("EDGE", "[LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Back][LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Bottom]"), model.selection("EDGE", "[LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Back][LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Right]"), model.selection("EDGE", "[LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Back][LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Left]"), model.selection("EDGE", "[LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Back][LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Top]"), model.selection("EDGE", "[LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Right][LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Bottom]"), model.selection("EDGE", "[LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Left][LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Top]"), model.selection("EDGE", "[LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Left][LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Bottom]"), model.selection("EDGE", "[LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Right][LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Top]"), model.selection("EDGE", "[LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Front][LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Bottom]"), model.selection("EDGE", "[LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Front][LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Left]"), model.selection("EDGE", "[LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Front][LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Right]"), model.selection("EDGE", "[LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Front][LinearCopy_1_1_2/MF:Translated_Face&Box_1_1/Top]")]
+Group_6 = model.addGroup(Part_1_doc, Group_6_objects)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Left"), model.selection("FACE", "LinearCopy_1_1_1/MF:Translated_Face&Box_1_1/Right"))
+Fill_1 = model.addFill(Part_1_doc, [model.selection("SOLID", "LinearCopy_1_1_1")], [model.selection("SOLID", "LinearCopy_1_1_2"), model.selection("FACE", "Plane_1")])
+model.do()
+# move groups to the end
+Part_1_doc.moveFeature(Group_1.feature(), Fill_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
+Part_1_doc.moveFeature(Group_4.feature(), Group_3.feature())
+Part_1_doc.moveFeature(Group_5.feature(), Group_4.feature())
+Part_1_doc.moveFeature(Group_6.feature(), Group_5.feature())
+model.end()
+
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+
+# groups related to original box should be split
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 3)
+assert(aFactory.validate(Group_1.feature()))
+
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 13)
+assert(aFactory.validate(Group_2.feature()))
+
+selectionList = Group_3.feature().selectionList("group_list")
+assert(selectionList.size() == 19)
+assert(aFactory.validate(Group_3.feature()))
+
+# groups related to the copied box should contain only the elements connected with the original box
+selectionList = Group_4.feature().selectionList("group_list")
+assert(selectionList.size() == 1)
+assert(aFactory.validate(Group_4.feature()))
+
+selectionList = Group_5.feature().selectionList("group_list")
+assert(selectionList.size() == 3)
+assert(aFactory.validate(Group_5.feature()))
+
+selectionList = Group_6.feature().selectionList("group_list")
+assert(selectionList.size() == 3)
+assert(aFactory.validate(Group_6.feature()))
+
+
+model.begin()
+Filling_1 = model.addFilling(Part_1_doc, [model.selection("EDGE", "Fill_1_1_2/Generated_Edge&Plane_1/Plane_1&Box_1_1/Top"), model.selection("EDGE", "[Fill_1_1_2/Modified_Face&Box_1_1/Right][(Fill_1_1_2/Modified_Face&Box_1_1/Right)(Fill_1_1_2/Modified_Face&Plane_1/Plane_1)(Fill_1_1_2/Modified_Face&Box_1_1/Front)(Fill_1_1_2/Modified_Face&Box_1_1/Top)2(Fill_1_1_2/Modified_Face&Box_1_1/Left)2]")])
+Fill_2 = model.addFill(Part_1_doc, [model.selection("SOLID", "Fill_1_1_2")], [model.selection("FACE", "Filling_1_1")])
+model.do()
+# move groups to the end once again
+Part_1_doc.moveFeature(Group_1.feature(), Fill_2.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
+Part_1_doc.moveFeature(Group_4.feature(), Group_3.feature())
+Part_1_doc.moveFeature(Group_5.feature(), Group_4.feature())
+Part_1_doc.moveFeature(Group_6.feature(), Group_5.feature())
+model.end()
+
+# groups related to original box should be split
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 4)
+assert(aFactory.validate(Group_1.feature()))
+
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 16)
+assert(aFactory.validate(Group_2.feature()))
+
+selectionList = Group_3.feature().selectionList("group_list")
+# one of edges should disappear, due to its belonging to the face of the filling
+assert(selectionList.size() == 18)
+assert(aFactory.validate(Group_3.feature()))
+
+# groups related to the copied box should be split correspondingly
+selectionList = Group_4.feature().selectionList("group_list")
+assert(selectionList.size() == 1)
+assert(aFactory.validate(Group_4.feature()))
+
+selectionList = Group_5.feature().selectionList("group_list")
+assert(selectionList.size() == 6)
+assert(aFactory.validate(Group_5.feature()))
+
+selectionList = Group_6.feature().selectionList("group_list")
+assert(selectionList.size() == 5)
+assert(aFactory.validate(Group_6.feature()))
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test of deep nested results history.
+# Faces and edges of a box has been collected to groups. After that, the box has been symmetried.
+# Check that groups moved to the end contain corresponding results.
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Box_1_1")])
+Group_2_objects = [model.selection("FACE", "Box_1_1/Back"), model.selection("FACE", "Box_1_1/Top"), model.selection("FACE", "Box_1_1/Right"), model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Front")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_3_objects = [model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Symmetry_1 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("FACE", "Box_1_1/Left"), False)
+model.do()
+# move groups to the end
+Part_1_doc.moveFeature(Group_1.feature(), Symmetry_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
+model.end()
+
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+# check group 1: solids should be selected
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 1)
+assert(aFactory.validate(Group_1.feature()))
+# check group 2: number of faces is the same
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 6)
+assert(aFactory.validate(Group_2.feature()))
+# check group 3: number of edges is the same
+selectionList = Group_3.feature().selectionList("group_list")
+assert(selectionList.size() == 12)
+assert(aFactory.validate(Group_3.feature()))
+
+model.begin()
+Symmetry_2 = model.addSymmetry(Part_1_doc, [model.selection("SOLID", "Symmetry_1_1")], model.selection("VERTEX", "[Symmetry_1_1/MF:Symmetried_Face&Box_1_1/Front][Symmetry_1_1/MF:Symmetried_Face&Box_1_1/Left][Symmetry_1_1/MF:Symmetried_Face&Box_1_1/Bottom]"), True)
+model.do()
+# move groups to the end
+Part_1_doc.moveFeature(Group_1.feature(), Symmetry_2.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
+model.end()
+
+# check group 1: all solids in compound should be selected
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 2)
+assert(aFactory.validate(Group_1.feature()))
+# check group 2: number of faces is multiplied twice than original
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 12)
+assert(aFactory.validate(Group_2.feature()))
+# check group 3: number of edges is multiplied twice than original
+selectionList = Group_3.feature().selectionList("group_list")
+assert(selectionList.size() == 24)
+assert(aFactory.validate(Group_3.feature()))
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test of deep nested results history. Fillet operation.
+# Check the groups of initial solids moved to the end contain the corresponding
+# results, but divided.
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Box_1_1")])
+Group_2_objects = [model.selection("FACE", "Box_1_1/Back"), model.selection("FACE", "Box_1_1/Top"), model.selection("FACE", "Box_1_1/Right"), model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Front")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_3_objects = [model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Top]"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Group_4 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")])
+Group_5_objects = [model.selection("FACE", "Cylinder_1_1/Face_1"), model.selection("FACE", "Cylinder_1_1/Face_2"), model.selection("FACE", "Cylinder_1_1/Face_3")]
+Group_5 = model.addGroup(Part_1_doc, Group_5_objects)
+Group_6_objects = [model.selection("EDGE", "[Cylinder_1_1/Face_1][Cylinder_1_1/Face_2]"), model.selection("EDGE", "[Cylinder_1_1/Face_1][Cylinder_1_1/Face_3]"), model.selection("EDGE", "([Cylinder_1_1/Face_1][Cylinder_1_1/Face_2])([Cylinder_1_1/Face_1][Cylinder_1_1/Face_3])")]
+Group_6 = model.addGroup(Part_1_doc, Group_6_objects)
+Fillet_1 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]")], 2)
+model.do()
+# move groups to the end
+Part_1_doc.moveFeature(Group_1.feature(), Fillet_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
+model.end()
+
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+
+# groups related to original box should be split
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 1)
+assert(aFactory.validate(Group_1.feature()))
+
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 6)
+assert(aFactory.validate(Group_2.feature()))
+
+selectionList = Group_3.feature().selectionList("group_list")
+assert(selectionList.size() == 11)
+assert(aFactory.validate(Group_3.feature()))
+
+model.begin()
+Fillet_2 = model.addFillet(Part_1_doc, [model.selection("FACE", "Cylinder_1_1/Face_2")], 2)
+model.do()
+# move groups to the end
+Part_1_doc.moveFeature(Group_4.feature(), Fillet_2.feature())
+Part_1_doc.moveFeature(Group_5.feature(), Group_4.feature())
+Part_1_doc.moveFeature(Group_6.feature(), Group_5.feature())
+model.end()
+
+# groups related to original cylinder should be split
+selectionList = Group_4.feature().selectionList("group_list")
+assert(selectionList.size() == 1)
+assert(aFactory.validate(Group_4.feature()))
+
+selectionList = Group_5.feature().selectionList("group_list")
+assert(selectionList.size() == 3)
+assert(aFactory.validate(Group_5.feature()))
+
+selectionList = Group_6.feature().selectionList("group_list")
+assert(selectionList.size() == 2) # edge selected for the fillet become removed
+assert(aFactory.validate(Group_6.feature()))
+
+model.begin()
+Fillet_3 = model.addFillet(Part_1_doc, [model.selection("EDGE", "[Fillet_1_1/MF:Fillet_Face&Box_1_1/Front][Fillet_1_1/MF:Fillet_Face&Box_1_1/Left]")], 1, 2)
+model.do()
+# move groups to the end
+Part_1_doc.moveFeature(Group_1.feature(), Fillet_3.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
+Part_1_doc.moveFeature(Group_4.feature(), Group_3.feature())
+Part_1_doc.moveFeature(Group_5.feature(), Group_4.feature())
+Part_1_doc.moveFeature(Group_6.feature(), Group_5.feature())
+model.end()
+
+# groups related to original box should be split
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 1)
+assert(aFactory.validate(Group_1.feature()))
+
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 6)
+assert(aFactory.validate(Group_2.feature()))
+
+selectionList = Group_3.feature().selectionList("group_list")
+assert(selectionList.size() == 9)
+assert(aFactory.validate(Group_3.feature()))
+
+# groups related to original cylinder should stay untouched
+selectionList = Group_4.feature().selectionList("group_list")
+assert(selectionList.size() == 1)
+assert(aFactory.validate(Group_4.feature()))
+
+selectionList = Group_5.feature().selectionList("group_list")
+assert(selectionList.size() == 3)
+assert(aFactory.validate(Group_5.feature()))
+
+selectionList = Group_6.feature().selectionList("group_list")
+assert(selectionList.size() == 2)
+assert(aFactory.validate(Group_6.feature()))
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test of deep nested results history. FuseFaces operation.
+# Check the groups of initial solids moved to the end contain the corresponding
+# results, but merged faces.
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1"), model.selection("SOLID", "Box_1_1")])
+Union_1_objects = [model.selection("SOLID", "Partition_1_1_1"), model.selection("SOLID", "Partition_1_1_2"), model.selection("SOLID", "Partition_1_1_3")]
+Union_1 = model.addUnion(Part_1_doc, Union_1_objects)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Union_1_1")])
+Group_2_objects = [model.selection("FACE", "Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_1"), model.selection("FACE", "Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_2"), model.selection("FACE", "Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_3"), model.selection("FACE", "Partition_1_1_2/Modified_Face&Box_1_1/Bottom&Cylinder_1_1/Face_3"), model.selection("FACE", "Partition_1_1_2/Modified_Face&Box_1_1/Top&Cylinder_1_1/Face_2"), model.selection("FACE", "Partition_1_1_3/Modified_Face&Box_1_1/Back"), model.selection("FACE", "Partition_1_1_3/Modified_Face&Box_1_1/Bottom"), model.selection("FACE", "Partition_1_1_3/Modified_Face&Box_1_1/Top"), model.selection("FACE", "Box_1_1/Right"), model.selection("FACE", "Partition_1_1_3/Modified_Face&Box_1_1/Left"), model.selection("FACE", "Box_1_1/Front")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_3_objects = [model.selection("EDGE", "[Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_1][Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_3]"), model.selection("EDGE", "[Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_2][Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_1]"), model.selection("EDGE", "([Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_1][Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_3])(Partition_1_1_3/Generated_Edge&Box_1_1/Back&Cylinder_1_1/Face_1)([Partition_1_1_3/Modified_Face&Box_1_1/Back][Partition_1_1_3/Modified_Face&Box_1_1/Bottom])([Partition_1_1_3/Modified_Face&Box_1_1/Bottom][Partition_1_1_2/Modified_Face&Box_1_1/Bottom&Cylinder_1_1/Face_3])_Union_1_1"), model.selection("EDGE", "[Partition_1_1_3/Modified_Face&Box_1_1/Back][Partition_1_1_3/Modified_Face&Box_1_1/Bottom]"), model.selection("EDGE", "[Partition_1_1_3/Modified_Face&Box_1_1/Back][Box_1_1/Right]"), model.selection("EDGE", "Partition_1_1_3/Generated_Edge&Box_1_1/Back&Cylinder_1_1/Face_1"), model.selection("EDGE", "([Partition_1_1_2/Modified_Face&Box_1_1/Top&Cylinder_1_1/Face_2][Partition_1_1_3/Modified_Face&Box_1_1/Top])([Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_2][Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_1])([Partition_1_1_3/Modified_Face&Box_1_1/Top][Partition_1_1_3/Modified_Face&Box_1_1/Back])(Partition_1_1_3/Generated_Edge&Box_1_1/Back&Cylinder_1_1/Face_1)_Union_1_1"), model.selection("EDGE", "[Partition_1_1_3/Modified_Face&Box_1_1/Top][Partition_1_1_3/Modified_Face&Box_1_1/Back]"), model.selection("EDGE", "([Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_1][Partition_1_1_3/Modified_Face&Box_1_1/Left])([Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_1][Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_3])([Partition_1_1_3/Modified_Face&Box_1_1/Left][Partition_1_1_3/Modified_Face&Box_1_1/Bottom])([Partition_1_1_3/Modified_Face&Box_1_1/Bottom][Partition_1_1_2/Modified_Face&Box_1_1/Bottom&Cylinder_1_1/Face_3])_Union_1_1"), model.selection("EDGE", "[Partition_1_1_3/Modified_Face&Box_1_1/Bottom][Partition_1_1_2/Modified_Face&Box_1_1/Bottom&Cylinder_1_1/Face_3]"), model.selection("EDGE", "[Partition_1_1_2/Modified_Face&Box_1_1/Top&Cylinder_1_1/Face_2][Partition_1_1_3/Modified_Face&Box_1_1/Top]"), model.selection("EDGE", "([Partition_1_1_2/Modified_Face&Box_1_1/Top&Cylinder_1_1/Face_2][Partition_1_1_3/Modified_Face&Box_1_1/Top])([Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_2][Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_1])([Partition_1_1_3/Modified_Face&Box_1_1/Top][Partition_1_1_3/Modified_Face&Box_1_1/Left])([Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_1][Partition_1_1_3/Modified_Face&Box_1_1/Left])_Union_1_1"), model.selection("EDGE", "[Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_1][Partition_1_1_3/Modified_Face&Box_1_1/Left]"), model.selection("EDGE", "[Partition_1_1_3/Modified_Face&Box_1_1/Top][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Right][Partition_1_1_3/Modified_Face&Box_1_1/Bottom]"), model.selection("EDGE", "[Partition_1_1_3/Modified_Face&Box_1_1/Left][Partition_1_1_3/Modified_Face&Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Partition_1_1_3/Modified_Face&Box_1_1/Left]"), model.selection("EDGE", "[Partition_1_1_3/Modified_Face&Box_1_1/Top][Partition_1_1_3/Modified_Face&Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Front][Partition_1_1_3/Modified_Face&Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Front]"), model.selection("EDGE", "[Partition_1_1_3/Modified_Face&Box_1_1/Top][Box_1_1/Front]")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Group_4_objects = [model.selection("VERTEX", "[Partition_1_1_3/Modified_Face&Box_1_1/Top][Box_1_1/Front][Partition_1_1_3/Modified_Face&Box_1_1/Left]"), model.selection("VERTEX", "[Partition_1_1_2/Modified_Face&Box_1_1/Top&Cylinder_1_1/Face_2][Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_2][Partition_1_1_3/Modified_Face&Box_1_1/Top][Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_1][Partition_1_1_3/Modified_Face&Box_1_1/Left]"), model.selection("VERTEX", "[Box_1_1/Front][Partition_1_1_3/Modified_Face&Box_1_1/Left][Partition_1_1_3/Modified_Face&Box_1_1/Bottom]"), model.selection("VERTEX", "[_weak_name_10_Union_1_1]e[_weak_name_4_Union_1_1]e"), model.selection("VERTEX", "[Partition_1_1_3/Modified_Face&Box_1_1/Top][Box_1_1/Right][Box_1_1/Front]"), model.selection("VERTEX", "[Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_1][Partition_1_1_3/Modified_Face&Box_1_1/Left][Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_3][Partition_1_1_3/Modified_Face&Box_1_1/Bottom][Partition_1_1_2/Modified_Face&Box_1_1/Bottom&Cylinder_1_1/Face_3]"), model.selection("VERTEX", "[Partition_1_1_2/Modified_Face&Box_1_1/Top&Cylinder_1_1/Face_2][Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_2][Partition_1_1_3/Modified_Face&Box_1_1/Top][Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_1][Partition_1_1_3/Modified_Face&Box_1_1/Back]"), model.selection("VERTEX", "[Box_1_1/Right][Box_1_1/Front][Partition_1_1_3/Modified_Face&Box_1_1/Bottom]"), model.selection("VERTEX", "[_weak_name_3_Union_1_1]e[_weak_name_9_Union_1_1]e"), model.selection("VERTEX", "[Partition_1_1_3/Modified_Face&Box_1_1/Top][Partition_1_1_3/Modified_Face&Box_1_1/Back][Box_1_1/Right]"), model.selection("VERTEX", "[Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_1][Partition_1_1_3/Modified_Face&Box_1_1/Back][Partition_1_1_1/Modified_Face&Cylinder_1_1/Face_3][Partition_1_1_3/Modified_Face&Box_1_1/Bottom][Partition_1_1_2/Modified_Face&Box_1_1/Bottom&Cylinder_1_1/Face_3]"), model.selection("VERTEX", "[Partition_1_1_3/Modified_Face&Box_1_1/Back][Box_1_1/Right][Partition_1_1_3/Modified_Face&Box_1_1/Bottom]")]
+Group_4 = model.addGroup(Part_1_doc, Group_4_objects)
+FusionFaces_1 = model.addFusionFaces(Part_1_doc, model.selection("SOLID", "Union_1_1"))
+model.do()
+# move groups to the end
+Part_1_doc.moveFeature(Group_1.feature(), FusionFaces_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
+Part_1_doc.moveFeature(Group_4.feature(), Group_3.feature())
+model.end()
+
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+
+# number of solids should be the same
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 1)
+assert(aFactory.validate(Group_1.feature()))
+
+# same-plane faces should be merged
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 11)
+assert(aFactory.validate(Group_2.feature()))
+
+# shared edges of merged faces should be deleted
+selectionList = Group_3.feature().selectionList("group_list")
+assert(selectionList.size() == 15)
+assert(aFactory.validate(Group_3.feature()))
+
+selectionList = Group_4.feature().selectionList("group_list")
+assert(selectionList.size() == 10)
+assert(aFactory.validate(Group_4.feature()))
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+from ModelAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_1.addCircle(-8, 20, 25)
+SketchLine_1 = Sketch_1.addLine(40, 32, -5, 32)
+SketchLine_2 = Sketch_1.addLine(-5, 32, -5, 5)
+SketchLine_3 = Sketch_1.addLine(-5, 5, 40, 5)
+SketchLine_4 = Sketch_1.addLine(40, 5, 40, 32)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0)
+Group_1_objects = [model.selection("SOLID", "Extrusion_1_1_2"), model.selection("SOLID", "Extrusion_1_1_1"), model.selection("SOLID", "Extrusion_1_1_3")]
+Group_1 = model.addGroup(Part_1_doc, Group_1_objects)
+# to create groups of faces, edges and vertices
+model.testHaveNamingSubshapes(Extrusion_1, model, Part_1_doc)
+model.do()
+Remove_SubShapes_1 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPSOLID", "Extrusion_1_1"))
+Remove_SubShapes_1.setSubShapesToRemove([model.selection("SOLID", "Extrusion_1_1_2"), model.selection("SOLID", "Extrusion_1_1_3")])
+model.do()
+# move groups to the end
+LastFeature = Remove_SubShapes_1.feature()
+for i in range(Part_1_doc.size("Groups")):
+ GroupFeature = Part_1_doc.feature(objectToResult(Part_1_doc.object("Groups", 0))) # move always the very first group
+ Part_1_doc.moveFeature(GroupFeature, LastFeature)
+ LastFeature = GroupFeature
+model.end()
+
+aFactory = ModelAPI_Session.get().validators()
+
+# Check groups
+a = 0
+num_in_groups = [1, 10, 15, 7]
+for i in range(Part_1_doc.size("Groups")):
+ GroupFeature = Part_1_doc.feature(objectToResult(Part_1_doc.object("Groups", i)))
+ assert(aFactory.validate(GroupFeature))
+ assert(GroupFeature.selectionList("group_list").size() == num_in_groups[a])
+ a = a + 1
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test of deep nested results history. Scale operation.
+# Check the groups of initial solids moved to the end contain the corresponding results.
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_1.addCircle(-15, 30, 30)
+SketchCircle_2 = Sketch_1.addCircle(15, 25, 25)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0)
+Group_1_objects = [model.selection("SOLID", "Extrusion_1_1_3"), model.selection("SOLID", "Extrusion_1_1_1"), model.selection("SOLID", "Extrusion_1_1_2")]
+Group_1 = model.addGroup(Part_1_doc, Group_1_objects)
+Group_2_objects = [model.selection("FACE", "Extrusion_1_1_3/Generated_Face&Sketch_1/SketchCircle_2_2"), model.selection("FACE", "Extrusion_1_1_3/Generated_Face&Sketch_1/SketchCircle_1_2"), model.selection("FACE", "Extrusion_1_1_3/From_Face"), model.selection("FACE", "Extrusion_1_1_3/To_Face"), model.selection("FACE", "Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1"), model.selection("FACE", "Extrusion_1_1_1/To_Face"), model.selection("FACE", "Extrusion_1_1_1/From_Face"), model.selection("FACE", "Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_2_2"), model.selection("FACE", "Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2"), model.selection("FACE", "Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_1"), model.selection("FACE", "Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1"), model.selection("FACE", "Extrusion_1_1_2/From_Face"), model.selection("FACE", "Extrusion_1_1_2/To_Face"), model.selection("FACE", "Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2"), model.selection("FACE", "Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_2")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_3_objects = [model.selection("EDGE", "[Extrusion_1_1_3/Generated_Face&Sketch_1/SketchCircle_1_2][Extrusion_1_1_3/Generated_Face&Sketch_1/SketchCircle_2_2][weak_name_1]"), model.selection("EDGE", "[Extrusion_1_1_3/Generated_Face&Sketch_1/SketchCircle_2_2][Extrusion_1_1_3/From_Face]"), model.selection("EDGE", "[Extrusion_1_1_3/Generated_Face&Sketch_1/SketchCircle_2_2][Extrusion_1_1_3/To_Face]"), model.selection("EDGE", "[Extrusion_1_1_3/Generated_Face&Sketch_1/SketchCircle_1_2][Extrusion_1_1_3/From_Face]"), model.selection("EDGE", "[Extrusion_1_1_3/Generated_Face&Sketch_1/SketchCircle_1_2][Extrusion_1_1_3/To_Face]"), model.selection("EDGE", "[Extrusion_1_1_3/Generated_Face&Sketch_1/SketchCircle_1_2][Extrusion_1_1_3/Generated_Face&Sketch_1/SketchCircle_2_2][weak_name_2]"), model.selection("EDGE", "[Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1][Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_2_2]"), model.selection("EDGE", "[Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1][Extrusion_1_1_1/From_Face]"), model.selection("EDGE", "[Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1][Extrusion_1_1_1/To_Face]"), model.selection("EDGE", "[Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_2_2][Extrusion_1_1_1/From_Face]"), model.selection("EDGE", "[Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1][Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2]"), model.selection("EDGE", "[Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_2_2][Extrusion_1_1_1/To_Face]"), model.selection("EDGE", "[Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2][Extrusion_1_1_1/To_Face]"), model.selection("EDGE", "[Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2][Extrusion_1_1_1/From_Face]"), model.selection("EDGE", "[Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2][Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_2_2]"), model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1][Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_1]"), model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_1][Extrusion_1_1_2/From_Face]"), model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_1][Extrusion_1_1_2/To_Face]"), model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1][Extrusion_1_1_2/To_Face]"), model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1][Extrusion_1_1_2/From_Face]"), model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1][Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2]"), model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2][Extrusion_1_1_2/To_Face]"), model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2][Extrusion_1_1_2/From_Face]"), model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_2][Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2]"), model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_2][Extrusion_1_1_2/To_Face]"), model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_2][Extrusion_1_1_2/From_Face]"), model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_1][Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_2]")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Group_4_objects = [model.selection("VERTEX", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_1][Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_2][Extrusion_1_1_2/To_Face]"), model.selection("VERTEX", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_1][Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_2][Extrusion_1_1_2/From_Face]"), model.selection("VERTEX", "[Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1][Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_2_2][Extrusion_1_1_1/To_Face]"), model.selection("VERTEX", "[_weak_name_5_Extrusion_1_1_3]e[_weak_name_2_Extrusion_1_1_3]e[_weak_name_4_Extrusion_1_1_3]e"), model.selection("VERTEX", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1][Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_1][Extrusion_1_1_2/To_Face]"), model.selection("VERTEX", "[_weak_name_5_Extrusion_1_1_3]e[_weak_name_1_Extrusion_1_1_3]e[_weak_name_3_Extrusion_1_1_3]e"), model.selection("VERTEX", "[Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1][Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_2_2][Extrusion_1_1_1/From_Face]"), model.selection("VERTEX", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1][Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_1][Extrusion_1_1_2/From_Face]"), model.selection("VERTEX", "[Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1][Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2][Extrusion_1_1_1/To_Face]"), model.selection("VERTEX", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1][Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2][Extrusion_1_1_2/To_Face]"), model.selection("VERTEX", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1][Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2][Extrusion_1_1_2/From_Face]"), model.selection("VERTEX", "[Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_1][Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2][Extrusion_1_1_1/From_Face]"), model.selection("VERTEX", "[_weak_name_6_Extrusion_1_1_3]e[_weak_name_2_Extrusion_1_1_3]e[_weak_name_4_Extrusion_1_1_3]e"), model.selection("VERTEX", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_2][Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2][Extrusion_1_1_2/To_Face]"), model.selection("VERTEX", "[Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2][Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_2_2][Extrusion_1_1_1/To_Face]"), model.selection("VERTEX", "[_weak_name_6_Extrusion_1_1_3]e[_weak_name_1_Extrusion_1_1_3]e[_weak_name_3_Extrusion_1_1_3]e"), model.selection("VERTEX", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_2_2&weak_name_2][Extrusion_1_1_2/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2][Extrusion_1_1_2/From_Face]"), model.selection("VERTEX", "[Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_1_2&weak_name_2][Extrusion_1_1_1/Generated_Face&Sketch_1/SketchCircle_2_2][Extrusion_1_1_1/From_Face]")]
+Group_4 = model.addGroup(Part_1_doc, Group_4_objects)
+Scale_1 = model.addScale(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1_1")] , model.selection("VERTEX", "PartSet/Origin"), 2)
+model.do()
+# move groups to the end
+Part_1_doc.moveFeature(Group_1.feature(), Scale_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
+Part_1_doc.moveFeature(Group_4.feature(), Group_3.feature())
+model.end()
+
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 1)
+assert(aFactory.validate(Group_1.feature()))
+
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 5)
+assert(aFactory.validate(Group_2.feature()))
+
+selectionList = Group_3.feature().selectionList("group_list")
+assert(selectionList.size() == 9)
+assert(aFactory.validate(Group_3.feature()))
+
+selectionList = Group_4.feature().selectionList("group_list")
+assert(selectionList.size() == 6)
+assert(aFactory.validate(Group_4.feature()))
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test of deep nested results history. Translation operation.
+# Check the groups of initial boxes moved to the end contain the corresponding
+# results, but divided.
+
+from salome.shaper import model
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+
+def moveGroupsAndVerify(thePart, theLastFeature, theRefNumInGroups):
+ # move groups to the end
+ model.begin()
+ LastFeature = theLastFeature
+ for i in range(thePart.size("Groups")):
+ GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", 0))) # move always the very first group
+ Part_1_doc.moveFeature(GroupFeature, LastFeature)
+ LastFeature = GroupFeature
+ model.end()
+
+ a = 0
+ for i in range(thePart.size("Groups")):
+ GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", i)))
+ assert(aFactory.validate(GroupFeature))
+ assert(GroupFeature.selectionList("group_list").size() == theRefNumInGroups[a])
+ a = a + 1
+
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Right"))
+Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Front"), model.selection("FACE", "Box_1_1/Back"))
+Partition_1_objects = [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Plane_1"), model.selection("FACE", "Plane_2")]
+Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Partition_1_1_3"), model.selection("SOLID", "Partition_1_1_1")])
+Group_2_objects = [model.selection("FACE", "Partition_1_1_4/Modified_Face&Box_1_1/Front"), model.selection("FACE", "Partition_1_1_4/Modified_Face&Box_1_1/Top"), model.selection("FACE", "Partition_1_1_2/Modified_Face&Box_1_1/Top"), model.selection("FACE", "Partition_1_1_2/Modified_Face&Box_1_1/Right")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_3_objects = [model.selection("EDGE", "[Partition_1_1_3/Modified_Face&Box_1_1/Top][Partition_1_1_3/Modified_Face&Box_1_1/Front]"), model.selection("EDGE", "[Partition_1_1_3/Modified_Face&Box_1_1/Top][Partition_1_1_3/Modified_Face&Box_1_1/Left]"), model.selection("EDGE", "Partition_1_1_1/Generated_Edge&Plane_2/Plane_2&Box_1_1/Top"), model.selection("EDGE", "[Partition_1_1_1/Modified_Face&Box_1_1/Top][Partition_1_1_1/Modified_Face&Box_1_1/Left]"), model.selection("EDGE", "[Partition_1_1_1/Modified_Face&Box_1_1/Back][Partition_1_1_1/Modified_Face&Box_1_1/Top]"), model.selection("EDGE", "Partition_1_1_2/Generated_Edge&Plane_1/Plane_1&Box_1_1/Top"), model.selection("EDGE", "Partition_1_1_3/Generated_Edge&Plane_1/Plane_1&Box_1_1/Top"), model.selection("EDGE", "[Partition_1_1_4/Modified_Face&Box_1_1/Top][Partition_1_1_4/Modified_Face&Box_1_1/Front]"), model.selection("EDGE", "[Partition_1_1_4/Modified_Face&Box_1_1/Top][Partition_1_1_4/Modified_Face&Box_1_1/Right]"), model.selection("EDGE", "Partition_1_1_2/Generated_Edge&Plane_2/Plane_2&Box_1_1/Top"), model.selection("EDGE", "[Partition_1_1_2/Modified_Face&Box_1_1/Back][Partition_1_1_2/Modified_Face&Box_1_1/Top]"), model.selection("EDGE", "[Partition_1_1_2/Modified_Face&Box_1_1/Top][Partition_1_1_2/Modified_Face&Box_1_1/Right]")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Group_4_objects = [model.selection("VERTEX", "[Partition_1_1_3/Modified_Face&Box_1_1/Front][Partition_1_1_3/Modified_Face&Box_1_1/Left][Partition_1_1_3/Modified_Face&Box_1_1/Bottom]"), model.selection("VERTEX", "Partition_1_1_4/Generated_Vertex&Plane_1/Plane_1&weak_name_1"), model.selection("VERTEX", "[Partition_1_1_4/Modified_Face&Box_1_1/Front][Partition_1_1_4/Modified_Face&Box_1_1/Bottom][Partition_1_1_4/Modified_Face&Box_1_1/Right]"), model.selection("VERTEX", "Partition_1_1_1/Generated_Vertex&Plane_2/Plane_2&weak_name_1"), model.selection("VERTEX", "[Partition_1_1_2/Modified_Face&Box_1_1/Bottom][Partition_1_1_2/Modified_Face&Plane_1/Plane_1][Partition_1_1_2/Modified_Face&Plane_2/Plane_2]"), model.selection("VERTEX", "Partition_1_1_2/Generated_Vertex&Plane_2/Plane_2&weak_name_1"), model.selection("VERTEX", "[Partition_1_1_1/Modified_Face&Box_1_1/Back][Partition_1_1_1/Modified_Face&Box_1_1/Bottom][Partition_1_1_1/Modified_Face&Box_1_1/Left]"), model.selection("VERTEX", "Partition_1_1_2/Generated_Vertex&Plane_1/Plane_1&weak_name_1"), model.selection("VERTEX", "[Partition_1_1_2/Modified_Face&Box_1_1/Back][Partition_1_1_2/Modified_Face&Box_1_1/Right][Partition_1_1_2/Modified_Face&Box_1_1/Bottom]")]
+Group_4 = model.addGroup(Part_1_doc, Group_4_objects)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_1_1")], model.selection("EDGE", "PartSet/OX"), 20)
+model.do()
+model.end()
+
+num_in_groups = [2, 4, 12, 9]
+moveGroupsAndVerify(Part_1_doc, Translation_1.feature(), num_in_groups)
+
+model.begin()
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Translation_1_1")], 10, 10, 0)
+model.end()
+moveGroupsAndVerify(Part_1_doc, Translation_2.feature(), num_in_groups)
+
+model.begin()
+Translation_3 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Translation_2_1")], model.selection("VERTEX", "[Translation_2_1_1/MF:Translated_Face&Box_1_1/Back][Translation_2_1_1/MF:Translated_Face&Box_1_1/Bottom][Translation_2_1_1/MF:Translated_Face&Box_1_1/Left]"), model.selection("VERTEX", "PartSet/Origin"))
+model.end()
+moveGroupsAndVerify(Part_1_doc, Translation_3.feature(), num_in_groups)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test of deep nested results history. Rotation operation.
+# Check the groups of initial boxes moved to the end contain the corresponding
+# results, but divided.
+
+from salome.shaper import model
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+
+def moveGroupsAndVerify(thePart, theLastFeature, theRefNumInGroups):
+ # move groups to the end
+ model.begin()
+ LastFeature = theLastFeature
+ for i in range(thePart.size("Groups")):
+ GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", 0))) # move always the very first group
+ Part_1_doc.moveFeature(GroupFeature, LastFeature)
+ LastFeature = GroupFeature
+ model.end()
+
+ a = 0
+ for i in range(thePart.size("Groups")):
+ GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", i)))
+ assert(aFactory.validate(GroupFeature))
+ assert(GroupFeature.selectionList("group_list").size() == theRefNumInGroups[a])
+ a = a + 1
+
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Right"))
+Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Front"), model.selection("FACE", "Box_1_1/Back"))
+Partition_1_objects = [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Plane_1"), model.selection("FACE", "Plane_2")]
+Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Partition_1_1_3"), model.selection("SOLID", "Partition_1_1_1")])
+Group_2_objects = [model.selection("FACE", "Partition_1_1_4/Modified_Face&Box_1_1/Front"), model.selection("FACE", "Partition_1_1_4/Modified_Face&Box_1_1/Top"), model.selection("FACE", "Partition_1_1_2/Modified_Face&Box_1_1/Top"), model.selection("FACE", "Partition_1_1_2/Modified_Face&Box_1_1/Right")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_3_objects = [model.selection("EDGE", "[Partition_1_1_3/Modified_Face&Box_1_1/Top][Partition_1_1_3/Modified_Face&Box_1_1/Front]"), model.selection("EDGE", "[Partition_1_1_3/Modified_Face&Box_1_1/Top][Partition_1_1_3/Modified_Face&Box_1_1/Left]"), model.selection("EDGE", "Partition_1_1_1/Generated_Edge&Plane_2/Plane_2&Box_1_1/Top"), model.selection("EDGE", "[Partition_1_1_1/Modified_Face&Box_1_1/Top][Partition_1_1_1/Modified_Face&Box_1_1/Left]"), model.selection("EDGE", "[Partition_1_1_1/Modified_Face&Box_1_1/Back][Partition_1_1_1/Modified_Face&Box_1_1/Top]"), model.selection("EDGE", "Partition_1_1_2/Generated_Edge&Plane_1/Plane_1&Box_1_1/Top"), model.selection("EDGE", "Partition_1_1_3/Generated_Edge&Plane_1/Plane_1&Box_1_1/Top"), model.selection("EDGE", "[Partition_1_1_4/Modified_Face&Box_1_1/Top][Partition_1_1_4/Modified_Face&Box_1_1/Front]"), model.selection("EDGE", "[Partition_1_1_4/Modified_Face&Box_1_1/Top][Partition_1_1_4/Modified_Face&Box_1_1/Right]"), model.selection("EDGE", "Partition_1_1_2/Generated_Edge&Plane_2/Plane_2&Box_1_1/Top"), model.selection("EDGE", "[Partition_1_1_2/Modified_Face&Box_1_1/Back][Partition_1_1_2/Modified_Face&Box_1_1/Top]"), model.selection("EDGE", "[Partition_1_1_2/Modified_Face&Box_1_1/Top][Partition_1_1_2/Modified_Face&Box_1_1/Right]")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Group_4_objects = [model.selection("VERTEX", "[Partition_1_1_3/Modified_Face&Box_1_1/Front][Partition_1_1_3/Modified_Face&Box_1_1/Left][Partition_1_1_3/Modified_Face&Box_1_1/Bottom]"), model.selection("VERTEX", "Partition_1_1_4/Generated_Vertex&Plane_1/Plane_1&weak_name_1"), model.selection("VERTEX", "[Partition_1_1_4/Modified_Face&Box_1_1/Front][Partition_1_1_4/Modified_Face&Box_1_1/Bottom][Partition_1_1_4/Modified_Face&Box_1_1/Right]"), model.selection("VERTEX", "Partition_1_1_1/Generated_Vertex&Plane_2/Plane_2&weak_name_1"), model.selection("VERTEX", "[Partition_1_1_2/Modified_Face&Box_1_1/Bottom][Partition_1_1_2/Modified_Face&Plane_1/Plane_1][Partition_1_1_2/Modified_Face&Plane_2/Plane_2]"), model.selection("VERTEX", "Partition_1_1_2/Generated_Vertex&Plane_2/Plane_2&weak_name_1"), model.selection("VERTEX", "[Partition_1_1_1/Modified_Face&Box_1_1/Back][Partition_1_1_1/Modified_Face&Box_1_1/Bottom][Partition_1_1_1/Modified_Face&Box_1_1/Left]"), model.selection("VERTEX", "Partition_1_1_2/Generated_Vertex&Plane_1/Plane_1&weak_name_1"), model.selection("VERTEX", "[Partition_1_1_2/Modified_Face&Box_1_1/Back][Partition_1_1_2/Modified_Face&Box_1_1/Right][Partition_1_1_2/Modified_Face&Box_1_1/Bottom]")]
+Group_4 = model.addGroup(Part_1_doc, Group_4_objects)
+Rotation_1 = model.addRotation(Part_1_doc, [model.selection("COMPSOLID", "Partition_1_1")], model.selection("EDGE", "PartSet/OX"), 45)
+model.end()
+
+num_in_groups = [2, 4, 12, 9]
+moveGroupsAndVerify(Part_1_doc, Rotation_1.feature(), num_in_groups)
+
+model.begin()
+Rotation_2 = model.addRotation(Part_1_doc, [model.selection("COMPSOLID", "Rotation_1_1")], model.selection("VERTEX", "[Rotation_1_1_3/MF:Rotated_Face&Box_1_1/Top][Rotation_1_1_3/MF:Rotated_Face&Box_1_1/Front][Rotation_1_1_3/MF:Rotated_Face&Box_1_1/Left]"), model.selection("VERTEX", "[Rotation_1_1_4/MF:Rotated_Face&Box_1_1/Front][Rotation_1_1_4/MF:Rotated_Face&Box_1_1/Bottom][Rotation_1_1_4/MF:Rotated_Face&Box_1_1/Right]"), model.selection("VERTEX", "[Rotation_1_1_2/MF:Rotated_Face&Box_1_1/Back][Rotation_1_1_2/MF:Rotated_Face&Box_1_1/Right][Rotation_1_1_2/MF:Rotated_Face&Box_1_1/Bottom]"))
+model.end()
+moveGroupsAndVerify(Part_1_doc, Rotation_2.feature(), num_in_groups)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test of deep nested results history. Scale operation.
+# Check the groups of initial boxes moved to the end contain the corresponding
+# results, but divided.
+
+from salome.shaper import model
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+
+def moveGroupsAndVerify(thePart, theLastFeature, theRefNumInGroups):
+ # move groups to the end
+ model.begin()
+ LastFeature = theLastFeature
+ for i in range(thePart.size("Groups")):
+ GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", 0))) # move always the very first group
+ Part_1_doc.moveFeature(GroupFeature, LastFeature)
+ LastFeature = GroupFeature
+ model.end()
+
+ a = 0
+ for i in range(thePart.size("Groups")):
+ GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", i)))
+ assert(aFactory.validate(GroupFeature))
+ assert(GroupFeature.selectionList("group_list").size() == theRefNumInGroups[a])
+ a = a + 1
+
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Right"))
+Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Front"), model.selection("FACE", "Box_1_1/Back"))
+Partition_1_objects = [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Plane_1"), model.selection("FACE", "Plane_2")]
+Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Partition_1_1_3"), model.selection("SOLID", "Partition_1_1_1")])
+Group_2_objects = [model.selection("FACE", "Partition_1_1_4/Modified_Face&Box_1_1/Front"), model.selection("FACE", "Partition_1_1_4/Modified_Face&Box_1_1/Top"), model.selection("FACE", "Partition_1_1_2/Modified_Face&Box_1_1/Top"), model.selection("FACE", "Partition_1_1_2/Modified_Face&Box_1_1/Right")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_3_objects = [model.selection("EDGE", "[Partition_1_1_3/Modified_Face&Box_1_1/Top][Partition_1_1_3/Modified_Face&Box_1_1/Front]"), model.selection("EDGE", "[Partition_1_1_3/Modified_Face&Box_1_1/Top][Partition_1_1_3/Modified_Face&Box_1_1/Left]"), model.selection("EDGE", "Partition_1_1_1/Generated_Edge&Plane_2/Plane_2&Box_1_1/Top"), model.selection("EDGE", "[Partition_1_1_1/Modified_Face&Box_1_1/Top][Partition_1_1_1/Modified_Face&Box_1_1/Left]"), model.selection("EDGE", "[Partition_1_1_1/Modified_Face&Box_1_1/Back][Partition_1_1_1/Modified_Face&Box_1_1/Top]"), model.selection("EDGE", "Partition_1_1_2/Generated_Edge&Plane_1/Plane_1&Box_1_1/Top"), model.selection("EDGE", "Partition_1_1_3/Generated_Edge&Plane_1/Plane_1&Box_1_1/Top"), model.selection("EDGE", "[Partition_1_1_4/Modified_Face&Box_1_1/Top][Partition_1_1_4/Modified_Face&Box_1_1/Front]"), model.selection("EDGE", "[Partition_1_1_4/Modified_Face&Box_1_1/Top][Partition_1_1_4/Modified_Face&Box_1_1/Right]"), model.selection("EDGE", "Partition_1_1_2/Generated_Edge&Plane_2/Plane_2&Box_1_1/Top"), model.selection("EDGE", "[Partition_1_1_2/Modified_Face&Box_1_1/Back][Partition_1_1_2/Modified_Face&Box_1_1/Top]"), model.selection("EDGE", "[Partition_1_1_2/Modified_Face&Box_1_1/Top][Partition_1_1_2/Modified_Face&Box_1_1/Right]")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Group_4_objects = [model.selection("VERTEX", "[Partition_1_1_3/Modified_Face&Box_1_1/Front][Partition_1_1_3/Modified_Face&Box_1_1/Left][Partition_1_1_3/Modified_Face&Box_1_1/Bottom]"), model.selection("VERTEX", "Partition_1_1_4/Generated_Vertex&Plane_1/Plane_1&weak_name_1"), model.selection("VERTEX", "[Partition_1_1_4/Modified_Face&Box_1_1/Front][Partition_1_1_4/Modified_Face&Box_1_1/Bottom][Partition_1_1_4/Modified_Face&Box_1_1/Right]"), model.selection("VERTEX", "Partition_1_1_1/Generated_Vertex&Plane_2/Plane_2&weak_name_1"), model.selection("VERTEX", "[Partition_1_1_2/Modified_Face&Box_1_1/Bottom][Partition_1_1_2/Modified_Face&Plane_1/Plane_1][Partition_1_1_2/Modified_Face&Plane_2/Plane_2]"), model.selection("VERTEX", "Partition_1_1_2/Generated_Vertex&Plane_2/Plane_2&weak_name_1"), model.selection("VERTEX", "[Partition_1_1_1/Modified_Face&Box_1_1/Back][Partition_1_1_1/Modified_Face&Box_1_1/Bottom][Partition_1_1_1/Modified_Face&Box_1_1/Left]"), model.selection("VERTEX", "Partition_1_1_2/Generated_Vertex&Plane_1/Plane_1&weak_name_1"), model.selection("VERTEX", "[Partition_1_1_2/Modified_Face&Box_1_1/Back][Partition_1_1_2/Modified_Face&Box_1_1/Right][Partition_1_1_2/Modified_Face&Box_1_1/Bottom]")]
+Group_4 = model.addGroup(Part_1_doc, Group_4_objects)
+Scale_1 = model.addScale(Part_1_doc, [model.selection("COMPSOLID", "Partition_1_1")] , model.selection("VERTEX", "PartSet/Origin"), 2)
+model.end()
+
+num_in_groups = [2, 4, 12, 9]
+moveGroupsAndVerify(Part_1_doc, Scale_1.feature(), num_in_groups)
+
+model.begin()
+Scale_2 = model.addScale(Part_1_doc, [model.selection("COMPSOLID", "Scale_1_1")] , model.selection("VERTEX", "PartSet/Origin"), 1 , 2, 3)
+model.end()
+moveGroupsAndVerify(Part_1_doc, Scale_2.feature(), num_in_groups)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test of deep nested results history. Placement operation.
+# Check the groups of initial boxes moved to the end contain the corresponding
+# results, but divided.
+
+from salome.shaper import model
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+
+def moveGroupsAndVerify(thePart, theLastFeature, theRefNumInGroups):
+ # move groups to the end
+ model.begin()
+ LastFeature = theLastFeature
+ for i in range(thePart.size("Groups")):
+ GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", 0))) # move always the very first group
+ Part_1_doc.moveFeature(GroupFeature, LastFeature)
+ LastFeature = GroupFeature
+ model.end()
+
+ a = 0
+ for i in range(thePart.size("Groups")):
+ GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", i)))
+ assert(aFactory.validate(GroupFeature))
+ assert(GroupFeature.selectionList("group_list").size() == theRefNumInGroups[a])
+ a = a + 1
+
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Right"))
+Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Back"), model.selection("FACE", "Box_1_1/Front"))
+Partition_1_objects = [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Plane_1"), model.selection("FACE", "Plane_2")]
+Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Partition_1_1_3"), model.selection("SOLID", "Partition_1_1_1")])
+Group_2_objects = [model.selection("FACE", "Partition_1_1_4/Modified_Face&Box_1_1/Front"), model.selection("FACE", "Partition_1_1_4/Modified_Face&Box_1_1/Top"), model.selection("FACE", "Partition_1_1_2/Modified_Face&Box_1_1/Top"), model.selection("FACE", "Partition_1_1_2/Modified_Face&Box_1_1/Right")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_3_objects = [model.selection("EDGE", "[Partition_1_1_3/Modified_Face&Box_1_1/Top][Partition_1_1_3/Modified_Face&Box_1_1/Front]"), model.selection("EDGE", "[Partition_1_1_3/Modified_Face&Box_1_1/Top][Partition_1_1_3/Modified_Face&Box_1_1/Left]"), model.selection("EDGE", "Partition_1_1_1/Generated_Edge&Plane_2/Plane_2&Box_1_1/Top"), model.selection("EDGE", "[Partition_1_1_1/Modified_Face&Box_1_1/Top][Partition_1_1_1/Modified_Face&Box_1_1/Left]"), model.selection("EDGE", "[Partition_1_1_1/Modified_Face&Box_1_1/Back][Partition_1_1_1/Modified_Face&Box_1_1/Top]"), model.selection("EDGE", "Partition_1_1_2/Generated_Edge&Plane_1/Plane_1&Box_1_1/Top"), model.selection("EDGE", "Partition_1_1_3/Generated_Edge&Plane_1/Plane_1&Box_1_1/Top"), model.selection("EDGE", "[Partition_1_1_4/Modified_Face&Box_1_1/Top][Partition_1_1_4/Modified_Face&Box_1_1/Front]"), model.selection("EDGE", "[Partition_1_1_4/Modified_Face&Box_1_1/Top][Partition_1_1_4/Modified_Face&Box_1_1/Right]"), model.selection("EDGE", "Partition_1_1_2/Generated_Edge&Plane_2/Plane_2&Box_1_1/Top"), model.selection("EDGE", "[Partition_1_1_2/Modified_Face&Box_1_1/Back][Partition_1_1_2/Modified_Face&Box_1_1/Top]"), model.selection("EDGE", "[Partition_1_1_2/Modified_Face&Box_1_1/Top][Partition_1_1_2/Modified_Face&Box_1_1/Right]")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Group_4_objects = [model.selection("VERTEX", "[Partition_1_1_3/Modified_Face&Box_1_1/Front][Partition_1_1_3/Modified_Face&Box_1_1/Left][Partition_1_1_3/Modified_Face&Box_1_1/Bottom]"), model.selection("VERTEX", "Partition_1_1_4/Generated_Vertex&Plane_1/Plane_1&weak_name_1"), model.selection("VERTEX", "[Partition_1_1_4/Modified_Face&Box_1_1/Front][Partition_1_1_4/Modified_Face&Box_1_1/Bottom][Partition_1_1_4/Modified_Face&Box_1_1/Right]"), model.selection("VERTEX", "Partition_1_1_1/Generated_Vertex&Plane_2/Plane_2&weak_name_1"), model.selection("VERTEX", "[Partition_1_1_2/Modified_Face&Box_1_1/Bottom][Partition_1_1_2/Modified_Face&Plane_1/Plane_1][Partition_1_1_2/Modified_Face&Plane_2/Plane_2]"), model.selection("VERTEX", "Partition_1_1_2/Generated_Vertex&Plane_2/Plane_2&weak_name_1"), model.selection("VERTEX", "[Partition_1_1_1/Modified_Face&Box_1_1/Back][Partition_1_1_1/Modified_Face&Box_1_1/Bottom][Partition_1_1_1/Modified_Face&Box_1_1/Left]"), model.selection("VERTEX", "Partition_1_1_2/Generated_Vertex&Plane_1/Plane_1&weak_name_1"), model.selection("VERTEX", "[Partition_1_1_2/Modified_Face&Box_1_1/Back][Partition_1_1_2/Modified_Face&Box_1_1/Right][Partition_1_1_2/Modified_Face&Box_1_1/Bottom]")]
+Group_4 = model.addGroup(Part_1_doc, Group_4_objects)
+Placement_1 = model.addPlacement(Part_1_doc, [model.selection("COMPSOLID", "Partition_1_1")], model.selection("FACE", "Partition_1_1_4/Modified_Face&Box_1_1/Bottom"), model.selection("FACE", "Partition_1_1_1/Modified_Face&Box_1_1/Top"), False, True)
+model.do()
+model.end()
+
+num_in_groups = [2, 4, 12, 9]
+moveGroupsAndVerify(Part_1_doc, Placement_1.feature(), num_in_groups)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test of deep nested results history. Compsolid operation.
+# Check the initial groups moved to the end contain the corresponding results.
+
+from salome.shaper import model
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+
+def moveGroupsAndVerify(thePart, theLastFeature, theRefNumInGroups):
+ # move groups to the end
+ model.begin()
+ LastFeature = theLastFeature
+ for i in range(thePart.size("Groups")):
+ GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", 0))) # move always the very first group
+ Part_1_doc.moveFeature(GroupFeature, LastFeature)
+ LastFeature = GroupFeature
+ model.end()
+
+ a = 0
+ for i in range(thePart.size("Groups")):
+ GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", i)))
+ assert(aFactory.validate(GroupFeature))
+ assert(GroupFeature.selectionList("group_list").size() == theRefNumInGroups[a])
+ a = a + 1
+
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Box_1_1")])
+Group_2_objects = [model.selection("FACE", "Box_1_1/Back"), model.selection("FACE", "Box_1_1/Top"), model.selection("FACE", "Box_1_1/Right"), model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Front")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_3_objects = [model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Group_4_objects = [model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Bottom]")]
+Group_4 = model.addGroup(Part_1_doc, Group_4_objects)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Top"))
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchCircle_1 = Sketch_1.addCircle(3.528942405489753, -5.938455554641368, 11.4411217503133)
+model.do()
+CompSolid_1 = model.addCompSolid(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r")])
+model.do()
+model.end()
+
+num_in_groups = [2, 10, 16, 8]
+moveGroupsAndVerify(Part_1_doc, CompSolid_1.feature(), num_in_groups)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test of deep nested results history. Solid operation.
+# Check the initial groups moved to the end contain the corresponding results.
+
+from salome.shaper import model
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+
+def moveGroupsAndVerify(thePart, theLastFeature, theRefNumInGroups):
+ # move groups to the end
+ model.begin()
+ LastFeature = theLastFeature
+ for i in range(thePart.size("Groups")):
+ GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", 0))) # move always the very first group
+ Part_1_doc.moveFeature(GroupFeature, LastFeature)
+ LastFeature = GroupFeature
+ model.end()
+
+ a = 0
+ for i in range(thePart.size("Groups")):
+ GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", i)))
+ assert(aFactory.validate(GroupFeature))
+ assert(GroupFeature.selectionList("group_list").size() == theRefNumInGroups[a])
+ a = a + 1
+
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Box_1_1")])
+Group_2_objects = [model.selection("FACE", "Box_1_1/Back"), model.selection("FACE", "Box_1_1/Top"), model.selection("FACE", "Box_1_1/Right"), model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Front")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_3_objects = [model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Group_4_objects = [model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Bottom]")]
+Group_4 = model.addGroup(Part_1_doc, Group_4_objects)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Top"))
+Sketch_1 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchCircle_1 = Sketch_1.addCircle(3.528942405489753, -5.938455554641368, 11.4411217503133)
+model.do()
+Solid_1_objects = [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r"), model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Front"), model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Back"), model.selection("FACE", "Box_1_1/Right")]
+Solid_1 = model.addSolid(Part_1_doc, Solid_1_objects)
+model.do()
+model.end()
+
+num_in_groups = [1, 5, 8, 4]
+moveGroupsAndVerify(Part_1_doc, Solid_1.feature(), num_in_groups)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test of deep nested results history. Shell operation.
+# Check the initial groups moved to the end contain the corresponding results.
+
+from salome.shaper import model
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+
+def moveGroupsAndVerify(thePart, theLastFeature, theRefNumInGroups):
+ # move groups to the end
+ model.begin()
+ LastFeature = theLastFeature
+ for i in range(thePart.size("Groups")):
+ GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", 0))) # move always the very first group
+ Part_1_doc.moveFeature(GroupFeature, LastFeature)
+ LastFeature = GroupFeature
+ model.end()
+
+ a = 0
+ for i in range(thePart.size("Groups")):
+ GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", i)))
+ assert(aFactory.validate(GroupFeature))
+ assert(GroupFeature.selectionList("group_list").size() == theRefNumInGroups[a])
+ a = a + 1
+
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Group_1_objects = [model.selection("FACE", "Box_1_1/Back"), model.selection("FACE", "Box_1_1/Top"), model.selection("FACE", "Box_1_1/Right"), model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Bottom"), model.selection("FACE", "Box_1_1/Front")]
+Group_1 = model.addGroup(Part_1_doc, Group_1_objects)
+Group_2_objects = [model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Back][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Left][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Right][Box_1_1/Top]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Bottom]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Left]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Right]"), model.selection("EDGE", "[Box_1_1/Front][Box_1_1/Top]")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_3_objects = [model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Right][Box_1_1/Bottom]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Bottom]")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Left"), model.selection("FACE", "Box_1_1/Right"))
+Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Front"), model.selection("FACE", "Box_1_1/Back"))
+Partition_1_objects = [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Plane_1"), model.selection("FACE", "Plane_2")]
+Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects)
+Shell_1_objects = [model.selection("FACE", "Partition_1_1_1/Modified_Face&Box_1_1/Back"), model.selection("FACE", "Partition_1_1_1/Modified_Face&Box_1_1/Left"), model.selection("FACE", "Partition_1_1_1/Modified_Face&Box_1_1/Top"), model.selection("FACE", "Partition_1_1_2/Modified_Face&Box_1_1/Back"), model.selection("FACE", "Partition_1_1_4/Modified_Face&Box_1_1/Front"), model.selection("FACE", "Partition_1_1_4/Modified_Face&Box_1_1/Right")]
+Shell_1 = model.addShell(Part_1_doc, Shell_1_objects)
+model.do()
+model.end()
+
+num_in_groups = [6, 13, 6]
+moveGroupsAndVerify(Part_1_doc, Shell_1.feature(), num_in_groups)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test of deep nested results history. Shell operation.
+# Check the initial groups moved to the end contain the corresponding results.
+
+from salome.shaper import model
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+
+def moveGroupsAndVerify(thePart, theLastFeature, theRefNumInGroups):
+ # move groups to the end
+ model.begin()
+ LastFeature = theLastFeature
+ for i in range(thePart.size("Groups")):
+ GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", 0))) # move always the very first group
+ Part_1_doc.moveFeature(GroupFeature, LastFeature)
+ LastFeature = GroupFeature
+ model.end()
+
+ a = 0
+ for i in range(thePart.size("Groups")):
+ GroupFeature = thePart.feature(objectToResult(thePart.object("Groups", i)))
+ assert(aFactory.validate(GroupFeature))
+ assert(GroupFeature.selectionList("group_list").size() == theRefNumInGroups[a])
+ a = a + 1
+
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(37.25033050129738, -29.31988879634488, -32.3129114537045, -29.31988879634488)
+SketchLine_2 = Sketch_1.addLine(-32.3129114537045, -29.31988879634488, -32.3129114537045, 42.23870159689701)
+SketchLine_3 = Sketch_1.addLine(-32.3129114537045, 42.23870159689701, 37.25033050129738, 42.23870159689701)
+SketchLine_4 = Sketch_1.addLine(37.25033050129738, 42.23870159689701, 37.25033050129738, -29.31988879634488)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+model.do()
+Edge_1_objects = [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_4"), model.selection("EDGE", "Sketch_1/SketchLine_2"), model.selection("EDGE", "Sketch_1/SketchLine_3")]
+Edge_1 = model.addEdge(Part_1_doc, Edge_1_objects)
+Group_1_objects = [model.selection("EDGE", "Edge_1_1"), model.selection("EDGE", "Edge_1_3"), model.selection("EDGE", "Edge_1_4"), model.selection("EDGE", "Edge_1_2")]
+Group_1 = model.addGroup(Part_1_doc, Group_1_objects)
+Group_2_objects = [model.selection("VERTEX", "Edge_1_1/Modified_Vertex&Sketch_1/SketchLine_1_StartVertex"), model.selection("VERTEX", "Edge_1_2/Modified_Vertex&Sketch_1/SketchLine_4_EndVertex"), model.selection("VERTEX", "Edge_1_1/Modified_Vertex&Sketch_1/SketchLine_1_EndVertex"), model.selection("VERTEX", "Edge_1_3/Modified_Vertex&Sketch_1/SketchLine_2_StartVertex"), model.selection("VERTEX", "Edge_1_4/Modified_Vertex&Sketch_1/SketchLine_3_EndVertex"), model.selection("VERTEX", "Edge_1_2/Modified_Vertex&Sketch_1/SketchLine_4_StartVertex"), model.selection("VERTEX", "Edge_1_3/Modified_Vertex&Sketch_1/SketchLine_2_EndVertex"), model.selection("VERTEX", "Edge_1_4/Modified_Vertex&Sketch_1/SketchLine_3_StartVertex")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Face_1_objects = [model.selection("EDGE", "Edge_1_1"), model.selection("EDGE", "Edge_1_2"), model.selection("EDGE", "Edge_1_3"), model.selection("EDGE", "Edge_1_4")]
+Face_1 = model.addFace(Part_1_doc, Face_1_objects)
+model.do()
+model.end()
+
+num_in_groups = [4, 8]
+moveGroupsAndVerify(Part_1_doc, Face_1.feature(), num_in_groups)
+
+assert(model.checkPythonDump())
+++ /dev/null
-# Copyright (C) 2014-2019 CEA/DEN, EDF R&D
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-#
-
-# Test that removed vertex, selected in the group makes group with one invalid element (empty shape)
-
-from salome.shaper import model
-from ModelAPI import *
-
-model.begin()
-partSet = model.moduleDocument()
-Part_1 = model.addPart(partSet)
-Part_1_doc = Part_1.document()
-Box_1 = model.addBox(Part_1_doc, 10, 10, 20)
-Plane_4 = model.addPlane(Part_1_doc, model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Right][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Front][Box_1_1/Left][Box_1_1/Top]"), model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Bottom]"))
-Group_1 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "[Box_1_1/Back][Box_1_1/Left][Box_1_1/Top]")])
-Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Plane_1")])
-Remove_SubShapes_1 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPSOLID", "Partition_1_1"))
-Remove_SubShapes_1.setSubShapesToKeep([model.selection("SOLID", "Partition_1_1_2")])
-model.do()
-# move group
-Part_1_doc.moveFeature(Group_1.feature(), Remove_SubShapes_1.feature())
-model.end()
-
-# Check group
-aFactory = ModelAPI_Session.get().validators()
-selectionList = Group_1.feature().selectionList("group_list")
-assert(selectionList.size() == 1)
-assert(aFactory.validate(Group_1.feature()) == False)
+++ /dev/null
-# Copyright (C) 2014-2019 CEA/DEN, EDF R&D
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#
-# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-#
-
-# Test that partition divides cylinder into 4 faces, there is no edges in a group moved to the end
-# Based on the CEA report mail 04.12.2018, page 2
-
-from SketchAPI import *
-
-from ModelAPI import *
-from GeomAPI import *
-from salome.shaper import model
-
-model.begin()
-partSet = model.moduleDocument()
-Part_1 = model.addPart(partSet)
-Part_1_doc = Part_1.document()
-Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
-SketchArc_1 = Sketch_1.addArc(-1.103476974288834e-12, 24.99999999999979, 24.49489742783218, 30, 0, 50, False)
-SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OZ"), False)
-SketchLine_1 = SketchProjection_1.createdFeature()
-SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.result())
-SketchLine_2 = Sketch_1.addLine(0, 50, -10, 50)
-SketchLine_2.setAuxiliary(True)
-SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_2.startPoint())
-SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_2.result())
-SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_1.results()[1], SketchLine_2.result())
-SketchLine_3 = Sketch_1.addLine(24.49489742783218, 30, 24.49489742783218, 5)
-SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_3.startPoint())
-SketchLine_4 = Sketch_1.addLine(24.49489742783218, 5, 34.49489742783218, 5)
-SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
-SketchLine_5 = Sketch_1.addLine(34.49489742783218, 5, 34.49489742783218, 0)
-SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
-SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
-SketchLine_6 = SketchProjection_2.createdFeature()
-SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.result())
-SketchLine_7 = Sketch_1.addLine(34.49489742783218, 0, 0, 0)
-SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_7.startPoint())
-SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_7.endPoint())
-SketchLine_8 = Sketch_1.addLine(0, 50, 0, 0)
-SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_8.startPoint())
-SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_8.endPoint())
-SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_4.result())
-SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_3.result())
-SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_5.result())
-SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_4.result(), 10)
-SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_5.result(), 5)
-SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_3.result(), 25)
-SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_8.result(), 50)
-SketchConstraintLength_5 = Sketch_1.setLength(SketchLine_2.result(), 10)
-SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 25)
-model.do()
-Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchArc_1_2r-SketchLine_8f-SketchLine_7r-SketchLine_5r-SketchLine_4r-SketchLine_3r")], model.selection("EDGE", "PartSet/OZ"), 360, 0)
-Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Revolution_1_1/Generated_Face&Sketch_1/SketchLine_3")])
-Partition_1_objects = [model.selection("SOLID", "Revolution_1_1"), model.selection("FACE", "PartSet/XOZ"), model.selection("FACE", "PartSet/YOZ")]
-Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects)
-model.do()
-
-# move group
-Part_1_doc.moveFeature(Group_1.feature(), Partition_1.feature())
-model.end()
-
-# Check group: result must be four faces
-aFactory = ModelAPI_Session.get().validators()
-selectionList = Group_1.feature().selectionList("group_list")
-assert(selectionList.size() == 4)
-assert(aFactory.validate(Group_1.feature()))
-for i in range(4):
- assert(Group_1.groupList().value(i).value().shapeType() == GeomAPI_Shape.FACE)
-
-assert(model.checkPythonDump())
TestBooleanCut_WireCompound_WireCompound.py
TestBooleanCut_Compound_Solid.py
TestBooleanCut_ErrorMsg.py
+ TestBooleanCut_SolidsHistory.py
TestBooleanSmash_Face_Face.py
TestBooleanSmash_SubSolid_Solid.py
TestBooleanSmash_CompSolid_Solid.py
TestBooleanSmash_ErrorMsg.py
+ TestBooleanSmash_SolidsHistory.py
TestBooleanFuse_SimpleMode.py
TestBooleanFuse_RemoveEdges.py
TestBooleanFuse_ErrorMsg.py
TestBooleanCommon_CompSolidCompound_Shell.py
TestBooleanCommon_CompSolidCompound_CompSolidCompound.py
TestBooleanCommon_ErrorMsg.py
+ TestBooleanCommon_SolidsHistory.py
Test2596.py
Test2592.py
Test2588.py
TestPartitionSubCompsolidWithPlane4.py
TestPartitionSubCompsolidWithPlane5.py
TestPartitionArgsUpdate.py
+ TestPartition_SolidsHistory.py
TestBooleanFuse_Vertex_Vertex.py
TestBooleanFuse_VertexCompound_VertexCompound.py
TestBooleanFuse_Edge_Edge.py
TestBooleanFuse_CompSolid_Face.py
TestBooleanFuse_CompSolid_CompSolid.py
TestBooleanFuse_CompSolidCompound_CompSolidCompound.py
+ TestBooleanFuse_SolidsHistory.py
TestFillet.py
TestFillet1.py
TestFillet_ErrorMsg.py
+ TestFillet_History.py
TestScale1.py
TestScale2.py
Test1816.py
+ Test1876.py
Test2631.py
+ Test2636.py
Test2650.py
Test2681.py
Test2686.py
Test2692.py
Test2617.py
Test2729.py
+ Test2738.py
Test2751.py
+ Test2826.py
Test2854.py
)
std::shared_ptr<ModelAPI_ResultBody> aResultBody =
document()->createBody(data(), aResultIndex);
- GeomShapePtr aBaseShape = anObjects.front();
- anObjects.pop_front();
+ ListOfShape anEmptyTools;
FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
- aBaseShape,
anObjects,
+ anEmptyTools,
aMakeShapeList,
aShape);
+ GeomShapePtr aBaseShape = anObjects.front();
+ anObjects.pop_front();
setResult(aResultBody, aResultIndex);
aResultIndex++;
if (aShapeIt.more() || aResShape->shapeType() == GeomAPI_Shape::VERTEX) {
std::shared_ptr<ModelAPI_ResultBody> aResultBody =
document()->createBody(data(), aResultIndex);
-
+ ListOfShape anObjectList;
+ anObjectList.push_back(anObject);
FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
- anObject,
+ anObjectList,
aTools,
aMakeShapeList,
aResShape);
std::shared_ptr<ModelAPI_ResultBody> aResultBody =
document()->createBody(data(), aResultIndex);
+ ListOfShape aCompSolidList;
+ aCompSolidList.push_back(aCompSolid);
FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
- aCompSolid,
+ aCompSolidList,
aTools,
aMakeShapeList,
aResultShape);
std::shared_ptr<ModelAPI_ResultBody> aResultBody =
document()->createBody(data(), aResultIndex);
+ ListOfShape aCompoundList;
+ aCompoundList.push_back(aCompound);
FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
- aCompound,
+ aCompoundList,
aTools,
aMakeShapeList,
aResultShape);
std::shared_ptr<ModelAPI_ResultBody> aResultBody =
document()->createBody(data(), aResultIndex);
+ ListOfShape anObjectList;
+ anObjectList.push_back(anObject);
FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
- anObject,
+ anObjectList,
aTools,
aMakeShapeList,
aResShape);
std::shared_ptr<ModelAPI_ResultBody> aResultBody =
document()->createBody(data(), aResultIndex);
+ ListOfShape anObjectList;
+ anObjectList.push_back(aCompSolid);
FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
- aCompSolid,
+ anObjectList,
aTools,
aMakeShapeList,
aResultShape);
std::shared_ptr<ModelAPI_ResultBody> aResultBody =
document()->createBody(data(), aResultIndex);
+ ListOfShape anObjectList;
+ anObjectList.push_back(aCompound);
FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
- aCompound,
+ anObjectList,
aTools,
aMakeShapeList,
aResultShape);
//
#include "FeaturesPlugin_BooleanFill.h"
+#include "FeaturesPlugin_Tools.h"
#include <ModelAPI_ResultBody.h>
#include <ModelAPI_AttributeSelectionList.h>
#include <ModelAPI_Tools.h>
#include <GeomAlgoAPI_Boolean.h>
+#include <GeomAlgoAPI_CompoundBuilder.h>
#include <GeomAlgoAPI_MakeShapeCustom.h>
#include <GeomAlgoAPI_MakeShapeList.h>
#include <GeomAlgoAPI_Partition.h>
return;
}
+ std::vector<FeaturesPlugin_Tools::ResultBaseAlgo> aResultBaseAlgoList;
+ ListOfShape aResultShapesList;
+
// For solids cut each object with all tools.
for(ListOfShape::iterator
anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) {
std::shared_ptr<ModelAPI_ResultBody> aResultBody =
document()->createBody(data(), aResultIndex);
+ // tools should be added to the list to fulfill the correct history of modification
+ aListWithObject.insert(aListWithObject.end(), aTools.begin(), aTools.end());
+
ListOfShape aUsedTools = aTools;
aUsedTools.insert(aUsedTools.end(), aPlanes.begin(), aPlanes.end());
- loadNamingDS(aResultBody, anObject, aUsedTools, aResShape, aMakeShapeList);
+ FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aListWithObject, aUsedTools,
+ aMakeShapeList, aResShape);
setResult(aResultBody, aResultIndex);
aResultIndex++;
+
+ FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
+ aRBA.resultBody = aResultBody;
+ aRBA.baseShape = anObject;
+ aRBA.makeShape = aMakeShapeList;
+ aResultBaseAlgoList.push_back(aRBA);
+ aResultShapesList.push_back(aResShape);
}
// Compsolids handling
ListOfShape aUsedTools = aTools;
aUsedTools.insert(aUsedTools.end(), aPlanes.begin(), aPlanes.end());
- loadNamingDS(aResultBody,
- aCompSolid,
- aUsedTools,
- aResultShape,
- aMakeShapeList);
+ ListOfShape aBaseShapes;
+ aBaseShapes.push_back(aCompSolid);
+ // tools should be added to the list to fulfill the correct history of modification
+ aBaseShapes.insert(aBaseShapes.end(), aTools.begin(), aTools.end());
+
+ FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapes, aUsedTools,
+ aMakeShapeList, aResultShape);
setResult(aResultBody, aResultIndex);
aResultIndex++;
+
+ FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
+ aRBA.resultBody = aResultBody;
+ aRBA.baseShape = aCompSolid;
+ aRBA.makeShape = aMakeShapeList;
+ aResultBaseAlgoList.push_back(aRBA);
+ aResultShapesList.push_back(aResultShape);
}
+ // Store deleted shapes after all results has been proceeded. This is to avoid issue when in one
+ // result shape has been deleted, but in another it was modified or stayed.
+ GeomShapePtr aResultShapesCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList);
+ FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList, aTools, aResultShapesCompound);
+
// remove the rest results if there were produced in the previous pass
removeResults(aResultIndex);
}
int aResultIndex = 0;
- GeomShapePtr aBackShape = anOriginalShapes.back();
- anOriginalShapes.pop_back();
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+ ListOfShape anEmptyTools;
FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
- aBackShape,
anOriginalShapes,
+ anEmptyTools,
aMakeShapeList,
aShape);
setResult(aResultBody, aResultIndex);
aResultIndex++;
FeaturesPlugin_Tools::loadDeletedShapes(aResultBody,
- aBackShape,
+ GeomShapePtr(),
anOriginalShapes,
aMakeShapeList,
aShape);
aMakeShapeList->appendAlgo(aFillerAlgo);
}
- std::shared_ptr<GeomAPI_Shape> aFrontShape = anOriginalShapes.front();
- anOriginalShapes.pop_front();
std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
- aFrontShape,
+ anOriginalShapes,
anOriginalShapes,
aMakeShapeList,
aShape);
aResultIndex++;
FeaturesPlugin_Tools::loadDeletedShapes(aResultBody,
- aFrontShape,
+ GeomShapePtr(),
anOriginalShapes,
aMakeShapeList,
aShape);
//
#include "FeaturesPlugin_Fillet.h"
+#include "FeaturesPlugin_Tools.h"
#include <ModelAPI_Data.h>
#include <ModelAPI_AttributeDouble.h>
#include <ModelAPI_Tools.h>
#include <ModelAPI_Validator.h>
+#include <GeomAlgoAPI_CompoundBuilder.h>
#include <GeomAlgoAPI_Fillet.h>
#include <GeomAlgoAPI_MakeShapeList.h>
#include <GeomAlgoAPI_Tools.h>
return anEdges;
}
-// If theShape is a compound of single shape, return it
+// If theShape is a compound of a single sub-shape, return this sub-shape
static GeomShapePtr unwrapCompound(const GeomShapePtr& theShape)
{
GeomShapePtr aShape = theShape;
if (!aCreationMethod)
return;
- GeomAPI_DataMapOfShapeMapOfShapes aSolidsAndSubs;
+ std::list<std::pair<GeomShapePtr, ListOfShape> > aSolidsAndSubs;
- // getting objects and sort them accroding to parent solids
+ // getting objects and sort them according to parent solids
AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECT_LIST_ID());
for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); ++anObjectsIndex) {
AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anObjectsIndex);
if (!aParent)
return;
+ // searching this parent is already in the list aSolidsAndSubs
+ std::list<std::pair<GeomShapePtr, ListOfShape> >::iterator aSearch = aSolidsAndSubs.begin();
+ ListOfShape* aFound;
+ for(; aSearch != aSolidsAndSubs.end(); aSearch++) {
+ if (aSearch->first->isSame(aParent)) {
+ aFound = &(aSearch->second);
+ break;
+ }
+ }
+ if (aSearch == aSolidsAndSubs.end()) { // not found, so, add a new one
+ aSolidsAndSubs.push_back(std::pair<GeomShapePtr, ListOfShape>(aParent, ListOfShape()));
+ aFound = &(aSolidsAndSubs.back().second);
+ }
+
ListOfShape anEdgesAndVertices;
collectSubs(anObject, anEdgesAndVertices, GeomAPI_Shape::EDGE);
collectSubs(anObject, anEdgesAndVertices, GeomAPI_Shape::VERTEX);
for (ListOfShape::iterator aEIt = anEdgesAndVertices.begin();
aEIt != anEdgesAndVertices.end(); ++aEIt)
- aSolidsAndSubs.add(aParent, *aEIt);
+ aFound->push_back(*aEIt);
}
bool isFixedRadius = true;
int aResultIndex = 0;
std::string anError;
- GeomAPI_DataMapOfShapeMapOfShapes::iterator anIt = aSolidsAndSubs.begin();
+ std::vector<FeaturesPlugin_Tools::ResultBaseAlgo> aResultBaseAlgoList;
+ ListOfShape anOriginalShapesList, aResultShapesList;
+
+ std::list<std::pair<GeomShapePtr, ListOfShape> >::iterator anIt = aSolidsAndSubs.begin();
for (; anIt != aSolidsAndSubs.end(); ++anIt) {
- GeomShapePtr aSolid = anIt.first();
- ListOfShape aFilletEdgesAndVertices = anIt.second();
+ GeomShapePtr aSolid = anIt->first;
+ ListOfShape aFilletEdgesAndVertices = anIt->second;
ListOfShape aFilletEdges = selectEdges(aFilletEdgesAndVertices);
if (isFixedRadius)
std::shared_ptr<ModelAPI_ResultBody> aResultBody =
document()->createBody(data(), aResultIndex);
- loadNamingDS(aResultBody, aSolid, aResult, aFilletBuilder);
+ ListOfShape aBaseShapes;
+ aBaseShapes.push_back(aSolid);
+ FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapes, ListOfShape(),
+ aFilletBuilder, aResult, "Fillet");
+
setResult(aResultBody, aResultIndex);
aResultIndex++;
- }
- removeResults(aResultIndex);
-}
-void FeaturesPlugin_Fillet::loadNamingDS(
- std::shared_ptr<ModelAPI_ResultBody> theResultBody,
- const std::shared_ptr<GeomAPI_Shape> theBaseShape,
- const std::shared_ptr<GeomAPI_Shape> theResultShape,
- const std::shared_ptr<GeomAlgoAPI_MakeShape>& theMakeShape)
-{
- //load result
- if(theBaseShape->isEqual(theResultShape)) {
- theResultBody->store(theResultShape, false);
- return;
+ FeaturesPlugin_Tools::ResultBaseAlgo aRBA;
+ aRBA.resultBody = aResultBody;
+ aRBA.baseShape = aSolid;
+ aRBA.makeShape = aFilletBuilder;
+ aResultBaseAlgoList.push_back(aRBA);
+ aResultShapesList.push_back(aResult);
+ anOriginalShapesList.push_back(aSolid);
+
+ const std::string aFilletFaceName = "Fillet";
+ ListOfShape::iterator aSelectedBase = aFilletEdges.begin();
+ for(; aSelectedBase != aFilletEdges.end(); aSelectedBase++) {
+ GeomShapePtr aBase = *aSelectedBase;
+ // Store new faces generated from edges and vertices
+ aResultBody->loadGeneratedShapes(
+ aFilletBuilder, aBase, GeomAPI_Shape::EDGE, aFilletFaceName, true);
+ }
}
- theResultBody->storeModified(theBaseShape, theResultShape);
+ // Store deleted shapes after all results has been proceeded. This is to avoid issue when in one
+ // result shape has been deleted, but in another it was modified or stayed.
+ GeomShapePtr aResultShapesCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList);
+ FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList,
+ anOriginalShapesList, aResultShapesCompound);
- const std::string aFilletFaceName = "Fillet_Face";
-
- // Store modified faces
- theResultBody->loadModifiedShapes(theMakeShape, theBaseShape, GeomAPI_Shape::FACE);
-
- // Store new faces generated from edges and vertices
- theResultBody->loadGeneratedShapes(theMakeShape,
- theBaseShape,
- GeomAPI_Shape::EDGE,
- aFilletFaceName);
- theResultBody->loadGeneratedShapes(theMakeShape,
- theBaseShape,
- GeomAPI_Shape::VERTEX,
- aFilletFaceName);
-
- // Deleted shapes
- theResultBody->loadDeletedShapes(theMakeShape, theBaseShape, GeomAPI_Shape::EDGE);
- theResultBody->loadDeletedShapes(theMakeShape, theBaseShape, GeomAPI_Shape::FACE);
+ removeResults(aResultIndex);
}
//
#include "FeaturesPlugin_FusionFaces.h"
+#include "FeaturesPlugin_Tools.h"
#include <ModelAPI_AttributeSelectionList.h>
#include <ModelAPI_AttributeString.h>
// Store result
GeomShapePtr aResultShape = anAlgo->shape();
ResultBodyPtr aResultBody = document()->createBody(data());
- if (aResultShape->isEqual(aBaseShape)) {
- aResultBody->store(aResultShape);
- } else {
- aResultBody->storeModified(aBaseShape, aResultShape);
- aResultBody->loadModifiedShapes(anAlgo, aBaseShape, GeomAPI_Shape::EDGE);
- aResultBody->loadModifiedShapes(anAlgo, aBaseShape, GeomAPI_Shape::FACE);
- }
+ ListOfShape aBaseShapesList;
+ aBaseShapesList.push_back(aBaseShape);
+ FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapesList, ListOfShape(),
+ anAlgo, aResultShape);
setResult(aResultBody);
}
setResult(aResultBody, aResultIndex);
aResultIndex++;
-
// remove the rest results if there were produced in the previous pass
removeResults(aResultIndex);
}
return;
}
- theResultBody->storeModified(theObjects.front(), aResultShape);
+ theResultBody->storeModified(theObjects, aResultShape, theMakeShape);
const int aShapeTypesNb = 3;
const GeomAPI_Shape::ShapeType aShapeTypes[aShapeTypesNb] = {GeomAPI_Shape::VERTEX,
// Author: Clarisse Genrault (CEA)
#include <FeaturesPlugin_MultiRotation.h>
+#include <FeaturesPlugin_Tools.h>
#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAlgoAPI_MakeShapeList.h>
#include <GeomAlgoAPI_ShapeTools.h>
#include <GeomAlgoAPI_Tools.h>
#include <GeomAlgoAPI_Translation.h>
} else {
std::string anError;
ListOfShape aListOfShape;
- std::list<std::shared_ptr<GeomAlgoAPI_Rotation> > aListOfRotationAlgo;
+ std::shared_ptr<GeomAlgoAPI_MakeShapeList>
+ aListOfRotationAlgo(new GeomAlgoAPI_MakeShapeList);
for (int i=0; i<nbCopies; i++) {
std::shared_ptr<GeomAlgoAPI_Rotation> aRotationnAlgo(
break;
}
aListOfShape.push_back(aRotationnAlgo->shape());
- aListOfRotationAlgo.push_back(aRotationnAlgo);
+ aListOfRotationAlgo->appendAlgo(aRotationnAlgo);
}
std::shared_ptr<GeomAPI_Shape> aCompound =
GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
- aResultBody->storeModified(aBaseShape, aCompound);
- loadNamingDS(aListOfRotationAlgo, aResultBody, aBaseShape);
+
+ ListOfShape aBaseShapes;
+ aBaseShapes.push_back(aBaseShape);
+ FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapes, ListOfShape(),
+ aListOfRotationAlgo, aCompound, "Rotated");
setResult(aResultBody, aResultIndex);
}
}
}
#endif
-
-//=================================================================================================
-void FeaturesPlugin_MultiRotation::loadNamingDS(
- std::list<std::shared_ptr<GeomAlgoAPI_Rotation> > theListOfRotationAlgo,
- std::shared_ptr<ModelAPI_ResultBody> theResultBody,
- std::shared_ptr<GeomAPI_Shape> theBaseShape)
-{
- for (std::list<std::shared_ptr<GeomAlgoAPI_Rotation> >::const_iterator anIt =
- theListOfRotationAlgo.begin(); anIt != theListOfRotationAlgo.cend(); ++anIt) {
- // naming of faces
- theResultBody->loadModifiedShapes(*anIt, theBaseShape, GeomAPI_Shape::FACE, "Rotated_Face");
-
- // naming of edges
- theResultBody->loadModifiedShapes(*anIt, theBaseShape, GeomAPI_Shape::EDGE, "Rotated_Edge");
-
- // naming of vertex
- theResultBody->loadModifiedShapes(*anIt, theBaseShape, GeomAPI_Shape::VERTEX, "Rotated_Vertex");
- }
-}
std::shared_ptr<ModelAPI_ResultBody> theResultBody,
std::shared_ptr<GeomAPI_Shape> theBaseShape, int nb);
#endif
-
- void loadNamingDS(std::list<std::shared_ptr<GeomAlgoAPI_Rotation> > theListOfRotationAlgo,
- std::shared_ptr<ModelAPI_ResultBody> theResultBody,
- std::shared_ptr<GeomAPI_Shape> theBaseShape);
};
#endif // FEATURESPLUGIN_MULTIROTATION_H_
//
#include <FeaturesPlugin_MultiTranslation.h>
+#include <FeaturesPlugin_Tools.h>
#include <GeomAlgoAPI_CompoundBuilder.h>
+#include <GeomAlgoAPI_MakeShapeList.h>
#include <GeomAlgoAPI_Tools.h>
#include <GeomAPI_Ax1.h>
} else {
std::string anError;
ListOfShape aListOfShape;
- std::list<std::shared_ptr<GeomAlgoAPI_Translation> > aListOfTranslationAlgo;
+ std::shared_ptr<GeomAlgoAPI_MakeShapeList>
+ aListOfTranslationAlgo(new GeomAlgoAPI_MakeShapeList);
for (int i=0; i<nbCopies; i++) {
std::shared_ptr<GeomAlgoAPI_Translation> aTranslationAlgo(
break;
}
aListOfShape.push_back(aTranslationAlgo->shape());
- aListOfTranslationAlgo.push_back(aTranslationAlgo);
+ aListOfTranslationAlgo->appendAlgo(aTranslationAlgo);
}
std::shared_ptr<GeomAPI_Shape> aCompound =
GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
- aResultBody->storeModified(aBaseShape, aCompound);
- loadNamingDS(aListOfTranslationAlgo, aResultBody, aBaseShape);
+
+ ListOfShape aBaseShapes;
+ aBaseShapes.push_back(aBaseShape);
+ FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapes, ListOfShape(),
+ aListOfTranslationAlgo, aCompound, "Translated");
setResult(aResultBody, aResultIndex);
}
} else {
std::string anError;
ListOfShape aListOfShape;
- std::list<std::shared_ptr<GeomAlgoAPI_Translation> > aListOfTranslationAlgo;
+ std::shared_ptr<GeomAlgoAPI_MakeShapeList>
+ aListOfTranslationAlgo(new GeomAlgoAPI_MakeShapeList);
for (int j=0; j<aSecondNbCopies; j++) {
for (int i=0; i<aFirstNbCopies; i++) {
break;
}
aListOfShape.push_back(aTranslationAlgo->shape());
- aListOfTranslationAlgo.push_back(aTranslationAlgo);
+ aListOfTranslationAlgo->appendAlgo(aTranslationAlgo);
}
}
std::shared_ptr<GeomAPI_Shape> aCompound =
GeomAlgoAPI_CompoundBuilder::compound(aListOfShape);
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
- aResultBody->storeModified(aBaseShape, aCompound);
- loadNamingDS(aListOfTranslationAlgo, aResultBody, aBaseShape);
+
+ ListOfShape aBaseShapes;
+ aBaseShapes.push_back(aBaseShape);
+ FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapes, ListOfShape(),
+ aListOfTranslationAlgo, aCompound, "Translated");
+
setResult(aResultBody, aResultIndex);
}
aResultIndex++;
// Remove the rest results if there were produced in the previous pass.
removeResults(aResultIndex);
}
-
-//=================================================================================================
-void FeaturesPlugin_MultiTranslation::loadNamingDS(
- std::list<std::shared_ptr<GeomAlgoAPI_Translation> > theListOfTranslationAlgo,
- std::shared_ptr<ModelAPI_ResultBody> theResultBody,
- std::shared_ptr<GeomAPI_Shape> theBaseShape)
-{
- for (std::list<std::shared_ptr<GeomAlgoAPI_Translation> >::const_iterator anIt =
- theListOfTranslationAlgo.begin(); anIt != theListOfTranslationAlgo.cend(); ++anIt) {
- // naming of faces
- theResultBody->loadModifiedShapes(*anIt,
- theBaseShape,
- GeomAPI_Shape::FACE,
- "Translated_Face");
-
- // naming of edges
- theResultBody->loadModifiedShapes(*anIt,
- theBaseShape,
- GeomAPI_Shape::EDGE,
- "Translated_Edge");
-
- // naming of vertex
- theResultBody->loadModifiedShapes(*anIt,
- theBaseShape,
- GeomAPI_Shape::VERTEX,
- "Translated_Vertex");
- }
-}
/// Perform the multi translation in two directions.
void performTwoDirection();
-
- void loadNamingDS(std::list<std::shared_ptr<GeomAlgoAPI_Translation> > theListOfTranslationAlgo,
- std::shared_ptr<ModelAPI_ResultBody> theResultBody,
- std::shared_ptr<GeomAPI_Shape> theBaseShape);
};
#endif // FEATURESPLUGIN_MULTITRANSLATION_H_
\ No newline at end of file
const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
const int theIndex)
{
- // Find base. The most complicated is the real modified object (#1799 if box is partitioned by
- // two planes the box is the base, not planes, independently on the order in the list).
- GeomShapePtr aBaseShape;
- for(ListOfShape::const_iterator anIt = theObjects.cbegin(); anIt != theObjects.cend(); ++anIt) {
- GeomShapePtr anObjectShape = *anIt;
- GeomShapePtr aCandidate =
- findBase(anObjectShape, theResultShape, GeomAPI_Shape::VERTEX, theMakeShape);
- if(!aCandidate.get()) {
- aCandidate = findBase(anObjectShape, theResultShape, GeomAPI_Shape::EDGE, theMakeShape);
- }
- if (!aCandidate.get())
- aCandidate = findBase(anObjectShape, theResultShape, GeomAPI_Shape::FACE, theMakeShape);
-
- if(aCandidate.get()) {
- if (!aBaseShape.get() || aBaseShape->shapeType() > aCandidate->shapeType()) {
- aBaseShape = aCandidate;
- }
- }
- }
-
// Create result body.
ResultBodyPtr aResultBody = document()->createBody(data(), theIndex);
- // Store modified shape.
- if(!aBaseShape.get() || aBaseShape->isEqual(theResultShape)) {
- aResultBody->store(theResultShape, false);
- setResult(aResultBody, theIndex);
- return;
+ // if result is same as one of the base object, no modification was performed
+ for(ListOfShape::const_iterator anObj = theObjects.cbegin(); anObj != theObjects.cend(); ++anObj)
+ {
+ if (anObj->get() && (*anObj)->isSame(theResultShape)) {
+ aResultBody->store(theResultShape, false);
+ setResult(aResultBody, theIndex);
+ return;
+ }
}
- aResultBody->storeModified(aBaseShape, theResultShape);
+ aResultBody->storeModified(theObjects, theResultShape, theMakeShape);
std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = theMakeShape->mapOfSubShapes();
theObjects.insert(theObjects.end(), thePlanes.begin(), thePlanes.end());
//================= Auxiliary functions ===================================================
-GeomShapePtr findBase(const GeomShapePtr theObjectShape,
- const GeomShapePtr theResultShape,
- const GeomAPI_Shape::ShapeType theShapeType,
- const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape)
-{
- GeomShapePtr aBaseShape;
- std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = theMakeShape->mapOfSubShapes();
- for(GeomAPI_ShapeExplorer anObjectSubShapesExp(theObjectShape, theShapeType);
- anObjectSubShapesExp.more();
- anObjectSubShapesExp.next()) {
- GeomShapePtr anObjectSubShape = anObjectSubShapesExp.current();
- ListOfShape aModifiedShapes;
- theMakeShape->modified(anObjectSubShape, aModifiedShapes);
- for(ListOfShape::const_iterator
- aModIt = aModifiedShapes.cbegin(); aModIt != aModifiedShapes.cend(); ++aModIt) {
- GeomShapePtr aModShape = *aModIt;
- if(aMapOfSubShapes->isBound(aModShape)) {
- aModShape = aMapOfSubShapes->find(aModShape);
- }
- if(theResultShape->isSubShape(aModShape)) {
- aBaseShape = theObjectShape;
- break;
- }
- }
- if(aBaseShape.get()) {
- break;
- }
- }
-
- return aBaseShape;
-}
-
static CompsolidSubs::iterator findOrAdd(CompsolidSubs& theList, const GeomShapePtr& theCompsolid)
{
CompsolidSubs::iterator aFound = theList.begin();
//LoadNamingDS
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
- aResultBody->storeModified(aBaseShape, aTransformAlgo->shape());
- FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShape, aTransformAlgo, "Placed");
+
+ ListOfShape aShapes;
+ aShapes.push_back(aBaseShape);
+ FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aShapes, ListOfShape(),
+ aTransformAlgo, aTransformAlgo->shape(), "Placed");
setResult(aResultBody, aResultIndex);
}
aResultIndex++;
}
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
- aResultBody->storeModified(aBaseShape, aRotationAlgo->shape());
- FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShape, aRotationAlgo, "Rotated");
+
+ ListOfShape aShapes;
+ aShapes.push_back(aBaseShape);
+ FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
+ aShapes,
+ ListOfShape(),
+ aRotationAlgo,
+ aRotationAlgo->shape(),
+ "Rotated");
setResult(aResultBody, aResultIndex);
}
aResultIndex++;
}
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
- aResultBody->storeModified(aBaseShape, aRotationAlgo->shape());
- FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShape, aRotationAlgo, "Rotated");
+
+ ListOfShape aShapes;
+ aShapes.push_back(aBaseShape);
+ FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
+ aShapes,
+ ListOfShape(),
+ aRotationAlgo,
+ aRotationAlgo->shape(),
+ "Rotated");
setResult(aResultBody, aResultIndex);
}
aResultIndex++;
}
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
- aResultBody->storeModified(aBaseShape, aScaleAlgo->shape());
- FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShape, aScaleAlgo, "Scaled");
+
+ ListOfShape aShapes;
+ aShapes.push_back(aBaseShape);
+ FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
+ aShapes,
+ ListOfShape(),
+ aScaleAlgo,
+ aScaleAlgo->shape(),
+ "Scaled");
setResult(aResultBody, aResultIndex);
aResultIndex++;
}
}
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
- aResultBody->storeModified(aBaseShape, aScaleAlgo->shape());
- FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShape, aScaleAlgo, "Scaled");
+
+ ListOfShape aShapes;
+ aShapes.push_back(aBaseShape);
+ FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
+ aShapes,
+ ListOfShape(),
+ aScaleAlgo,
+ aScaleAlgo->shape(),
+ "Scaled");
setResult(aResultBody, aResultIndex);
aResultIndex++;
}
// Store and name the result.
ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
- aResultBody->storeModified(theBaseShape, aCompound);
- FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, theBaseShape, anAlgoList, "Symmetried");
+
+ ListOfShape aBaseShapes;
+ aBaseShapes.push_back(theBaseShape);
+ FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aBaseShapes, ListOfShape(),
+ anAlgoList, aCompound, "Symmetried");
+
setResult(aResultBody, theResultIndex);
}
//==================================================================================================
void FeaturesPlugin_Tools::loadModifiedShapes(ResultBodyPtr theResultBody,
- const GeomShapePtr theBaseShape,
+ const ListOfShape& theBaseShapes,
const ListOfShape& theTools,
const GeomMakeShapePtr& theMakeShape,
- const GeomShapePtr theResultShape)
+ const GeomShapePtr theResultShape,
+ const std::string& theNamePrefix)
{
- if (theBaseShape->isEqual(theResultShape)) {
- theResultBody->store(theResultShape, false);
- return;
- }
+ theResultBody->storeModified(theBaseShapes, theResultShape, theMakeShape);
- theResultBody->storeModified(theBaseShape, theResultShape);
+ ListOfShape aShapes = theBaseShapes;
+ ListOfShape::const_iterator aToolIter = theTools.cbegin();
+ for(; aToolIter != theTools.cend(); aToolIter++)
+ aShapes.push_back(*aToolIter);
- ListOfShape aShapes = theTools;
- aShapes.push_front(theBaseShape);
+ std::string aVertexName, anEdgeName, aFaceName;
+ if (!theNamePrefix.empty()) {
+ aVertexName = theNamePrefix + "_Vertex";
+ anEdgeName = theNamePrefix + "_Edge";
+ aFaceName = theNamePrefix + "_Face";
+ }
for (ListOfShape::const_iterator anIter = aShapes.begin(); anIter != aShapes.end(); ++anIter)
{
- theResultBody->loadModifiedShapes(theMakeShape, *anIter, GeomAPI_Shape::VERTEX);
- theResultBody->loadModifiedShapes(theMakeShape, *anIter, GeomAPI_Shape::EDGE);
- theResultBody->loadModifiedShapes(theMakeShape, *anIter, GeomAPI_Shape::FACE);
+ theResultBody->loadModifiedShapes(theMakeShape, *anIter, GeomAPI_Shape::VERTEX, aVertexName);
+ theResultBody->loadModifiedShapes(theMakeShape, *anIter, GeomAPI_Shape::EDGE, anEdgeName);
+ theResultBody->loadModifiedShapes(theMakeShape, *anIter, GeomAPI_Shape::FACE, aFaceName);
}
}
//==================================================================================================
void FeaturesPlugin_Tools::loadModifiedShapes(ResultBodyPtr theResultBody,
- const GeomShapePtr theBaseShape,
+ const GeomShapePtr& theBaseShape,
const GeomMakeShapePtr& theMakeShape,
const std::string theName)
{
const GeomShapePtr theResultShapesCompound)
{
ListOfShape aShapes = theTools;
- aShapes.push_front(theBaseShape);
+ if (theBaseShape.get())
+ aShapes.push_front(theBaseShape);
for (ListOfShape::const_iterator anIter = aShapes.begin(); anIter != aShapes.end(); anIter++)
{
public:
static void loadModifiedShapes(ResultBodyPtr theResultBody,
- const GeomShapePtr theBaseShape,
+ const ListOfShape& theBaseShapes,
const ListOfShape& theTools,
const GeomMakeShapePtr& theMakeShape,
- const GeomShapePtr theResultShape);
+ const GeomShapePtr theResultShape,
+ const std::string& theNamePrefix = "");
static void loadModifiedShapes(ResultBodyPtr theResultBody,
- const GeomShapePtr theBaseShape,
+ const GeomShapePtr& theBaseShape,
const GeomMakeShapePtr& theMakeShape,
const std::string theName);
-
/// Stores deleted shapes.
static void loadDeletedShapes(ResultBodyPtr theResultBody,
const GeomShapePtr theBaseShape,
}
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
- aResultBody->storeModified(aBaseShape, aTranslationAlgo->shape());
+
+ ListOfShape aShapes;
+ aShapes.push_back(aBaseShape);
FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
- aBaseShape,
+ aShapes,
+ ListOfShape(),
aTranslationAlgo,
+ aTranslationAlgo->shape(),
"Translated");
setResult(aResultBody, aResultIndex);
}
}
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
- aResultBody->storeModified(aBaseShape, aTranslationAlgo->shape());
+
+ ListOfShape aShapes;
+ aShapes.push_back(aBaseShape);
FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
- aBaseShape,
+ aShapes,
+ ListOfShape(),
aTranslationAlgo,
+ aTranslationAlgo->shape(),
"Translated");
setResult(aResultBody, aResultIndex);
}
}
ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
- aResultBody->storeModified(aBaseShape, aTranslationAlgo->shape());
+
+ ListOfShape aShapes;
+ aShapes.push_back(aBaseShape);
FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
- aBaseShape,
+ aShapes,
+ ListOfShape(),
aTranslationAlgo,
+ aTranslationAlgo->shape(),
"Translated");
setResult(aResultBody, aResultIndex);
}
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+from ModelAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(396.8373493975904, 115.9638554216867, -225.1506024096385, 115.9638554216867)
+SketchLine_2 = Sketch_1.addLine(-225.1506024096385, 115.9638554216867, -225.1506024096385, -149.0963855421687)
+SketchLine_3 = Sketch_1.addLine(-225.1506024096385, -149.0963855421687, 396.8373493975904, -149.0963855421687)
+SketchLine_4 = Sketch_1.addLine(396.8373493975904, -149.0963855421687, 396.8373493975904, 115.9638554216867)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_2.addCircle(-348.644578313253, 155.1204819277109, 207.6894050099908)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f-SketchLine_4f")], model.selection(), 100, 0)
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_1_2r")], model.selection(), 100, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Extrusion_2_1")])
+Group_2 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_2_1")])
+model.end()
+
+# move groups
+model.begin()
+Part_1_doc.moveFeature(Group_1.feature(), Partition_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+model.end()
+
+# check each group contain two results: one is related to original body only, another - common part
+
+aFactory = ModelAPI_Session.get().validators()
+assert(aFactory.validate(Group_1.feature()))
+assert(aFactory.validate(Group_2.feature()))
+aList1 = Group_1.feature().selectionList("group_list")
+aList2 = Group_2.feature().selectionList("group_list")
+assert(aList1.size() == 2)
+assert(aList2.size() == 2)
+assert(aList1.value(0).value().shapeTypeStr() == "SOLID")
+assert(aList1.value(1).value().shapeTypeStr() == "SOLID")
+assert(aList2.value(0).value().shapeTypeStr() == "SOLID")
+assert(aList2.value(1).value().shapeTypeStr() == "SOLID")
+assert(aList1.value(0).value().isSame(aList2.value(0).value()) or aList1.value(1).value().isSame(aList2.value(0).value()) or
+aList1.value(0).value().isSame(aList2.value(1).value()) or aList1.value(1).value().isSame(aList2.value(1).value()))
Face_1_objects = [model.selection("EDGE", "Sketch_1/SketchArc_2_2"), model.selection("EDGE", "Sketch_1/SketchLine_4"), model.selection("EDGE", "Sketch_1/SketchLine_5"), model.selection("EDGE", "Sketch_1/SketchLine_6"), model.selection("EDGE", "Sketch_1/SketchLine_7"), model.selection("EDGE", "Sketch_1/SketchLine_8"), model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")]
Face_1 = model.addFace(Part_1_doc, Face_1_objects)
Intersection_1 = model.addIntersection(Part_1_doc, [model.selection("SOLID", "Recover_1_1"), model.selection("FACE", "Face_1_1")])
-Group_1_objects = [model.selection("VERTEX", "[Intersection_1_1_3/Intersection_1_1_3&Face_1_1/Edge_3][weak_name_2]"), model.selection("VERTEX", "[Intersection_1_1_1/Intersection_1_1_1][weak_name_2]"), model.selection("VERTEX", "[Intersection_1_1_9/Intersection_1_1_9&Face_1_1/Edge_7][weak_name_1]"), model.selection("VERTEX", "[Intersection_1_1_7/Intersection_1_1_7&Face_1_1/Edge_5][weak_name_2]"), model.selection("VERTEX", "[Intersection_1_1_4/Intersection_1_1_4][weak_name_2]"), model.selection("VERTEX", "[Intersection_1_1_1/Intersection_1_1_1][weak_name_1]"), model.selection("VERTEX", "[Intersection_1_1_2/Intersection_1_1_2&Face_1_1/Edge_2][weak_name_1]"), model.selection("VERTEX", "[Intersection_1_1_4/Intersection_1_1_4][weak_name_1]"), model.selection("VERTEX", "[Intersection_1_1_6/Intersection_1_1_6&Face_1_1/Edge_4][weak_name_2]"), model.selection("VERTEX", "[Intersection_1_1_10/Intersection_1_1_10&Face_1_1/Edge_8][weak_name_1]"), model.selection("VERTEX", "[Intersection_1_1_8/Intersection_1_1_8&Face_1_1/Edge_6][weak_name_1]")]
+Group_1_objects = [
+model.selection("VERTEX", "[Intersection_1_1_3/Intersection_1_1_3&Face_1_1/Edge_3][weak_name_2]"),
+model.selection("VERTEX", "[Intersection_1_1_1/Intersection_1_1_1][weak_name_2]"),
+model.selection("VERTEX", "[Intersection_1_1_9/Intersection_1_1_9&Face_1_1/Edge_7][weak_name_1]"),
+model.selection("VERTEX", "[Intersection_1_1_7/Intersection_1_1_7&Face_1_1/Edge_5][weak_name_2]"),
+model.selection("VERTEX", "[Intersection_1_1_4/Intersection_1_1_4][weak_name_2]"),
+model.selection("VERTEX", "[Intersection_1_1_1/Intersection_1_1_1][weak_name_1]"),
+model.selection("VERTEX", "[Intersection_1_1_2/Intersection_1_1_2&Face_1_1/Edge_2][weak_name_1]"),
+model.selection("VERTEX", "[Intersection_1_1_4/Intersection_1_1_4][weak_name_1]"),
+model.selection("VERTEX", "[Intersection_1_1_6/Intersection_1_1_6&Face_1_1/Edge_4][weak_name_2]"),
+model.selection("VERTEX", "[Intersection_1_1_10/Intersection_1_1_10&Face_1_1/Edge_8][weak_name_1]"),
+model.selection("VERTEX", "[Intersection_1_1_8/Intersection_1_1_8&Face_1_1/Edge_6][weak_name_1]")]
+
Group_1 = model.addGroup(Part_1_doc, Group_1_objects)
Group_2_objects = [model.selection("EDGE", "Intersection_1_1_7"), model.selection("EDGE", "Intersection_1_1_6"), model.selection("EDGE", "Intersection_1_1_3"), model.selection("EDGE", "Intersection_1_1_11"), model.selection("EDGE", "Intersection_1_1_5"), model.selection("EDGE", "Intersection_1_1_1"), model.selection("EDGE", "Intersection_1_1_4"), model.selection("EDGE", "Intersection_1_1_2"), model.selection("EDGE", "Intersection_1_1_10"), model.selection("EDGE", "Intersection_1_1_9"), model.selection("EDGE", "Intersection_1_1_8")]
Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
--- /dev/null
+## Copyright (C) 2019-20xx CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+model.addParameter(partSet, "epsilon", "0.1")
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_1 = SketchProjection_1.createdFeature()
+SketchLine_1.setName("SketchLine_2")
+SketchLine_1.result().setName("SketchLine_2")
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_2 = SketchProjection_2.createdFeature()
+SketchLine_2.setName("SketchLine_3")
+SketchLine_2.result().setName("SketchLine_3")
+SketchLine_3 = Sketch_1.addLine(0, 0, 0, -21)
+SketchLine_3.setName("SketchLine_4")
+SketchLine_3.result().setName("SketchLine_4")
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(0, -21, 54, -21)
+SketchLine_4.setName("SketchLine_5")
+SketchLine_4.result().setName("SketchLine_5")
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(54, -21, 57, -18)
+SketchLine_5.setName("SketchLine_6")
+SketchLine_5.result().setName("SketchLine_6")
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_3.result())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_4.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_3.result(), "42/2")
+SketchConstraintAngle_1 = Sketch_1.setAngleComplementary(SketchLine_4.result(), SketchLine_5.result(), 45)
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchLine_5.endPoint(), SketchLine_3.endPoint(), 57)
+SketchLine_6 = Sketch_1.addLine(57, -18, 159.1, -18)
+SketchLine_6.setName("SketchLine_7")
+SketchLine_6.result().setName("SketchLine_7")
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_6.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchLine_5.endPoint(), SketchLine_1.result(), "36/2", True)
+SketchLine_7 = Sketch_1.addLine(162.1, -21, 162.1, -31.5)
+SketchLine_7.setName("SketchLine_8")
+SketchLine_7.result().setName("SketchLine_8")
+SketchLine_8 = Sketch_1.addLine(162.1, -31.5, 204.1, -31.5)
+SketchLine_8.setName("SketchLine_9")
+SketchLine_8.result().setName("SketchLine_9")
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchLine_9 = Sketch_1.addLine(204.1, -31.5, 204.1, -21)
+SketchLine_9.setName("SketchLine_10")
+SketchLine_9.result().setName("SketchLine_10")
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchLine_10 = Sketch_1.addLine(204.1, -21, 181.1, -21)
+SketchLine_10.setName("SketchLine_11")
+SketchLine_10.result().setName("SketchLine_11")
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchLine_11 = Sketch_1.addLine(181.1, -21, 168.9756443470179, 0)
+SketchLine_11.setName("SketchLine_12")
+SketchLine_11.result().setName("SketchLine_12")
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_11.startPoint())
+SketchLine_12 = Sketch_1.addLine(168.9756443470179, 0, 0, 0)
+SketchLine_12.setName("SketchLine_13")
+SketchLine_12.result().setName("SketchLine_13")
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_12.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchAPI_Line(SketchLine_1).startPoint(), SketchLine_12.endPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_12.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_10.result())
+SketchConstraintHorizontal_5 = Sketch_1.setHorizontal(SketchLine_8.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_9.result())
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchLine_12.startPoint(), SketchLine_8.endPoint(), "63/2")
+SketchConstraintDistanceVertical_2 = Sketch_1.setVerticalDistance(SketchLine_12.startPoint(), SketchLine_10.startPoint(), "42/2")
+SketchConstraintAngle_2 = Sketch_1.setAngleComplementary(SketchLine_12.result(), SketchLine_11.result(), 60)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_10.result(), 23)
+SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_8.result(), 42)
+SketchLine_13 = Sketch_1.addLine(54, -21, 54, 0)
+SketchLine_13.setName("SketchLine_14")
+SketchLine_13.result().setName("SketchLine_14")
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_13.startPoint())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_13.endPoint(), SketchLine_1.result())
+SketchLine_14 = Sketch_1.addLine(57, -18, 57, 0)
+SketchLine_14.setName("SketchLine_15")
+SketchLine_14.result().setName("SketchLine_15")
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_14.startPoint())
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchLine_14.endPoint(), SketchLine_1.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_14.result())
+SketchConstraintVertical_5 = Sketch_1.setVertical(SketchLine_13.result())
+SketchLine_15 = Sketch_1.addLine(181.1, -21, 181.1, -31.5)
+SketchLine_15.setName("SketchLine_18")
+SketchLine_15.result().setName("SketchLine_18")
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_15.startPoint())
+SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchLine_15.endPoint(), SketchLine_8.result())
+SketchConstraintVertical_6 = Sketch_1.setVertical(SketchLine_15.result())
+SketchArc_1 = Sketch_1.addArc(159.1, -21, 162.1, -21, 159.1, -18, False)
+SketchPoint_1 = Sketch_1.addPoint(162.1, -18)
+SketchPoint_1.setName("SketchPoint_2")
+SketchPoint_1.result().setName("SketchPoint_2")
+SketchPoint_1.setAuxiliary(True)
+SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchLine_6.result())
+SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchLine_7.result())
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchLine_6.startPoint(), SketchPoint_1.coordinates(), "105+epsilon", False)
+SketchConstraintCoincidence_19 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_20 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_6.endPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchArc_1.results()[1], SketchLine_6.result())
+SketchConstraintTangent_2 = Sketch_1.setTangent(SketchArc_1.results()[1], SketchLine_7.result())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 3)
+SketchLine_16 = Sketch_1.addLine(162.1, -21, 181.1, -21)
+SketchLine_16.setName("SketchLine_36")
+SketchLine_16.result().setName("SketchLine_36")
+SketchConstraintCoincidence_21 = Sketch_1.setCoincident(SketchLine_16.endPoint(), SketchLine_11.result())
+SketchConstraintCoincidence_22 = Sketch_1.setCoincident(SketchLine_16.startPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_23 = Sketch_1.setCoincident(SketchLine_16.endPoint(), SketchLine_15.startPoint())
+SketchLine_17 = Sketch_1.addLine(159.1, -18, 159.1, 0)
+SketchLine_17.setName("SketchLine_35")
+SketchLine_17.result().setName("SketchLine_35")
+SketchConstraintCoincidence_24 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_17.startPoint())
+SketchConstraintCoincidence_25 = Sketch_1.setCoincident(SketchLine_17.endPoint(), SketchLine_12.result())
+SketchConstraintVertical_7 = Sketch_1.setVertical(SketchLine_17.result())
+SketchLine_18 = Sketch_1.addLine(159.1, -18, 175.3264973081038, -11)
+SketchLine_18.setName("SketchLine_37")
+SketchLine_18.result().setName("SketchLine_37")
+SketchConstraintCoincidence_26 = Sketch_1.setCoincident(SketchLine_18.endPoint(), SketchLine_11.result())
+SketchConstraintCoincidence_27 = Sketch_1.setCoincident(SketchLine_18.startPoint(), SketchLine_6.endPoint())
+SketchLine_19 = Sketch_1.addLine(168.9756443470179, 0, 168.9756443470179, -5)
+SketchLine_19.setName("SketchLine_38")
+SketchLine_19.result().setName("SketchLine_38")
+SketchLine_19.setAuxiliary(True)
+SketchConstraintCoincidence_28 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_19.startPoint())
+SketchConstraintVertical_8 = Sketch_1.setVertical(SketchLine_19.result())
+SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_19.result(), 5)
+SketchConstraintDistanceVertical_3 = Sketch_1.setVerticalDistance(SketchLine_18.endPoint(), SketchLine_12.startPoint(), 11)
+model.do()
+Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection("EDGE", "Sketch_1/SketchLine_13"), 360, 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Revolution_1_1_1/Generated_Face&Sketch_1/SketchLine_4"))
+SketchPoint_2 = Sketch_2.addPoint(0, 0)
+SketchPoint_2.setName("SketchPoint_3")
+SketchPoint_2.result().setName("SketchPoint_3")
+SketchProjection_3 = Sketch_2.addProjection(model.selection("VERTEX", "[Revolution_1_1_1/Generated_Face&Sketch_1/SketchLine_4][Revolution_1_1_1/Generated_Face&Sketch_1/SketchLine_5]__cc"), False)
+SketchProjection_3.setName("SketchProjection_4")
+SketchProjection_3.result().setName("SketchProjection_4")
+SketchPoint_3 = SketchProjection_3.createdFeature()
+SketchPoint_3.setName("SketchPoint_4")
+SketchPoint_3.result().setName("SketchPoint_4")
+SketchConstraintCoincidence_29 = Sketch_2.setCoincident(SketchPoint_2.coordinates(), SketchPoint_3.result())
+model.do()
+Sketch_2.setName("Sketch_3")
+Sketch_2.result().setName("Sketch_3")
+model.do()
+Part_2 = model.addPart(partSet)
+Part_2_doc = Part_2.document()
+Sketch_3 = model.addSketch(Part_2_doc, model.defaultPlane("XOY"))
+SketchProjection_4 = Sketch_3.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_20 = SketchProjection_4.createdFeature()
+SketchLine_20.setName("SketchLine_2")
+SketchLine_20.result().setName("SketchLine_2")
+SketchProjection_5 = Sketch_3.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_21 = SketchProjection_5.createdFeature()
+SketchLine_21.setName("SketchLine_3")
+SketchLine_21.result().setName("SketchLine_3")
+SketchLine_22 = Sketch_3.addLine(0, 0, 0, -21)
+SketchLine_22.setName("SketchLine_4")
+SketchLine_22.result().setName("SketchLine_4")
+SketchConstraintCoincidence_30 = Sketch_3.setCoincident(SketchAPI_Line(SketchLine_20).startPoint(), SketchLine_22.startPoint())
+SketchLine_23 = Sketch_3.addLine(0, -21, 54, -21)
+SketchLine_23.setName("SketchLine_5")
+SketchLine_23.result().setName("SketchLine_5")
+SketchConstraintCoincidence_31 = Sketch_3.setCoincident(SketchLine_22.endPoint(), SketchLine_23.startPoint())
+SketchLine_24 = Sketch_3.addLine(54, -21, 57, -18)
+SketchLine_24.setName("SketchLine_6")
+SketchLine_24.result().setName("SketchLine_6")
+SketchConstraintCoincidence_32 = Sketch_3.setCoincident(SketchLine_23.endPoint(), SketchLine_24.startPoint())
+SketchConstraintVertical_9 = Sketch_3.setVertical(SketchLine_22.result())
+SketchConstraintHorizontal_6 = Sketch_3.setHorizontal(SketchLine_23.result())
+SketchConstraintLength_5 = Sketch_3.setLength(SketchLine_22.result(), "42/2")
+SketchConstraintAngle_3 = Sketch_3.setAngleComplementary(SketchLine_23.result(), SketchLine_24.result(), 45)
+SketchConstraintDistanceHorizontal_2 = Sketch_3.setHorizontalDistance(SketchLine_24.endPoint(), SketchLine_22.endPoint(), 57)
+SketchLine_25 = Sketch_3.addLine(57, -18, 159.1, -18)
+SketchLine_25.setName("SketchLine_7")
+SketchLine_25.result().setName("SketchLine_7")
+SketchConstraintCoincidence_33 = Sketch_3.setCoincident(SketchLine_24.endPoint(), SketchLine_25.startPoint())
+SketchConstraintHorizontal_7 = Sketch_3.setHorizontal(SketchLine_25.result())
+SketchConstraintDistance_3 = Sketch_3.setDistance(SketchLine_24.endPoint(), SketchLine_20.result(), "36/2", True)
+SketchLine_26 = Sketch_3.addLine(162.1, -21, 162.1, -31.5)
+SketchLine_26.setName("SketchLine_8")
+SketchLine_26.result().setName("SketchLine_8")
+SketchLine_27 = Sketch_3.addLine(162.1, -31.5, 204.1, -31.5)
+SketchLine_27.setName("SketchLine_9")
+SketchLine_27.result().setName("SketchLine_9")
+SketchConstraintCoincidence_34 = Sketch_3.setCoincident(SketchLine_26.endPoint(), SketchLine_27.startPoint())
+SketchLine_28 = Sketch_3.addLine(204.1, -31.5, 204.1, -21)
+SketchLine_28.setName("SketchLine_10")
+SketchLine_28.result().setName("SketchLine_10")
+SketchConstraintCoincidence_35 = Sketch_3.setCoincident(SketchLine_27.endPoint(), SketchLine_28.startPoint())
+SketchLine_29 = Sketch_3.addLine(204.1, -21, 181.1, -21)
+SketchLine_29.setName("SketchLine_11")
+SketchLine_29.result().setName("SketchLine_11")
+SketchConstraintCoincidence_36 = Sketch_3.setCoincident(SketchLine_28.endPoint(), SketchLine_29.startPoint())
+SketchLine_30 = Sketch_3.addLine(181.1, -21, 168.9756443470179, 0)
+SketchLine_30.setName("SketchLine_12")
+SketchLine_30.result().setName("SketchLine_12")
+SketchConstraintCoincidence_37 = Sketch_3.setCoincident(SketchLine_29.endPoint(), SketchLine_30.startPoint())
+SketchLine_31 = Sketch_3.addLine(168.9756443470179, 0, 0, 0)
+SketchLine_31.setName("SketchLine_13")
+SketchLine_31.result().setName("SketchLine_13")
+SketchConstraintCoincidence_38 = Sketch_3.setCoincident(SketchLine_30.endPoint(), SketchLine_31.startPoint())
+SketchConstraintCoincidence_39 = Sketch_3.setCoincident(SketchAPI_Line(SketchLine_20).startPoint(), SketchLine_31.endPoint())
+SketchConstraintHorizontal_8 = Sketch_3.setHorizontal(SketchLine_31.result())
+SketchConstraintHorizontal_9 = Sketch_3.setHorizontal(SketchLine_29.result())
+SketchConstraintHorizontal_10 = Sketch_3.setHorizontal(SketchLine_27.result())
+SketchConstraintVertical_10 = Sketch_3.setVertical(SketchLine_26.result())
+SketchConstraintVertical_11 = Sketch_3.setVertical(SketchLine_28.result())
+SketchConstraintDistanceVertical_4 = Sketch_3.setVerticalDistance(SketchLine_31.startPoint(), SketchLine_27.endPoint(), "63/2")
+SketchConstraintDistanceVertical_5 = Sketch_3.setVerticalDistance(SketchLine_31.startPoint(), SketchLine_29.startPoint(), "42/2")
+SketchConstraintAngle_4 = Sketch_3.setAngleComplementary(SketchLine_31.result(), SketchLine_30.result(), 60)
+SketchConstraintLength_6 = Sketch_3.setLength(SketchLine_29.result(), 23)
+SketchConstraintLength_7 = Sketch_3.setLength(SketchLine_27.result(), 42)
+SketchLine_32 = Sketch_3.addLine(54, -21, 54, 0)
+SketchLine_32.setName("SketchLine_14")
+SketchLine_32.result().setName("SketchLine_14")
+SketchConstraintCoincidence_40 = Sketch_3.setCoincident(SketchLine_23.endPoint(), SketchLine_32.startPoint())
+SketchConstraintCoincidence_41 = Sketch_3.setCoincident(SketchLine_32.endPoint(), SketchLine_20.result())
+SketchLine_33 = Sketch_3.addLine(57, -18, 57, 0)
+SketchLine_33.setName("SketchLine_15")
+SketchLine_33.result().setName("SketchLine_15")
+SketchConstraintCoincidence_42 = Sketch_3.setCoincident(SketchLine_24.endPoint(), SketchLine_33.startPoint())
+SketchConstraintCoincidence_43 = Sketch_3.setCoincident(SketchLine_33.endPoint(), SketchLine_20.result())
+SketchConstraintVertical_12 = Sketch_3.setVertical(SketchLine_33.result())
+SketchConstraintVertical_13 = Sketch_3.setVertical(SketchLine_32.result())
+SketchLine_34 = Sketch_3.addLine(181.1, -21, 181.1, -31.5)
+SketchLine_34.setName("SketchLine_18")
+SketchLine_34.result().setName("SketchLine_18")
+SketchConstraintCoincidence_44 = Sketch_3.setCoincident(SketchLine_29.endPoint(), SketchLine_34.startPoint())
+SketchConstraintCoincidence_45 = Sketch_3.setCoincident(SketchLine_34.endPoint(), SketchLine_27.result())
+SketchConstraintVertical_14 = Sketch_3.setVertical(SketchLine_34.result())
+SketchArc_2 = Sketch_3.addArc(159.1, -21, 162.1, -21, 159.1, -18, False)
+SketchPoint_4 = Sketch_3.addPoint(162.1, -18)
+SketchPoint_4.setName("SketchPoint_2")
+SketchPoint_4.result().setName("SketchPoint_2")
+SketchPoint_4.setAuxiliary(True)
+SketchConstraintCoincidence_46 = Sketch_3.setCoincident(SketchPoint_4.coordinates(), SketchLine_25.result())
+SketchConstraintCoincidence_47 = Sketch_3.setCoincident(SketchPoint_4.coordinates(), SketchLine_26.result())
+SketchConstraintDistance_4 = Sketch_3.setDistance(SketchLine_25.startPoint(), SketchPoint_4.coordinates(), "105+epsilon", False)
+SketchConstraintCoincidence_48 = Sketch_3.setCoincident(SketchArc_2.startPoint(), SketchLine_26.startPoint())
+SketchConstraintCoincidence_49 = Sketch_3.setCoincident(SketchArc_2.endPoint(), SketchLine_25.endPoint())
+SketchConstraintTangent_3 = Sketch_3.setTangent(SketchArc_2.results()[1], SketchLine_25.result())
+SketchConstraintTangent_4 = Sketch_3.setTangent(SketchArc_2.results()[1], SketchLine_26.result())
+SketchConstraintRadius_2 = Sketch_3.setRadius(SketchArc_2.results()[1], 3)
+SketchLine_35 = Sketch_3.addLine(162.1, -21, 181.1, -21)
+SketchLine_35.setName("SketchLine_36")
+SketchLine_35.result().setName("SketchLine_36")
+SketchConstraintCoincidence_50 = Sketch_3.setCoincident(SketchLine_35.endPoint(), SketchLine_30.result())
+SketchConstraintCoincidence_51 = Sketch_3.setCoincident(SketchLine_35.startPoint(), SketchLine_26.startPoint())
+SketchConstraintCoincidence_52 = Sketch_3.setCoincident(SketchLine_35.endPoint(), SketchLine_34.startPoint())
+SketchLine_36 = Sketch_3.addLine(159.1, -18, 159.1, 0)
+SketchLine_36.setName("SketchLine_35")
+SketchLine_36.result().setName("SketchLine_35")
+SketchConstraintCoincidence_53 = Sketch_3.setCoincident(SketchLine_25.endPoint(), SketchLine_36.startPoint())
+SketchConstraintCoincidence_54 = Sketch_3.setCoincident(SketchLine_36.endPoint(), SketchLine_31.result())
+SketchConstraintVertical_15 = Sketch_3.setVertical(SketchLine_36.result())
+SketchLine_37 = Sketch_3.addLine(159.1, -18, 175.3264973081038, -11)
+SketchLine_37.setName("SketchLine_37")
+SketchLine_37.result().setName("SketchLine_37")
+SketchConstraintCoincidence_55 = Sketch_3.setCoincident(SketchLine_37.endPoint(), SketchLine_30.result())
+SketchConstraintCoincidence_56 = Sketch_3.setCoincident(SketchLine_37.startPoint(), SketchLine_25.endPoint())
+SketchLine_38 = Sketch_3.addLine(168.9756443470179, 0, 168.9756443470179, -5)
+SketchLine_38.setName("SketchLine_38")
+SketchLine_38.result().setName("SketchLine_38")
+SketchLine_38.setAuxiliary(True)
+SketchConstraintCoincidence_57 = Sketch_3.setCoincident(SketchLine_30.endPoint(), SketchLine_38.startPoint())
+SketchConstraintVertical_16 = Sketch_3.setVertical(SketchLine_38.result())
+SketchConstraintLength_8 = Sketch_3.setLength(SketchLine_38.result(), 5)
+SketchConstraintDistanceVertical_6 = Sketch_3.setVerticalDistance(SketchLine_37.endPoint(), SketchLine_31.startPoint(), 11)
+model.do()
+Revolution_2 = model.addRevolution(Part_2_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection("EDGE", "Sketch_1/SketchLine_13"), 360, 0)
+Sketch_4 = model.addSketch(Part_2_doc, model.selection("FACE", "Revolution_1_1_1/Generated_Face&Sketch_1/SketchLine_4"))
+SketchLine_39 = Sketch_4.addLine(50, 0, -50, 0)
+SketchLine_39.setName("SketchLine_19")
+SketchLine_39.result().setName("SketchLine_19")
+SketchConstraintHorizontal_11 = Sketch_4.setHorizontal(SketchLine_39.result())
+SketchProjection_6 = Sketch_4.addProjection(model.selection("VERTEX", "[Revolution_1_1_1/Generated_Face&Sketch_1/SketchLine_4][Revolution_1_1_1/Generated_Face&Sketch_1/SketchLine_5]__cc"), False)
+SketchPoint_5 = SketchProjection_6.createdFeature()
+SketchPoint_5.setName("SketchPoint_1")
+SketchPoint_5.result().setName("SketchPoint_1")
+SketchConstraintLength_9 = Sketch_4.setLength(SketchLine_39.result(), 100)
+SketchLine_40 = Sketch_4.addLine(0, -50, 0, 50)
+SketchLine_40.setName("SketchLine_20")
+SketchLine_40.result().setName("SketchLine_20")
+SketchProjection_7 = Sketch_4.addProjection(model.selection("EDGE", "PartSet/OZ"), False)
+SketchLine_41 = SketchProjection_7.createdFeature()
+SketchLine_41.setName("SketchLine_21")
+SketchLine_41.result().setName("SketchLine_21")
+SketchConstraintCoincidence_58 = Sketch_4.setCoincident(SketchLine_40.startPoint(), SketchLine_41.result())
+SketchConstraintVertical_17 = Sketch_4.setVertical(SketchLine_40.result())
+SketchConstraintLength_10 = Sketch_4.setLength(SketchLine_40.result(), 100)
+SketchCircle_1 = Sketch_4.addCircle(0, 0, 7)
+SketchCircle_1.setAuxiliary(True)
+SketchConstraintCoincidence_59 = Sketch_4.setCoincident(SketchAPI_Point(SketchPoint_5).coordinates(), SketchCircle_1.center())
+SketchConstraintRadius_3 = Sketch_4.setRadius(SketchCircle_1.results()[1], 7)
+SketchLine_42 = Sketch_4.addLine(0, 0, -4.949747468305834, -4.949747468305832)
+SketchLine_42.setName("SketchLine_22")
+SketchLine_42.result().setName("SketchLine_22")
+SketchLine_42.setAuxiliary(True)
+SketchConstraintCoincidence_60 = Sketch_4.setCoincident(SketchAPI_Point(SketchPoint_5).coordinates(), SketchLine_42.startPoint())
+SketchConstraintCoincidence_61 = Sketch_4.setCoincident(SketchLine_42.endPoint(), SketchCircle_1.results()[1])
+SketchConstraintAngle_5 = Sketch_4.setAngleComplementary(SketchLine_42.result(), SketchLine_39.result(), 45)
+SketchLine_43 = Sketch_4.addLine(0, -7, -4.949747468305834, -4.949747468305832)
+SketchLine_43.setName("SketchLine_23")
+SketchLine_43.result().setName("SketchLine_23")
+SketchConstraintCoincidence_62 = Sketch_4.setCoincident(SketchLine_43.startPoint(), SketchLine_41.result())
+SketchConstraintCoincidence_63 = Sketch_4.setCoincident(SketchLine_42.endPoint(), SketchLine_43.endPoint())
+SketchLine_44 = Sketch_4.addLine(-4.949747468305834, -4.949747468305832, -7, 0)
+SketchLine_44.setName("SketchLine_24")
+SketchLine_44.result().setName("SketchLine_24")
+SketchConstraintCoincidence_64 = Sketch_4.setCoincident(SketchLine_42.endPoint(), SketchLine_44.startPoint())
+SketchConstraintCoincidence_65 = Sketch_4.setCoincident(SketchLine_44.endPoint(), SketchLine_39.result())
+SketchLine_45 = Sketch_4.addLine(-4.949747468305834, -4.949747468305832, -33.23401871576774, -33.23401871576773)
+SketchLine_45.setName("SketchLine_25")
+SketchLine_45.result().setName("SketchLine_25")
+SketchConstraintCoincidence_66 = Sketch_4.setCoincident(SketchLine_42.endPoint(), SketchLine_45.startPoint())
+SketchConstraintCollinear_1 = Sketch_4.setCollinear(SketchLine_45.result(), SketchLine_42.result())
+SketchConstraintCoincidence_67 = Sketch_4.setCoincident(SketchLine_43.startPoint(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_68 = Sketch_4.setCoincident(SketchLine_44.endPoint(), SketchCircle_1.results()[1])
+SketchConstraintLength_11 = Sketch_4.setLength(SketchLine_45.result(), 40)
+SketchMultiRotation_1_objects = [SketchLine_43.result(), SketchLine_45.result(), SketchLine_44.result()]
+SketchMultiRotation_1 = Sketch_4.addRotation(SketchMultiRotation_1_objects, SketchAPI_Line(SketchLine_41).startPoint(), 90, 4)
+[SketchLine_46, SketchLine_47, SketchLine_48, SketchLine_49, SketchLine_50, SketchLine_51, SketchLine_52, SketchLine_53, SketchLine_54] = SketchMultiRotation_1.rotated()
+SketchLine_54.setName("SketchLine_34")
+SketchLine_54.result().setName("SketchLine_34")
+SketchLine_53.setName("SketchLine_33")
+SketchLine_53.result().setName("SketchLine_33")
+SketchLine_52.setName("SketchLine_28")
+SketchLine_52.result().setName("SketchLine_28")
+SketchLine_51.setName("SketchLine_32")
+SketchLine_51.result().setName("SketchLine_32")
+SketchLine_50.setName("SketchLine_31")
+SketchLine_50.result().setName("SketchLine_31")
+SketchLine_49.setName("SketchLine_27")
+SketchLine_49.result().setName("SketchLine_27")
+SketchLine_48.setName("SketchLine_30")
+SketchLine_48.result().setName("SketchLine_30")
+SketchLine_47.setName("SketchLine_29")
+SketchLine_47.result().setName("SketchLine_29")
+SketchLine_46.setName("SketchLine_26")
+SketchLine_46.result().setName("SketchLine_26")
+model.do()
+Edge_1_objects = [model.selection("EDGE", "Sketch_2/SketchLine_27"), model.selection("EDGE", "Sketch_2/SketchLine_26"), model.selection("EDGE", "Sketch_2/SketchLine_28"), model.selection("EDGE", "Sketch_2/SketchLine_19"), model.selection("EDGE", "Sketch_2/SketchLine_25"), model.selection("EDGE", "Sketch_2/SketchLine_23"), model.selection("EDGE", "Sketch_2/SketchLine_24"), model.selection("EDGE", "Sketch_2/SketchLine_30"), model.selection("EDGE", "Sketch_2/SketchLine_34"), model.selection("EDGE", "Sketch_2/SketchLine_29"), model.selection("EDGE", "Sketch_2/SketchLine_33"), model.selection("EDGE", "Sketch_2/SketchLine_31"), model.selection("EDGE", "Sketch_2/SketchLine_20"), model.selection("EDGE", "Sketch_2/SketchLine_32")]
+Edge_1 = model.addEdge(Part_2_doc, Edge_1_objects)
+Extrusion_1_objects = [model.selection("EDGE", "Edge_1_1"), model.selection("EDGE", "Edge_1_2"), model.selection("EDGE", "Edge_1_3"), model.selection("EDGE", "Edge_1_4"), model.selection("EDGE", "Edge_1_5"), model.selection("EDGE", "Edge_1_6"), model.selection("EDGE", "Edge_1_7"), model.selection("EDGE", "Edge_1_8"), model.selection("EDGE", "Edge_1_9"), model.selection("EDGE", "Edge_1_10"), model.selection("EDGE", "Edge_1_11"), model.selection("EDGE", "Edge_1_12"), model.selection("EDGE", "Edge_1_13"), model.selection("EDGE", "Edge_1_14")]
+Extrusion_1 = model.addExtrusion(Part_2_doc, Extrusion_1_objects, model.selection("EDGE", "PartSet/OX"), 300, 0)
+Fill_1_objects_2 = [model.selection("FACE", "Extrusion_1_1"), model.selection("FACE", "Extrusion_1_2"), model.selection("FACE", "Extrusion_1_3"), model.selection("FACE", "Extrusion_1_4"), model.selection("FACE", "Extrusion_1_5"), model.selection("FACE", "Extrusion_1_6"), model.selection("FACE", "Extrusion_1_7"), model.selection("FACE", "Extrusion_1_8"), model.selection("FACE", "Extrusion_1_9"), model.selection("FACE", "Extrusion_1_10"), model.selection("FACE", "Extrusion_1_11"), model.selection("FACE", "Extrusion_1_12"), model.selection("FACE", "Extrusion_1_13"), model.selection("FACE", "Extrusion_1_14")]
+Fill_1 = model.addFill(Part_2_doc, [model.selection("COMPSOLID", "Revolution_1_1")], Fill_1_objects_2)
+Group_1_objects = [model.selection("SOLID", "Fill_1_1_25"), model.selection("SOLID", "Fill_1_1_28"), model.selection("SOLID", "Fill_1_1_26"), model.selection("SOLID", "Fill_1_1_27"), model.selection("SOLID", "Fill_1_1_31"), model.selection("SOLID", "Fill_1_1_35"), model.selection("SOLID", "Fill_1_1_36"), model.selection("SOLID", "Fill_1_1_32"), model.selection("SOLID", "Fill_1_1_34"), model.selection("SOLID", "Fill_1_1_30"), model.selection("SOLID", "Fill_1_1_33"), model.selection("SOLID", "Fill_1_1_29")]
+Group_1 = model.addGroup(Part_2_doc, Group_1_objects)
+Group_1.setName("CORPS")
+Group_1.result().setName("CORPS")
+Group_2_objects = [model.selection("SOLID", "Fill_1_1_41"), model.selection("SOLID", "Fill_1_1_49"), model.selection("SOLID", "Fill_1_1_69"), model.selection("SOLID", "Fill_1_1_71"), model.selection("SOLID", "Fill_1_1_51"), model.selection("SOLID", "Fill_1_1_43"), model.selection("SOLID", "Fill_1_1_44"), model.selection("SOLID", "Fill_1_1_67"), model.selection("SOLID", "Fill_1_1_39"), model.selection("SOLID", "Fill_1_1_47"), model.selection("SOLID", "Fill_1_1_45"), model.selection("SOLID", "Fill_1_1_37"), model.selection("SOLID", "Fill_1_1_65"), model.selection("SOLID", "Fill_1_1_66"), model.selection("SOLID", "Fill_1_1_38"), model.selection("SOLID", "Fill_1_1_46"), model.selection("SOLID", "Fill_1_1_48"), model.selection("SOLID", "Fill_1_1_40"), model.selection("SOLID", "Fill_1_1_68"), model.selection("SOLID", "Fill_1_1_42"), model.selection("SOLID", "Fill_1_1_70"), model.selection("SOLID", "Fill_1_1_50"), model.selection("SOLID", "Fill_1_1_52"), model.selection("SOLID", "Fill_1_1_72"), model.selection("SOLID", "Fill_1_1_63"), model.selection("SOLID", "Fill_1_1_64"), model.selection("SOLID", "Fill_1_1_61"), model.selection("SOLID", "Fill_1_1_62"), model.selection("SOLID", "Fill_1_1_58"), model.selection("SOLID", "Fill_1_1_57"), model.selection("SOLID", "Fill_1_1_54"), model.selection("SOLID", "Fill_1_1_53"), model.selection("SOLID", "Fill_1_1_55"), model.selection("SOLID", "Fill_1_1_56"), model.selection("SOLID", "Fill_1_1_60"), model.selection("SOLID", "Fill_1_1_59")]
+Group_2 = model.addGroup(Part_2_doc, Group_2_objects)
+Group_2.setName("TETE")
+Group_2.result().setName("TETE")
+Group_3_objects = [model.selection("SOLID", "Fill_1_1_2"), model.selection("SOLID", "Fill_1_1_1"), model.selection("SOLID", "Fill_1_1_5"), model.selection("SOLID", "Fill_1_1_9"), model.selection("SOLID", "Fill_1_1_13"), model.selection("SOLID", "Fill_1_1_14"), model.selection("SOLID", "Fill_1_1_15"), model.selection("SOLID", "Fill_1_1_19"), model.selection("SOLID", "Fill_1_1_11"), model.selection("SOLID", "Fill_1_1_12"), model.selection("SOLID", "Fill_1_1_24"), model.selection("SOLID", "Fill_1_1_23"), model.selection("SOLID", "Fill_1_1_16"), model.selection("SOLID", "Fill_1_1_8"), model.selection("SOLID", "Fill_1_1_20"), model.selection("SOLID", "Fill_1_1_4"), model.selection("SOLID", "Fill_1_1_3"), model.selection("SOLID", "Fill_1_1_7"), model.selection("SOLID", "Fill_1_1_10"), model.selection("SOLID", "Fill_1_1_6")]
+Group_3 = model.addGroup(Part_2_doc, Group_3_objects)
+Group_3.setName("PIED")
+Group_3.result().setName("PIED")
+Group_4 = model.addGroup(Part_2_doc, [model.selection("EDGE", "Fill_1_1_36/Generated_Edge&Sketch_2/SketchLine_31&Sketch_1/SketchLine_7")])
+Group_4.setName("corps_hauteur")
+Group_4.result().setName("corps_hauteur")
+Group_5 = model.addGroup(Part_2_doc, [model.selection("EDGE", "Fill_1_1_11/Generated_Edge&Sketch_2/SketchLine_31&Sketch_1/SketchLine_5")])
+Group_5.setName("pied_hauteur")
+Group_5.result().setName("pied_hauteur")
+Group_6 = model.addGroup(Part_2_doc, [model.selection("EDGE", "Fill_1_1_24/Generated_Edge&Sketch_2/SketchLine_31&Sketch_1/SketchLine_6")])
+Group_6.setName("chanfrein")
+Group_6.result().setName("chanfrein")
+Group_7 = model.addGroup(Part_2_doc, [model.selection("EDGE", "Fill_1_1_72/Generated_Edge&Sketch_2/SketchLine_31&Sketch_1/SketchArc_1_2")])
+Group_7.setName("filet")
+Group_7.result().setName("filet")
+Group_8 = model.addGroup(Part_2_doc, [model.selection("EDGE", "Fill_1_1_42/Generated_Edge&Sketch_2/SketchLine_31&Sketch_1/SketchLine_9")])
+Group_8.setName("tete_bas")
+Group_8.result().setName("tete_bas")
+Group_9_objects = [model.selection("FACE", "Fill_1_1_12/Modified_Face&Sketch_1/SketchLine_5"), model.selection("FACE", "Fill_1_1_11/Modified_Face&Sketch_1/SketchLine_5"), model.selection("FACE", "Fill_1_1_9/Modified_Face&Sketch_1/SketchLine_5"), model.selection("FACE", "Fill_1_1_8/Modified_Face&Sketch_1/SketchLine_5"), model.selection("FACE", "Fill_1_1_4/Modified_Face&Sketch_1/SketchLine_5"), model.selection("FACE", "Fill_1_1_1/Modified_Face&Sketch_1/SketchLine_5"), model.selection("FACE", "Fill_1_1_2/Modified_Face&Sketch_1/SketchLine_5"), model.selection("FACE", "Fill_1_1_5/Modified_Face&Sketch_1/SketchLine_5")]
+Group_9 = model.addGroup(Part_2_doc, Group_9_objects)
+Group_9.setName("ADH_PIEDS")
+Group_9.result().setName("ADH_PIEDS")
+Group_10_objects = [model.selection("FACE", "Fill_1_1_13/Modified_Face&Sketch_1/SketchLine_6"), model.selection("FACE", "Fill_1_1_14/Modified_Face&Sketch_1/SketchLine_6"), model.selection("FACE", "Fill_1_1_25/Modified_Face&Sketch_1/SketchLine_7"), model.selection("FACE", "Fill_1_1_26/Modified_Face&Sketch_1/SketchLine_7"), model.selection("FACE", "Fill_1_1_15/Modified_Face&Sketch_1/SketchLine_6"), model.selection("FACE", "Fill_1_1_27/Modified_Face&Sketch_1/SketchLine_7"), model.selection("FACE", "Fill_1_1_19/Modified_Face&Sketch_1/SketchLine_6"), model.selection("FACE", "Fill_1_1_31/Modified_Face&Sketch_1/SketchLine_7"), model.selection("FACE", "Fill_1_1_23/Modified_Face&Sketch_1/SketchLine_6"), model.selection("FACE", "Fill_1_1_35/Modified_Face&Sketch_1/SketchLine_7"), model.selection("FACE", "Fill_1_1_24/Modified_Face&Sketch_1/SketchLine_6"), model.selection("FACE", "Fill_1_1_36/Modified_Face&Sketch_1/SketchLine_7"), model.selection("FACE", "Fill_1_1_32/Modified_Face&Sketch_1/SketchLine_7"), model.selection("FACE", "Fill_1_1_20/Modified_Face&Sketch_1/SketchLine_6"), model.selection("FACE", "Fill_1_1_16/Modified_Face&Sketch_1/SketchLine_6"), model.selection("FACE", "Fill_1_1_28/Modified_Face&Sketch_1/SketchLine_7"), model.selection("FACE", "Fill_1_1_70/Modified_Face&Sketch_1/SketchArc_1_2"), model.selection("FACE", "Fill_1_1_42/Modified_Face&Sketch_1/SketchLine_8"), model.selection("FACE", "Fill_1_1_68/Modified_Face&Sketch_1/SketchArc_1_2"), model.selection("FACE", "Fill_1_1_40/Modified_Face&Sketch_1/SketchLine_8"), model.selection("FACE", "Fill_1_1_66/Modified_Face&Sketch_1/SketchArc_1_2"), model.selection("FACE", "Fill_1_1_38/Modified_Face&Sketch_1/SketchLine_8"), model.selection("FACE", "Fill_1_1_37/Modified_Face&Sketch_1/SketchLine_8"), model.selection("FACE", "Fill_1_1_65/Modified_Face&Sketch_1/SketchArc_1_2"), model.selection("FACE", "Fill_1_1_39/Modified_Face&Sketch_1/SketchLine_8"), model.selection("FACE", "Fill_1_1_67/Modified_Face&Sketch_1/SketchArc_1_2"), model.selection("FACE", "Fill_1_1_69/Modified_Face&Sketch_1/SketchArc_1_2"), model.selection("FACE", "Fill_1_1_41/Modified_Face&Sketch_1/SketchLine_8"), model.selection("FACE", "Fill_1_1_43/Modified_Face&Sketch_1/SketchLine_8"), model.selection("FACE", "Fill_1_1_71/Modified_Face&Sketch_1/SketchArc_1_2"), model.selection("FACE", "Fill_1_1_44/Modified_Face&Sketch_1/SketchLine_8"), model.selection("FACE", "Fill_1_1_72/Modified_Face&Sketch_1/SketchArc_1_2"), model.selection("FACE", "Fill_1_1_52/Modified_Face&Sketch_1/SketchLine_9"), model.selection("FACE", "Fill_1_1_44/Modified_Face&Sketch_1/SketchLine_9"), model.selection("FACE", "Fill_1_1_43/Modified_Face&Sketch_1/SketchLine_9"), model.selection("FACE", "Fill_1_1_51/Modified_Face&Sketch_1/SketchLine_9"), model.selection("FACE", "Fill_1_1_50/Modified_Face&Sketch_1/SketchLine_9"), model.selection("FACE", "Fill_1_1_42/Modified_Face&Sketch_1/SketchLine_9"), model.selection("FACE", "Fill_1_1_40/Modified_Face&Sketch_1/SketchLine_9"), model.selection("FACE", "Fill_1_1_48/Modified_Face&Sketch_1/SketchLine_9"), model.selection("FACE", "Fill_1_1_46/Modified_Face&Sketch_1/SketchLine_9"), model.selection("FACE", "Fill_1_1_38/Modified_Face&Sketch_1/SketchLine_9"), model.selection("FACE", "Fill_1_1_37/Modified_Face&Sketch_1/SketchLine_9"), model.selection("FACE", "Fill_1_1_45/Modified_Face&Sketch_1/SketchLine_9"), model.selection("FACE", "Fill_1_1_39/Modified_Face&Sketch_1/SketchLine_9"), model.selection("FACE", "Fill_1_1_47/Modified_Face&Sketch_1/SketchLine_9"), model.selection("FACE", "Fill_1_1_49/Modified_Face&Sketch_1/SketchLine_9"), model.selection("FACE", "Fill_1_1_41/Modified_Face&Sketch_1/SketchLine_9")]
+Group_10 = model.addGroup(Part_2_doc, Group_10_objects)
+Group_10.setName("CONTACT_VIS")
+Group_10.result().setName("CONTACT_VIS")
+Translation_1 = model.addTranslation(Part_2_doc, [model.selection("COMPSOLID", "Fill_1_1")], 0, 100, 0)
+AngularCopy_1 = model.addMultiRotation(Part_2_doc, [model.selection("COMPSOLID", "Translation_1_1")], model.selection("EDGE", "PartSet/OX"), 4)
+model.do()
+
+# move groups to the end
+Part_2_doc.moveFeature(Group_1.feature(), AngularCopy_1.feature())
+Part_2_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_2_doc.moveFeature(Group_3.feature(), Group_2.feature())
+Part_2_doc.moveFeature(Group_4.feature(), Group_3.feature())
+Part_2_doc.moveFeature(Group_5.feature(), Group_4.feature())
+Part_2_doc.moveFeature(Group_6.feature(), Group_5.feature())
+Part_2_doc.moveFeature(Group_7.feature(), Group_6.feature())
+Part_2_doc.moveFeature(Group_8.feature(), Group_7.feature())
+Part_2_doc.moveFeature(Group_9.feature(), Group_8.feature())
+Part_2_doc.moveFeature(Group_10.feature(), Group_9.feature())
+model.end()
+
+from ModelAPI import *
+
+aFactory = ModelAPI_Session.get().validators()
+
+# Check groups
+a = 0
+num_in_groups = [48, 144, 80, 4, 4, 4, 4, 4, 32, 192]
+for i in range(Part_2_doc.size("Groups")):
+ GroupFeature = Part_2_doc.feature(objectToResult(Part_2_doc.object("Groups", i)))
+ assert(aFactory.validate(GroupFeature))
+ assert(GroupFeature.selectionList("group_list").size() == num_in_groups[a])
+ a = a + 1
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# -*- coding: utf-8 -*-
+
+from salome.shaper import model
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "d", "8")
+model.addParameter(Part_1_doc, "nb", "3")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_1.addCircle(-34.12026714434272, 28.71281409244911, 1.619211673722419)
+SketchCircle_2 = Sketch_1.addCircle(-34.12026714434272, 28.71281409244911, 3.180589706721861)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchCircle_2.center())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("WIRE_2", (-35.73947881806514, 28.71281409244911, 0))], model.selection(), 2, -1)
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", (-37.30085685106458, 28.71281409244911, 0))], model.selection(), 5, 0)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("COMPOUND", "all-in-Extrusion_1"), model.selection("COMPOUND", "all-in-Extrusion_2")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", (-34.12026714434272, 28.71281409244911, 1.5))])
+Group_1.setName("Group_dechets")
+Group_1.result().setName("Group_dechets")
+Group_2 = model.addGroup(Part_1_doc, [model.selection("SOLID", (-34.12026714434272, 28.71281409244911, 2.35984679315518))])
+Group_2.setName("Group_colis")
+Group_2.result().setName("Group_colis")
+LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("COMPSOLID", (-34.12026714434272, 28.71281409244911, 2.5))], model.selection("EDGE", "PartSet/OX"), "d", "nb", model.selection("EDGE", "PartSet/OY"), "d", "nb")
+model.do()
+# move groups to the end
+Part_1_doc.moveFeature(Group_1.feature(), LinearCopy_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+model.end()
+
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+
+# number of solids should be multiplyed by linear copy
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 9)
+assert(aFactory.validate(Group_1.feature()))
+# checkthat solids in the first group are small, like the origin
+for i in range(9):
+ delta = GeomAlgoAPI_ShapeTools_volume(selectionList.value(i).value()) - 8.236773528312948
+ assert(fabs(delta) < 1.e-5)
+
+# same-plane faces should be merged
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 9)
+assert(aFactory.validate(Group_2.feature()))
+
+# checkthat solids in the secong group are big, like the origin
+for i in range(9):
+ delta = GeomAlgoAPI_ShapeTools_volume(selectionList.value(i).value()) - 150.66735294710597
+ assert(fabs(delta) < 1.e-5)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# -*- coding: utf-8 -*-
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
+SketchLine_1 = Sketch_1.addLine(6.188, 9.025, 6.188, -3.45)
+SketchLine_2 = Sketch_1.addLine(6.188, -3.45, 0, -3.45)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(0, -3.45, 0, -6.449999999999999)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(0, -6.449999999999999, 7.782, -6.45)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(7.782, -6.45, 7.782, -3.45)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(7.782, -3.45, 6.538, -3.45)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchLine_7 = Sketch_1.addLine(6.538, -3.45, 6.538, -2.4)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchLine_8 = Sketch_1.addLine(6.538, -2.4, 6.375999999999999, -2.25)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchLine_9 = Sketch_1.addLine(6.375999999999999, -2.25, 6.375999999999999, 9.025)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchLine_10 = Sketch_1.addLine(6.375999999999999, 9.025, 6.188, 9.025)
+SketchLine_10.setAuxiliary(True)
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_10.endPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_10.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_2.result())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_6.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_4.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_3.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_1.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_9.result())
+SketchConstraintVertical_5 = Sketch_1.setVertical(SketchLine_7.result())
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OZ"), False)
+SketchLine_11 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_3.startPoint(), SketchLine_11.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_11).startPoint(), SketchLine_2.result(), 3.45, True)
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_3.result(), 3)
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_12 = SketchProjection_2.createdFeature()
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchLine_1.startPoint(), SketchLine_12.result(), 9.025, True)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_10.result(), 0.188)
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchLine_8.endPoint(), SketchLine_7.endPoint(), 0.15)
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_2.result())
+SketchConstraintDistance_3 = Sketch_1.setDistance(SketchLine_6.endPoint(), SketchLine_1.result(), 0.35, True)
+SketchConstraintDistance_4 = Sketch_1.setDistance(SketchLine_8.endPoint(), SketchLine_12.result(), 2.25, True)
+SketchConstraintDistance_5 = Sketch_1.setDistance(SketchLine_2.startPoint(), SketchLine_11.result(), 6.188, True)
+SketchLine_13 = Sketch_1.addLine(7.032, -4.050000000000001, 5.532, -4.050000000000001)
+SketchLine_14 = Sketch_1.addLine(5.532, -4.050000000000001, 5.532, -5.850000000000001)
+SketchLine_15 = Sketch_1.addLine(5.532, -5.850000000000001, 7.032, -5.850000000000001)
+SketchLine_16 = Sketch_1.addLine(7.032, -5.850000000000001, 7.032, -4.050000000000001)
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchLine_16.endPoint(), SketchLine_13.startPoint())
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchLine_13.endPoint(), SketchLine_14.startPoint())
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchLine_14.endPoint(), SketchLine_15.startPoint())
+SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchLine_15.endPoint(), SketchLine_16.startPoint())
+SketchConstraintHorizontal_5 = Sketch_1.setHorizontal(SketchLine_13.result())
+SketchConstraintVertical_6 = Sketch_1.setVertical(SketchLine_14.result())
+SketchConstraintHorizontal_6 = Sketch_1.setHorizontal(SketchLine_15.result())
+SketchConstraintVertical_7 = Sketch_1.setVertical(SketchLine_16.result())
+SketchLine_17 = Sketch_1.addLine(6.282, 9.025000000000013, 6.282, -4.050000000000002)
+SketchLine_17.setAuxiliary(True)
+SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchLine_17.startPoint(), SketchLine_10.result())
+SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchLine_17.endPoint(), SketchLine_13.result())
+SketchConstraintVertical_8 = Sketch_1.setVertical(SketchLine_17.result())
+SketchConstraintMiddle_1 = Sketch_1.setMiddlePoint(SketchLine_17.startPoint(), SketchLine_10.result())
+SketchConstraintMiddle_2 = Sketch_1.setMiddlePoint(SketchLine_17.endPoint(), SketchLine_13.result())
+SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_13.result(), 1.5)
+SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_16.result(), 1.8)
+SketchConstraintDistance_6 = Sketch_1.setDistance(SketchLine_17.endPoint(), SketchLine_5.result(), 1.5, True)
+SketchConstraintDistance_7 = Sketch_1.setDistance(SketchLine_14.startPoint(), SketchLine_2.result(), 0.6, True)
+SketchLine_18 = Sketch_1.addLine(6.375999999999999, 9.025, 6.537999999999999, 9.186999999999999)
+SketchConstraintCoincidence_19 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_18.startPoint())
+SketchLine_19 = Sketch_1.addLine(6.537999999999999, 9.186999999999999, 6.537999999999999, 10.256)
+SketchConstraintCoincidence_20 = Sketch_1.setCoincident(SketchLine_18.endPoint(), SketchLine_19.startPoint())
+SketchLine_20 = Sketch_1.addLine(6.537999999999999, 10.256, 6.188, 10.256)
+SketchConstraintCoincidence_21 = Sketch_1.setCoincident(SketchLine_19.endPoint(), SketchLine_20.startPoint())
+SketchLine_21 = Sketch_1.addLine(6.188, 10.256, 4.938, 10.97786688777512)
+SketchConstraintCoincidence_22 = Sketch_1.setCoincident(SketchLine_20.endPoint(), SketchLine_21.startPoint())
+SketchLine_22 = Sketch_1.addLine(6.188, 9.025, 6.082, 9.532)
+SketchConstraintCoincidence_23 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_22.startPoint())
+SketchArc_1 = Sketch_1.addArc(4.793854309433998, 9.262673655435936, 6.082, 9.532, 5.676829966640704, 10.23848613167324, False)
+SketchConstraintCoincidence_24 = Sketch_1.setCoincident(SketchLine_22.endPoint(), SketchArc_1.startPoint())
+SketchLine_23 = Sketch_1.addLine(5.676829966640704, 10.23848613167324, 5.417460848824595, 10.45671600291324)
+SketchConstraintCoincidence_25 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_23.startPoint())
+SketchLine_24 = Sketch_1.addLine(5.417460848824595, 10.45671600291324, 5.143396378647488, 10.65615482129427)
+SketchConstraintCoincidence_26 = Sketch_1.setCoincident(SketchLine_23.endPoint(), SketchLine_24.startPoint())
+SketchLine_25 = Sketch_1.addLine(5.143396378647488, 10.65615482129427, 4.856000000000001, 10.83583872155447)
+SketchConstraintCoincidence_27 = Sketch_1.setCoincident(SketchLine_24.endPoint(), SketchLine_25.startPoint())
+SketchArc_2 = Sketch_1.addArc(0, 2.425, 4.856000000000001, 10.83583872155447, 0, 12.137, False)
+SketchConstraintCoincidence_28 = Sketch_1.setCoincident(SketchLine_25.endPoint(), SketchArc_2.startPoint())
+SketchArc_3 = Sketch_1.addArc(0, 2.425, 4.938, 10.97786688777512, 0, 12.301, False)
+SketchConstraintCoincidence_29 = Sketch_1.setCoincident(SketchLine_21.endPoint(), SketchArc_3.startPoint())
+SketchConstraintCoincidence_30 = Sketch_1.setCoincident(SketchArc_3.center(), SketchArc_2.center())
+SketchConstraintCoincidence_31 = Sketch_1.setCoincident(SketchArc_2.center(), SketchLine_11.result())
+SketchArc_4 = Sketch_1.addArc(0, 2.425, 0, 12.219, 6.538, 9.717255618119815, True)
+SketchArc_4.setAuxiliary(True)
+SketchConstraintCoincidence_32 = Sketch_1.setCoincident(SketchArc_2.center(), SketchArc_4.center())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_4.results()[1], 9.794)
+SketchLine_26 = Sketch_1.addLine(0, 12.301, 0, 12.137)
+SketchConstraintCoincidence_33 = Sketch_1.setCoincident(SketchArc_3.endPoint(), SketchLine_26.startPoint())
+SketchConstraintCoincidence_34 = Sketch_1.setCoincident(SketchArc_2.endPoint(), SketchLine_26.endPoint())
+SketchConstraintCoincidence_35 = Sketch_1.setCoincident(SketchLine_26.startPoint(), SketchLine_11.result())
+SketchConstraintCoincidence_36 = Sketch_1.setCoincident(SketchLine_26.endPoint(), SketchArc_2.endPoint())
+SketchConstraintCoincidence_37 = Sketch_1.setCoincident(SketchLine_11.result(), SketchLine_26.endPoint())
+SketchConstraintCoincidence_38 = Sketch_1.setCoincident(SketchArc_4.startPoint(), SketchLine_26.result())
+SketchConstraintMiddle_3 = Sketch_1.setMiddlePoint(SketchArc_4.startPoint(), SketchLine_26.result())
+SketchConstraintDistance_8 = Sketch_1.setDistance(SketchLine_26.startPoint(), SketchArc_4.startPoint(), 0.082, True)
+SketchConstraintHorizontal_7 = Sketch_1.setHorizontal(SketchLine_20.result())
+SketchConstraintVertical_9 = Sketch_1.setVertical(SketchLine_19.result())
+SketchConstraintDistance_9 = Sketch_1.setDistance(SketchArc_3.center(), SketchLine_12.result(), 2.425, True)
+SketchLine_27 = Sketch_1.addLine(4.856000000000001, 10.83583872155447, 0, 2.425)
+SketchLine_27.setAuxiliary(True)
+SketchConstraintCoincidence_39 = Sketch_1.setCoincident(SketchLine_25.endPoint(), SketchLine_27.startPoint())
+SketchConstraintCoincidence_40 = Sketch_1.setCoincident(SketchArc_2.center(), SketchLine_27.endPoint())
+SketchLine_28 = Sketch_1.addLine(5.143396378647488, 10.65615482129427, 0, 2.425)
+SketchLine_28.setAuxiliary(True)
+SketchConstraintCoincidence_41 = Sketch_1.setCoincident(SketchLine_24.endPoint(), SketchLine_28.startPoint())
+SketchConstraintCoincidence_42 = Sketch_1.setCoincident(SketchArc_2.center(), SketchLine_28.endPoint())
+SketchLine_29 = Sketch_1.addLine(0, 2.425, 5.417460848824595, 10.45671600291324)
+SketchLine_29.setAuxiliary(True)
+SketchConstraintCoincidence_43 = Sketch_1.setCoincident(SketchArc_2.center(), SketchLine_29.startPoint())
+SketchConstraintCoincidence_44 = Sketch_1.setCoincident(SketchLine_23.endPoint(), SketchLine_29.endPoint())
+SketchLine_30 = Sketch_1.addLine(5.676829966640704, 10.23848613167324, 0, 2.425)
+SketchLine_30.setAuxiliary(True)
+SketchConstraintCoincidence_45 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_30.startPoint())
+SketchConstraintCoincidence_46 = Sketch_1.setCoincident(SketchArc_2.center(), SketchLine_30.endPoint())
+SketchConstraintAngle_1 = Sketch_1.setAngle(SketchLine_27.result(), SketchLine_11.result(), 29.99999999999999)
+SketchConstraintAngle_2 = Sketch_1.setAngle(SketchLine_28.result(), SketchLine_11.result(), 32.00000000000001)
+SketchConstraintAngle_3 = Sketch_1.setAngle(SketchLine_29.result(), SketchLine_11.result(), 34.00000000000001)
+SketchConstraintAngle_4 = Sketch_1.setAngle(SketchLine_30.result(), SketchLine_11.result(), 36.00000000000001)
+SketchConstraintAngle_5 = Sketch_1.setAngleComplementary(SketchLine_18.result(), SketchLine_10.result(), 44.99999999999972)
+SketchConstraintLength_5 = Sketch_1.setLength(SketchLine_20.result(), 0.35)
+SketchConstraintDistance_10 = Sketch_1.setDistance(SketchLine_20.startPoint(), SketchLine_12.result(), 10.256, True)
+SketchConstraintDistance_10.setName("SketchConstraintDistance_13")
+SketchConstraintDistance_11 = Sketch_1.setDistance(SketchLine_22.endPoint(), SketchLine_1.result(), 0.106, True)
+SketchConstraintDistance_11.setName("SketchConstraintDistance_14")
+SketchConstraintDistance_12 = Sketch_1.setDistance(SketchLine_22.endPoint(), SketchLine_12.result(), 9.532, True)
+SketchConstraintDistance_12.setName("SketchConstraintDistance_15")
+SketchLine_31 = Sketch_1.addLine(4.856000000000001, 10.83583872155447, 4.938, 10.97786688777512)
+SketchLine_31.setAuxiliary(True)
+SketchConstraintCoincidence_47 = Sketch_1.setCoincident(SketchLine_25.endPoint(), SketchLine_31.startPoint())
+SketchConstraintCoincidence_47.setName("SketchConstraintCoincidence_48")
+SketchConstraintCoincidence_48 = Sketch_1.setCoincident(SketchLine_21.endPoint(), SketchLine_31.endPoint())
+SketchConstraintCoincidence_48.setName("SketchConstraintCoincidence_49")
+SketchConstraintCollinear_1 = Sketch_1.setCollinear(SketchLine_31.result(), SketchLine_27.result())
+SketchConstraintCoincidence_49 = Sketch_1.setCoincident(SketchArc_4.endPoint(), SketchLine_19.result())
+SketchConstraintCoincidence_49.setName("SketchConstraintCoincidence_50")
+SketchConstraintRadius_2 = Sketch_1.setRadius(SketchArc_1.results()[1], 1.316)
+SketchLine_32 = Sketch_1.addLine(5.143396378647488, 10.65615482129427, 5.236653048654413, 10.80539669036974)
+SketchLine_32.setAuxiliary(True)
+SketchConstraintCoincidence_50 = Sketch_1.setCoincident(SketchLine_24.endPoint(), SketchLine_32.startPoint())
+SketchConstraintCoincidence_50.setName("SketchConstraintCoincidence_51")
+SketchConstraintCoincidence_51 = Sketch_1.setCoincident(SketchLine_32.endPoint(), SketchLine_21.result())
+SketchConstraintCoincidence_51.setName("SketchConstraintCoincidence_52")
+SketchLine_33 = Sketch_1.addLine(5.417460848824595, 10.45671600291324, 5.536033128724348, 10.63250663704018)
+SketchLine_33.setAuxiliary(True)
+SketchConstraintCoincidence_52 = Sketch_1.setCoincident(SketchLine_23.endPoint(), SketchLine_33.startPoint())
+SketchConstraintCoincidence_52.setName("SketchConstraintCoincidence_53")
+SketchConstraintCoincidence_53 = Sketch_1.setCoincident(SketchLine_33.endPoint(), SketchLine_21.result())
+SketchConstraintCoincidence_53.setName("SketchConstraintCoincidence_54")
+SketchLine_34 = Sketch_1.addLine(5.676829966640704, 10.23848613167324, 5.836876630976977, 10.4587714668974)
+SketchLine_34.setAuxiliary(True)
+SketchConstraintCoincidence_54 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_34.startPoint())
+SketchConstraintCoincidence_54.setName("SketchConstraintCoincidence_55")
+SketchConstraintCoincidence_55 = Sketch_1.setCoincident(SketchLine_34.endPoint(), SketchLine_21.result())
+SketchConstraintCoincidence_55.setName("SketchConstraintCoincidence_56")
+SketchConstraintCollinear_2 = Sketch_1.setCollinear(SketchLine_32.result(), SketchLine_28.result())
+SketchConstraintCollinear_3 = Sketch_1.setCollinear(SketchLine_33.result(), SketchLine_29.result())
+SketchConstraintCollinear_4 = Sketch_1.setCollinear(SketchLine_34.result(), SketchLine_30.result())
+SketchPoint_1 = Sketch_1.addPoint(5.190029273900029, 10.73078305375602)
+SketchConstraintCoincidence_56 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_4.results()[1])
+SketchConstraintCoincidence_56.setName("SketchConstraintCoincidence_57")
+SketchConstraintCoincidence_57 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchLine_32.result())
+SketchConstraintCoincidence_57.setName("SketchConstraintCoincidence_58")
+SketchConstraintDistance_13 = Sketch_1.setDistance(SketchLine_25.startPoint(), SketchPoint_1.coordinates(), 0.08799999999999999, True)
+SketchConstraintDistance_13.setName("SketchConstraintDistance_16")
+SketchPoint_2 = Sketch_1.addPoint(5.476735296592504, 10.54459398560407)
+SketchConstraintCoincidence_58 = Sketch_1.setCoincident(SketchPoint_2.coordinates(), SketchArc_4.results()[1])
+SketchConstraintCoincidence_58.setName("SketchConstraintCoincidence_59")
+SketchConstraintCoincidence_59 = Sketch_1.setCoincident(SketchLine_33.result(), SketchPoint_2.coordinates())
+SketchConstraintCoincidence_59.setName("SketchConstraintCoincidence_60")
+SketchConstraintDistance_14 = Sketch_1.setDistance(SketchLine_24.startPoint(), SketchPoint_2.coordinates(), 0.106, True)
+SketchConstraintDistance_14.setName("SketchConstraintDistance_17")
+SketchPoint_3 = Sketch_1.addPoint(5.756768760952494, 10.34851244290823)
+SketchConstraintCoincidence_60 = Sketch_1.setCoincident(SketchPoint_3.coordinates(), SketchArc_4.results()[1])
+SketchConstraintCoincidence_60.setName("SketchConstraintCoincidence_61")
+SketchConstraintCoincidence_61 = Sketch_1.setCoincident(SketchPoint_3.coordinates(), SketchLine_34.result())
+SketchConstraintCoincidence_61.setName("SketchConstraintCoincidence_62")
+SketchConstraintDistance_15 = Sketch_1.setDistance(SketchArc_1.endPoint(), SketchPoint_3.coordinates(), 0.136, True)
+SketchConstraintDistance_15.setName("SketchConstraintDistance_18")
+SketchConstraintCoincidence_62 = Sketch_1.setCoincident(SketchLine_21.startPoint(), SketchLine_1.result())
+SketchConstraintCoincidence_62.setName("SketchConstraintCoincidence_63")
+model.do()
+Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6f-SketchLine_7f-SketchLine_8f-SketchLine_9f-SketchLine_18f-SketchLine_19f-SketchLine_20f-SketchLine_21f-SketchArc_3_2f-SketchLine_26f-SketchArc_2_2r-SketchLine_25r-SketchLine_24r-SketchLine_23r-SketchArc_1_2r-SketchLine_22r-SketchLine_16r-SketchLine_15r-SketchLine_14r-SketchLine_13r")], model.selection("EDGE", "PartSet/OZ"), 360, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Revolution_1_1/Generated_Face&Sketch_1/SketchLine_4")])
+Group_1.setName("Base")
+Group_1.result().setName("Base")
+Group_2_objects = [model.selection("FACE", "Revolution_1_1/Generated_Face&Sketch_1/SketchLine_2"), model.selection("FACE", "Revolution_1_1/Generated_Face&Sketch_1/SketchLine_1"), model.selection("FACE", "Revolution_1_1/Generated_Face&Sketch_1/SketchLine_24"), model.selection("FACE", "Revolution_1_1/Generated_Face&Sketch_1/SketchArc_2_2"), model.selection("FACE", "Revolution_1_1/Generated_Face&Sketch_1/SketchLine_25"), model.selection("FACE", "Revolution_1_1/Generated_Face&Sketch_1/SketchLine_23"), model.selection("FACE", "Revolution_1_1/Generated_Face&Sketch_1/SketchLine_22"), model.selection("FACE", "Revolution_1_1/Generated_Face&Sketch_1/SketchArc_1_2")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_2.setName("Faces_int")
+Group_2.result().setName("Faces_int")
+Group_3_objects = [model.selection("FACE", "Revolution_1_1/Generated_Face&Sketch_1/SketchLine_16"), model.selection("FACE", "Revolution_1_1/Generated_Face&Sketch_1/SketchLine_13"), model.selection("FACE", "Revolution_1_1/Generated_Face&Sketch_1/SketchLine_14"), model.selection("FACE", "Revolution_1_1/Generated_Face&Sketch_1/SketchLine_15")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Group_3.setName("Faces_gallerie")
+Group_3.result().setName("Faces_gallerie")
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
+SketchLine_35 = Sketch_2.addLine(3.397674805046317, 12.11397308570391, 3.082152448528626, 11.21424138021434)
+SketchLine_36 = Sketch_2.addLine(3.241000000000001, 12.09482302308413, 3.241000000000001, 11.06850194037818)
+SketchLine_36.setAuxiliary(True)
+SketchConstraintVertical_10 = Sketch_2.setVertical(SketchLine_36.result())
+SketchPoint_4 = Sketch_2.addPoint(3.241, 11.66720509403099)
+SketchConstraintCoincidence_63 = Sketch_2.setCoincident(SketchPoint_4.coordinates(), SketchLine_35.result())
+SketchConstraintCoincidence_63.setName("SketchConstraintCoincidence_64")
+SketchConstraintCoincidence_64 = Sketch_2.setCoincident(SketchLine_36.result(), SketchPoint_4.coordinates())
+SketchConstraintCoincidence_64.setName("SketchConstraintCoincidence_65")
+SketchProjection_3 = Sketch_2.addProjection(model.selection("EDGE", "Sketch_1/SketchArc_4_2"), False)
+SketchArc_5 = SketchProjection_3.createdFeature()
+SketchConstraintCoincidence_65 = Sketch_2.setCoincident(SketchPoint_4.coordinates(), SketchArc_5.results()[1])
+SketchConstraintCoincidence_65.setName("SketchConstraintCoincidence_66")
+SketchConstraintAngle_6 = Sketch_2.setAngleComplementary(SketchLine_35.result(), SketchLine_36.result(), 160.675)
+SketchProjection_4 = Sketch_2.addProjection(model.selection("EDGE", "PartSet/OZ"), False)
+SketchLine_37 = SketchProjection_4.createdFeature()
+SketchConstraintDistance_16 = Sketch_2.setDistance(SketchPoint_4.coordinates(), SketchLine_37.result(), 3.241, True)
+SketchConstraintDistance_16.setName("SketchConstraintDistance_19")
+SketchLine_38 = Sketch_2.addLine(3.911629569238839, 11.53981731861503, 3.828898026216406, 11.30390315670624)
+SketchLine_39 = Sketch_2.addLine(3.828898026216406, 11.30390315670624, 4.057270795192212, 11.20218846558286)
+SketchConstraintCoincidence_66 = Sketch_2.setCoincident(SketchLine_38.endPoint(), SketchLine_39.startPoint())
+SketchConstraintCoincidence_66.setName("SketchConstraintCoincidence_67")
+SketchLine_40 = Sketch_2.addLine(4.057270795192212, 11.20218846558286, 4.140002338214646, 11.43810262749166)
+SketchLine_40.setAuxiliary(True)
+SketchConstraintCoincidence_67 = Sketch_2.setCoincident(SketchLine_39.endPoint(), SketchLine_40.startPoint())
+SketchConstraintCoincidence_67.setName("SketchConstraintCoincidence_68")
+SketchLine_41 = Sketch_2.addLine(4.140002338214646, 11.43810262749166, 3.911629569238839, 11.53981731861503)
+SketchConstraintCoincidence_68 = Sketch_2.setCoincident(SketchLine_40.endPoint(), SketchLine_41.startPoint())
+SketchConstraintCoincidence_68.setName("SketchConstraintCoincidence_69")
+SketchConstraintCoincidence_69 = Sketch_2.setCoincident(SketchLine_38.startPoint(), SketchLine_41.endPoint())
+SketchConstraintCoincidence_69.setName("SketchConstraintCoincidence_70")
+SketchLine_42 = Sketch_2.addLine(4.057270795192212, 11.20218846558286, 4.410949215071502, 11.07754130426779)
+SketchConstraintCoincidence_70 = Sketch_2.setCoincident(SketchLine_39.endPoint(), SketchLine_42.startPoint())
+SketchConstraintCoincidence_70.setName("SketchConstraintCoincidence_71")
+SketchProjection_5 = Sketch_2.addProjection(model.selection("EDGE", "Sketch_1/SketchArc_2_2"), False)
+SketchArc_6 = SketchProjection_5.createdFeature()
+SketchConstraintCoincidence_71 = Sketch_2.setCoincident(SketchLine_42.endPoint(), SketchArc_6.results()[1])
+SketchConstraintCoincidence_71.setName("SketchConstraintCoincidence_72")
+SketchLine_43 = Sketch_2.addLine(4.410949215071502, 11.07754130426779, 4.465704943014801, 11.23368068225505)
+SketchConstraintCoincidence_72 = Sketch_2.setCoincident(SketchLine_42.endPoint(), SketchLine_43.startPoint())
+SketchConstraintCoincidence_72.setName("SketchConstraintCoincidence_73")
+SketchProjection_6 = Sketch_2.addProjection(model.selection("EDGE", "Sketch_1/SketchArc_3_2"), False)
+SketchArc_7 = SketchProjection_6.createdFeature()
+SketchConstraintCoincidence_73 = Sketch_2.setCoincident(SketchLine_43.endPoint(), SketchArc_7.results()[1])
+SketchConstraintCoincidence_73.setName("SketchConstraintCoincidence_74")
+SketchLine_44 = Sketch_2.addLine(4.465704943014801, 11.23368068225505, 4.140002338214646, 11.43810262749166)
+SketchConstraintCoincidence_74 = Sketch_2.setCoincident(SketchLine_43.endPoint(), SketchLine_44.startPoint())
+SketchConstraintCoincidence_74.setName("SketchConstraintCoincidence_75")
+SketchConstraintCoincidence_75 = Sketch_2.setCoincident(SketchLine_40.endPoint(), SketchLine_44.endPoint())
+SketchConstraintCoincidence_75.setName("SketchConstraintCoincidence_76")
+SketchConstraintParallel_1 = Sketch_2.setParallel(SketchLine_38.result(), SketchLine_35.result())
+SketchConstraintParallel_2 = Sketch_2.setParallel(SketchLine_40.result(), SketchLine_38.result())
+SketchConstraintParallel_3 = Sketch_2.setParallel(SketchLine_43.result(), SketchLine_40.result())
+SketchConstraintLength_6 = Sketch_2.setLength(SketchLine_40.result(), 0.25)
+SketchConstraintEqual_1 = Sketch_2.setEqual(SketchLine_40.result(), SketchLine_38.result())
+SketchPoint_5 = Sketch_2.addPoint(3.87026379772762, 11.42186023766063)
+SketchConstraintCoincidence_76 = Sketch_2.setCoincident(SketchPoint_5.coordinates(), SketchLine_38.result())
+SketchConstraintCoincidence_76.setName("SketchConstraintCoincidence_77")
+SketchConstraintMiddle_4 = Sketch_2.setMiddlePoint(SketchPoint_5.coordinates(), SketchLine_38.result())
+SketchConstraintCoincidence_77 = Sketch_2.setCoincident(SketchPoint_5.coordinates(), SketchArc_5.results()[1])
+SketchConstraintCoincidence_77.setName("SketchConstraintCoincidence_78")
+SketchPoint_6 = Sketch_2.addPoint(4.09863656670343, 11.32014554653726)
+SketchConstraintCoincidence_78 = Sketch_2.setCoincident(SketchPoint_6.coordinates(), SketchLine_40.result())
+SketchConstraintCoincidence_78.setName("SketchConstraintCoincidence_79")
+SketchConstraintCoincidence_79 = Sketch_2.setCoincident(SketchPoint_6.coordinates(), SketchArc_5.results()[1])
+SketchConstraintCoincidence_79.setName("SketchConstraintCoincidence_80")
+SketchConstraintMiddle_5 = Sketch_2.setMiddlePoint(SketchPoint_6.coordinates(), SketchLine_40.result())
+SketchConstraintLength_7 = Sketch_2.setLength(SketchLine_41.result(), 0.25)
+SketchConstraintDistance_17 = Sketch_2.setDistance(SketchLine_38.startPoint(), SketchLine_35.result(), "1.35/2", True)
+SketchConstraintDistance_17.setName("SketchConstraintDistance_20")
+SketchConstraintDistance_18 = Sketch_2.setDistance(SketchLine_41.startPoint(), SketchLine_43.result(), 0.375, True)
+SketchConstraintDistance_18.setName("SketchConstraintDistance_21")
+SketchLine_45 = Sketch_2.addLine(3.911629569238839, 11.53981731861503, 3.397674805046317, 12.11397308570391)
+SketchConstraintCoincidence_80 = Sketch_2.setCoincident(SketchLine_38.startPoint(), SketchLine_45.startPoint())
+SketchConstraintCoincidence_80.setName("SketchConstraintCoincidence_81")
+SketchConstraintCoincidence_81 = Sketch_2.setCoincident(SketchLine_35.startPoint(), SketchLine_45.endPoint())
+SketchConstraintCoincidence_81.setName("SketchConstraintCoincidence_82")
+SketchLine_46 = Sketch_2.addLine(3.082152448528626, 11.21424138021434, 3.828898026216406, 11.30390315670624)
+SketchConstraintCoincidence_82 = Sketch_2.setCoincident(SketchLine_35.endPoint(), SketchLine_46.startPoint())
+SketchConstraintCoincidence_82.setName("SketchConstraintCoincidence_83")
+SketchConstraintCoincidence_83 = Sketch_2.setCoincident(SketchLine_38.endPoint(), SketchLine_46.endPoint())
+SketchConstraintCoincidence_83.setName("SketchConstraintCoincidence_84")
+model.do()
+Revolution_2 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_35r-SketchLine_46f-SketchLine_38r-SketchLine_45f")], model.selection("EDGE", "Sketch_2/SketchLine_35"), 360, 0)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Revolution_2_1")], model.selection("EDGE", "PartSet/OZ"), 2)
+Cut_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Revolution_1_1")], [model.selection("COMPOUND", "AngularCopy_1_1")])
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/XOY"), 3.6, False)
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchProjection_7 = Sketch_3.addProjection(model.selection("EDGE", "[Revolution_1_1/Generated_Face&Sketch_1/SketchLine_9][Revolution_1_1/Generated_Face&Sketch_1/SketchLine_8]"), True)
+SketchCircle_1 = SketchProjection_7.createdFeature()
+SketchProjection_8 = Sketch_3.addProjection(model.selection("EDGE", "[Revolution_1_1/Generated_Face&Sketch_1/SketchLine_1][Revolution_1_1/Generated_Face&Sketch_1/SketchLine_2]"), True)
+SketchCircle_2 = SketchProjection_8.createdFeature()
+SketchLine_47 = Sketch_3.addLine(6.067916611160706, -1.958, 6.166614630411087, -1.958)
+SketchConstraintCoincidence_84 = Sketch_3.setCoincident(SketchLine_47.startPoint(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_84.setName("SketchConstraintCoincidence_85")
+SketchArc_8 = Sketch_3.addArc(0, 0, 6.166614630411087, -1.958, 6.47, 0, False)
+SketchConstraintCoincidence_85 = Sketch_3.setCoincident(SketchLine_47.endPoint(), SketchArc_8.startPoint())
+SketchConstraintCoincidence_85.setName("SketchConstraintCoincidence_87")
+SketchConstraintHorizontal_8 = Sketch_3.setHorizontal(SketchLine_47.result())
+SketchProjection_9 = Sketch_3.addProjection(model.selection("EDGE", "PartSet/OX"), False)
+SketchLine_48 = SketchProjection_9.createdFeature()
+SketchLine_48.setName("SketchLine_49")
+SketchLine_48.result().setName("SketchLine_49")
+SketchConstraintDistance_19 = Sketch_3.setDistance(SketchLine_47.endPoint(), SketchLine_48.result(), 1.958, True)
+SketchConstraintDistance_19.setName("SketchConstraintDistance_23")
+SketchLine_49 = Sketch_3.addLine(5.870057921349673, -1.957999999999988, 5.858998207885032, -1.675999999999991)
+SketchLine_49.setName("SketchLine_50")
+SketchLine_49.result().setName("SketchLine_50")
+SketchConstraintCoincidence_86 = Sketch_3.setCoincident(SketchLine_49.startPoint(), SketchCircle_2.results()[1])
+SketchConstraintCoincidence_86.setName("SketchConstraintCoincidence_89")
+SketchConstraintCoincidence_87 = Sketch_3.setCoincident(SketchArc_8.endPoint(), SketchLine_48.result())
+SketchConstraintCoincidence_87.setName("SketchConstraintCoincidence_88")
+SketchArc_9 = Sketch_3.addArc(0, 0, 5.858998207885032, -1.675999999999991, 6.093999999999999, 0, False)
+SketchConstraintCoincidence_88 = Sketch_3.setCoincident(SketchLine_49.endPoint(), SketchArc_9.startPoint())
+SketchConstraintCoincidence_88.setName("SketchConstraintCoincidence_90")
+SketchConstraintCoincidence_89 = Sketch_3.setCoincident(SketchLine_48.result(), SketchArc_9.endPoint())
+SketchConstraintCoincidence_89.setName("SketchConstraintCoincidence_91")
+SketchConstraintCoincidence_90 = Sketch_3.setCoincident(SketchArc_9.center(), SketchAPI_Line(SketchLine_48).startPoint())
+SketchConstraintCoincidence_90.setName("SketchConstraintCoincidence_92")
+SketchConstraintCoincidence_91 = Sketch_3.setCoincident(SketchArc_8.result(), SketchAPI_Line(SketchLine_48).startPoint())
+SketchConstraintCoincidence_91.setName("SketchConstraintCoincidence_93")
+SketchPoint_7 = Sketch_3.addPoint(6.188, 0)
+SketchConstraintCoincidence_92 = Sketch_3.setCoincident(SketchPoint_7.coordinates(), SketchCircle_2.results()[1])
+SketchConstraintCoincidence_92.setName("SketchConstraintCoincidence_94")
+SketchConstraintCoincidence_93 = Sketch_3.setCoincident(SketchPoint_7.coordinates(), SketchLine_48.result())
+SketchConstraintCoincidence_93.setName("SketchConstraintCoincidence_95")
+SketchPoint_8 = Sketch_3.addPoint(6.375999999999999, 0)
+SketchConstraintCoincidence_94 = Sketch_3.setCoincident(SketchPoint_8.coordinates(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_94.setName("SketchConstraintCoincidence_96")
+SketchConstraintCoincidence_95 = Sketch_3.setCoincident(SketchPoint_8.coordinates(), SketchLine_48.result())
+SketchConstraintCoincidence_95.setName("SketchConstraintCoincidence_97")
+SketchConstraintDistance_20 = Sketch_3.setDistance(SketchPoint_8.coordinates(), SketchArc_8.endPoint(), 0.094, True)
+SketchConstraintDistance_20.setName("SketchConstraintDistance_22")
+SketchConstraintDistance_21 = Sketch_3.setDistance(SketchArc_9.endPoint(), SketchPoint_7.coordinates(), 0.094, True)
+SketchConstraintDistance_21.setName("SketchConstraintDistance_24")
+SketchConstraintDistance_22 = Sketch_3.setDistance(SketchArc_9.startPoint(), SketchLine_47.result(), 0.282, True)
+SketchConstraintDistance_22.setName("SketchConstraintDistance_25")
+SketchConstraintCoincidence_96 = Sketch_3.setCoincident(SketchLine_49.startPoint(), SketchLine_47.result())
+SketchConstraintCoincidence_96.setName("SketchConstraintCoincidence_98")
+SketchConstraintMirror_1_objects = [SketchArc_9.results()[1], SketchLine_49.result(), SketchLine_47.result(), SketchArc_8.results()[1]]
+SketchConstraintMirror_1 = Sketch_3.addMirror(SketchLine_48.result(), SketchConstraintMirror_1_objects)
+[SketchArc_10, SketchLine_50, SketchLine_51, SketchArc_11] = SketchConstraintMirror_1.mirrored()
+SketchLine_51.setName("SketchLine_52")
+SketchLine_51.result().setName("SketchLine_52")
+SketchLine_50.setName("SketchLine_51")
+SketchLine_50.result().setName("SketchLine_51")
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchProjection_8f-SketchProjection_8f-SketchLine_51f-SketchArc_10_2r-SketchArc_9_2r-SketchLine_50r"), model.selection("FACE", "Sketch_3/Face-SketchProjection_7r-SketchLine_47f-SketchArc_8_2f-SketchArc_11_2f-SketchLine_52r-SketchProjection_7r")], model.selection(), 0, 4.2)
+Sketch_4 = model.addSketch(Part_1_doc, model.standardPlane("YOZ"))
+SketchLine_52 = Sketch_4.addLine(0.75, 2.1, -0.75, 2.1)
+SketchLine_52.setName("SketchLine_53")
+SketchLine_52.result().setName("SketchLine_53")
+SketchLine_53 = Sketch_4.addLine(-0.75, 2.1, -0.75, 0.3)
+SketchLine_53.setName("SketchLine_54")
+SketchLine_53.result().setName("SketchLine_54")
+SketchLine_54 = Sketch_4.addLine(-0.75, 0.3, 0.75, 0.3)
+SketchLine_54.setName("SketchLine_55")
+SketchLine_54.result().setName("SketchLine_55")
+SketchLine_55 = Sketch_4.addLine(0.75, 0.3, 0.75, 2.1)
+SketchLine_55.setName("SketchLine_56")
+SketchLine_55.result().setName("SketchLine_56")
+SketchConstraintCoincidence_97 = Sketch_4.setCoincident(SketchLine_55.endPoint(), SketchLine_52.startPoint())
+SketchConstraintCoincidence_97.setName("SketchConstraintCoincidence_99")
+SketchConstraintCoincidence_98 = Sketch_4.setCoincident(SketchLine_52.endPoint(), SketchLine_53.startPoint())
+SketchConstraintCoincidence_98.setName("SketchConstraintCoincidence_100")
+SketchConstraintCoincidence_99 = Sketch_4.setCoincident(SketchLine_53.endPoint(), SketchLine_54.startPoint())
+SketchConstraintCoincidence_99.setName("SketchConstraintCoincidence_101")
+SketchConstraintCoincidence_100 = Sketch_4.setCoincident(SketchLine_54.endPoint(), SketchLine_55.startPoint())
+SketchConstraintCoincidence_100.setName("SketchConstraintCoincidence_102")
+SketchConstraintHorizontal_9 = Sketch_4.setHorizontal(SketchLine_52.result())
+SketchConstraintVertical_11 = Sketch_4.setVertical(SketchLine_53.result())
+SketchConstraintHorizontal_10 = Sketch_4.setHorizontal(SketchLine_54.result())
+SketchConstraintVertical_12 = Sketch_4.setVertical(SketchLine_55.result())
+SketchProjection_10 = Sketch_4.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_56 = SketchProjection_10.createdFeature()
+SketchLine_56.setName("SketchLine_57")
+SketchLine_56.result().setName("SketchLine_57")
+SketchConstraintDistance_23 = Sketch_4.setDistance(SketchLine_52.startPoint(), SketchLine_56.result(), 2.1, True)
+SketchConstraintDistance_23.setName("SketchConstraintDistance_26")
+SketchConstraintDistance_24 = Sketch_4.setDistance(SketchLine_54.endPoint(), SketchLine_56.result(), 0.3, True)
+SketchConstraintDistance_24.setName("SketchConstraintDistance_27")
+SketchPoint_9 = Sketch_4.addPoint(0, 2.1)
+SketchConstraintCoincidence_101 = Sketch_4.setCoincident(SketchPoint_9.coordinates(), SketchLine_52.result())
+SketchConstraintCoincidence_101.setName("SketchConstraintCoincidence_103")
+SketchProjection_11 = Sketch_4.addProjection(model.selection("EDGE", "PartSet/OZ"), False)
+SketchLine_57 = SketchProjection_11.createdFeature()
+SketchLine_57.setName("SketchLine_58")
+SketchLine_57.result().setName("SketchLine_58")
+SketchConstraintCoincidence_102 = Sketch_4.setCoincident(SketchPoint_9.coordinates(), SketchLine_57.result())
+SketchConstraintCoincidence_102.setName("SketchConstraintCoincidence_104")
+SketchConstraintMiddle_6 = Sketch_4.setMiddlePoint(SketchPoint_9.coordinates(), SketchLine_52.result())
+SketchConstraintDistance_25 = Sketch_4.setDistance(SketchPoint_9.coordinates(), SketchLine_52.startPoint(), 0.75, True)
+SketchConstraintDistance_25.setName("SketchConstraintDistance_28")
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_4/Face-SketchLine_53r-SketchLine_54f-SketchLine_55f-SketchLine_56f")], model.selection(), 10, 0)
+Rotation_1_objects = [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_1_2"), model.selection("SOLID", "Extrusion_2_1")]
+Rotation_1 = model.addRotation(Part_1_doc, Rotation_1_objects, model.selection("EDGE", "PartSet/OZ"), -90)
+Cut_2_objects_1 = [model.selection("SOLID", "Cut_1_1"), model.selection("SOLID", "Rotation_1_1"), model.selection("SOLID", "Rotation_1_2")]
+Cut_2 = model.addCut(Part_1_doc, Cut_2_objects_1, [model.selection("SOLID", "Rotation_1_3")])
+Fuse_2_objects_1 = [model.selection("SOLID", "Cut_2_1"), model.selection("SOLID", "Cut_2_2"), model.selection("SOLID", "Cut_2_3")]
+Fuse_2 = model.addFuse(Part_1_doc, Fuse_2_objects_1, True)
+model.do()
+# move groups to the end
+Part_1_doc.moveFeature(Group_1.feature(), Fuse_2.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
+model.end()
+
+# check groups are correct
+from ModelAPI import *
+from GeomAPI import *
+aFactory = ModelAPI_Session.get().validators()
+
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 1)
+assert(aFactory.validate(Group_1.feature()))
+assert(Group_1.groupList().value(0).value().shapeType() == GeomAPI_Shape.FACE)
+
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 8)
+assert(aFactory.validate(Group_2.feature()))
+for i in range(8):
+ assert(Group_2.groupList().value(i).value().shapeType() == GeomAPI_Shape.FACE)
+
+selectionList = Group_3.feature().selectionList("group_list")
+assert(selectionList.size() == 4)
+assert(aFactory.validate(Group_3.feature()))
+for i in range(4):
+ assert(Group_3.groupList().value(i).value().shapeType() == GeomAPI_Shape.FACE)
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test that the history of Common operation works correctly after movement of groups after this Common feature
+
+# -*- coding: utf-8 -*-
+
+from salome.shaper import model
+from ModelAPI import *
+from GeomAPI import *
+from SketchAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_1.addCircle(5, 5, 7.071067811865464)
+SketchCircle_2 = Sketch_1.addCircle(0, 10, 7.071067811865464)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchCircle_2.results()[1])
+SketchCircle_3 = Sketch_1.addCircle(-5, 5, 7.071067811865464)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchCircle_2.center(), SketchCircle_3.results()[1])
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchCircle_3.center(), SketchCircle_2.results()[1])
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchCircle_1.results()[1], SketchCircle_2.center())
+SketchCircle_4 = Sketch_1.addCircle(0, 0, 7.071067811865464)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchCircle_4.center(), SketchCircle_3.results()[1])
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchCircle_4.results()[1], SketchCircle_3.center())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchCircle_4.results()[1], SketchCircle_1.center())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchCircle_1.center(), SketchCircle_3.center(), 10, True)
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchCircle_2.center(), SketchCircle_4.center(), 10, True)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "PartSet/Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchCircle_4.center(), SketchAPI_Point(SketchPoint_1).coordinates())
+SketchProjection_2 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_1 = SketchProjection_2.createdFeature()
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchCircle_2.center(), SketchLine_1.result())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_2 = Sketch_2.addLine(-5, 5, 0, 0)
+SketchProjection_3 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/SketchCircle_3_2__cc"), False)
+SketchPoint_2 = SketchProjection_3.createdFeature()
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_2.startPoint(), SketchPoint_2.result())
+SketchProjection_4 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/SketchCircle_4_2__cc"), False)
+SketchPoint_3 = SketchProjection_4.createdFeature()
+SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchLine_2.endPoint(), SketchPoint_3.result())
+SketchLine_3 = Sketch_2.addLine(0, 0, 5, 5)
+SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchProjection_5 = Sketch_2.addProjection(model.selection("VERTEX", "Sketch_1/SketchCircle_1_2__cc"), False)
+SketchPoint_4 = SketchProjection_5.createdFeature()
+SketchConstraintCoincidence_13 = Sketch_2.setCoincident(SketchLine_3.endPoint(), SketchPoint_4.result())
+SketchLine_4 = Sketch_2.addLine(-5, 5, 5, 5)
+SketchConstraintCoincidence_14 = Sketch_2.setCoincident(SketchLine_2.startPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_15 = Sketch_2.setCoincident(SketchLine_3.endPoint(), SketchLine_4.endPoint())
+SketchArc_1 = Sketch_2.addArc(-1.474514954580286e-16, 5, -5, 5, 5, 5, True)
+SketchConstraintCoincidence_16 = Sketch_2.setCoincident(SketchLine_4.result(), SketchArc_1.center())
+SketchConstraintCoincidence_17 = Sketch_2.setCoincident(SketchLine_2.startPoint(), SketchArc_1.startPoint())
+SketchConstraintCoincidence_18 = Sketch_2.setCoincident(SketchLine_4.endPoint(), SketchArc_1.endPoint())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "all-in-Sketch_1")], model.selection(), 10, 0)
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "all-in-Sketch_2")], model.selection(), 5, 5)
+Group_1_objects = [model.selection("SOLID", "Extrusion_1_1_13"), model.selection("SOLID", "Extrusion_1_1_10"), model.selection("SOLID", "Extrusion_1_1_7"), model.selection("SOLID", "Extrusion_1_1_9"), model.selection("SOLID", "Extrusion_1_1_1"), model.selection("SOLID", "Extrusion_1_1_5"), model.selection("SOLID", "Extrusion_1_1_4"), model.selection("SOLID", "Extrusion_1_1_12"), model.selection("SOLID", "Extrusion_1_1_11"), model.selection("SOLID", "Extrusion_1_1_8"), model.selection("SOLID", "Extrusion_1_1_3"), model.selection("SOLID", "Extrusion_1_1_6"), model.selection("SOLID", "Extrusion_1_1_2")]
+Group_1 = model.addGroup(Part_1_doc, Group_1_objects)
+Group_2 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Extrusion_2_1_2"), model.selection("SOLID", "Extrusion_2_1_1")])
+Group_3_objects = [model.selection("FACE", "Extrusion_1_1_7/From_Face"), model.selection("FACE", "Extrusion_1_1_1/From_Face"), model.selection("FACE", "Extrusion_1_1_9/From_Face"), model.selection("FACE", "Extrusion_1_1_12/From_Face"), model.selection("FACE", "Extrusion_1_1_4/From_Face"), model.selection("FACE", "Extrusion_1_1_5/From_Face"), model.selection("FACE", "Extrusion_1_1_8/From_Face"), model.selection("FACE", "Extrusion_1_1_11/From_Face"), model.selection("FACE", "Extrusion_1_1_6/From_Face"), model.selection("FACE", "Extrusion_1_1_2/From_Face"), model.selection("FACE", "Extrusion_1_1_3/From_Face"), model.selection("FACE", "Extrusion_1_1_10/From_Face")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Group_4_objects = [model.selection("FACE", "Extrusion_2_1_2/Generated_Face&Sketch_2/SketchLine_4"), model.selection("FACE", "Extrusion_2_1_2/Generated_Face&Sketch_2/SketchArc_1_2"), model.selection("FACE", "Extrusion_2_1_2/From_Face"), model.selection("FACE", "Extrusion_2_1_2/To_Face"), model.selection("FACE", "Extrusion_2_1_1/Generated_Face&Sketch_2/SketchLine_2"), model.selection("FACE", "Extrusion_2_1_1/To_Face"), model.selection("FACE", "Extrusion_2_1_1/From_Face"), model.selection("FACE", "Extrusion_2_1_1/Generated_Face&Sketch_2/SketchLine_4"), model.selection("FACE", "Extrusion_2_1_1/Generated_Face&Sketch_2/SketchLine_3")]
+Group_4 = model.addGroup(Part_1_doc, Group_4_objects)
+Common_1 = model.addCommon(Part_1_doc, [model.selection("COMPSOLID", "Extrusion_1_1"), model.selection("COMPSOLID", "Extrusion_2_1")])
+Common_1.result().subResult(0).setColor(254, 254, 127)
+Common_1.result().subResult(1).setColor(204, 102, 204)
+Common_1.result().subResult(2).setColor(51, 102, 102)
+Common_1.result().subResult(3).setColor(0, 153, 0)
+Common_1.result().subResult(4).setColor(254, 0, 0)
+Common_1.result().subResult(5).setColor(204, 0, 204)
+Common_1.result().subResult(6).setColor(102, 0, 0)
+Common_1.result().subResult(7).setColor(0, 0, 153)
+Common_1.result().subResult(8).setColor(0, 0, 204)
+Common_1.result().subResult(9).setColor(0, 0, 204)
+Common_1.result().subResult(10).setColor(0, 153, 0)
+Common_1.result().subResult(11).setColor(127, 127, 254)
+model.do()
+# move groups after the Common
+Part_1_doc.moveFeature(Group_1.feature(), Common_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
+Part_1_doc.moveFeature(Group_4.feature(), Group_3.feature())
+model.end()
+
+# check groups are correct
+aFactory = ModelAPI_Session.get().validators()
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 12)
+assert(aFactory.validate(Group_1.feature()))
+for i in range(12):
+ assert(Group_1.groupList().value(i).value().shapeType() == GeomAPI_Shape.SOLID)
+
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 12)
+assert(aFactory.validate(Group_2.feature()))
+for i in range(12):
+ assert(Group_2.groupList().value(i).value().shapeType() == GeomAPI_Shape.SOLID)
+
+selectionList = Group_3.feature().selectionList("group_list")
+assert(selectionList.size() == 12)
+assert(aFactory.validate(Group_3.feature()))
+for i in range(12):
+ assert(Group_3.groupList().value(i).value().shapeType() == GeomAPI_Shape.FACE)
+
+selectionList = Group_4.feature().selectionList("group_list")
+assert(selectionList.size() == 22)
+assert(aFactory.validate(Group_4.feature()))
+for i in range(22):
+ assert(Group_4.groupList().value(i).value().shapeType() == GeomAPI_Shape.FACE)
+
+assert(model.checkPythonDump(model.ModelHighAPI.CHECK_NAMING))
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test that the history of Cut operation works correctly after movement of groups after this Cut feature:
+# cut tools are deleted, cut objects are correctly transformed to and divided if needed
+
+# -*- coding: utf-8 -*-
+
+from salome.shaper import model
+from ModelAPI import *
+from GeomAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_1.addCircle(-10.57884322822754, 25.90966115484096, 9.63424990252037)
+SketchLine_1 = Sketch_1.addLine(-18.29572175958338, 20.14177099321736, -2.288684850537554, 30.81802598002054)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchCircle_1.results()[1])
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_2 = Sketch_2.addLine(7.424373233594292, 20.04016872303595, -10.19950738916256, 28.60837438423646)
+SketchLine_3 = Sketch_2.addLine(-10.19950738916256, 28.60837438423646, 10.7835313495703, 29.11992811073657)
+SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_2.addLine(10.7835313495703, 29.11992811073657, 7.424373233594292, 20.04016872303595)
+SketchConstraintCoincidence_4 = Sketch_2.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchLine_2.startPoint(), SketchLine_4.endPoint())
+SketchLine_5 = Sketch_2.addLine(-10.19950738916256, 28.60837438423646, 9.111243103183778, 24.59975538297626)
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_2.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_4.result())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "all-in-Sketch_1"), model.selection("COMPOUND", "all-in-Sketch_2")], model.selection(), 10, 0)
+Group_1_objects = [model.selection("SOLID", "Extrusion_1_1_2"), model.selection("SOLID", "Extrusion_1_1_1"), model.selection("SOLID", "Extrusion_1_2_2"), model.selection("SOLID", "Extrusion_1_2_1")]
+Group_1 = model.addGroup(Part_1_doc, Group_1_objects)
+Group_2_objects = [model.selection("FACE", "Extrusion_1_1_2/Generated_Face&Sketch_1/SketchLine_1"), model.selection("FACE", "Extrusion_1_1_2/To_Face"), model.selection("FACE", "Extrusion_1_2_2/To_Face")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Cut_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1_2")], [model.selection("SOLID", "Extrusion_1_2_2")])
+model.do()
+# move groups after the Cut
+Part_1_doc.moveFeature(Group_1.feature(), Cut_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+model.end()
+
+# check groups are correct
+aFactory = ModelAPI_Session.get().validators()
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 2)
+assert(aFactory.validate(Group_1.feature()))
+for i in range(2):
+ assert(Group_1.groupList().value(i).value().shapeType() == GeomAPI_Shape.SOLID)
+
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 3)
+assert(aFactory.validate(Group_2.feature()))
+for i in range(3):
+ assert(Group_2.groupList().value(i).value().shapeType() == GeomAPI_Shape.FACE)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# -*- coding: utf-8 -*-
+
+from salome.shaper import model
+from ModelAPI import *
+from GeomAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-9.826354679802961, 29.97660098522167, -30.22536945812809, 29.97660098522167)
+SketchLine_2 = Sketch_1.addLine(-30.22536945812809, 29.97660098522167, -30.22536945812809, 11.69211822660099)
+SketchLine_3 = Sketch_1.addLine(-30.22536945812809, 11.69211822660099, -9.826354679802961, 11.69211822660099)
+SketchLine_4 = Sketch_1.addLine(-9.826354679802961, 11.69211822660099, -9.826354679802961, 29.97660098522167)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+SketchLine_5 = Sketch_1.addLine(-30.22536945812809, 11.69211822660099, -9.826354679802961, 29.97660098522167)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_5.endPoint())
+SketchCircle_1 = Sketch_1.addCircle(9.328817733990148, 6.841133004926101, 8.342093824373531)
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_2 = Sketch_2.addCircle(-5.846059113300496, 9.453201970443347, 11.01344978196573)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "all-in-Sketch_1")], model.selection(), 10, 0)
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_2")], model.selection(), 11, 1)
+Group_1_objects = [model.selection("SOLID", "Extrusion_1_2_1"), model.selection("SOLID", "Extrusion_1_2_2"), model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "Extrusion_1_1")]
+Group_1 = model.addGroup(Part_1_doc, Group_1_objects)
+Group_2_objects = [model.selection("FACE", "Extrusion_1_2_1/To_Face"), model.selection("FACE", "Extrusion_1_2_2/To_Face"), model.selection("FACE", "Extrusion_2_1/To_Face"), model.selection("FACE", "Extrusion_1_1/To_Face")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Fuse_1_objects_1 = [model.selection("SOLID", "Extrusion_1_2_2"), model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "Extrusion_1_1")]
+Fuse_1 = model.addFuse(Part_1_doc, Fuse_1_objects_1)
+model.do()
+# move group
+Part_1_doc.moveFeature(Group_1.feature(), Fuse_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+model.end()
+
+# Check group 1: 3 solids
+aFactory = ModelAPI_Session.get().validators()
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 3)
+assert(aFactory.validate(Group_1.feature()))
+for i in range(3):
+ assert(Group_1.groupList().value(i).value().shapeType() == GeomAPI_Shape.SOLID)
+
+# Check group 2: 3 faces
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 3)
+assert(aFactory.validate(Group_2.feature()))
+for i in range(3):
+ assert(Group_2.groupList().value(i).value().shapeType() == GeomAPI_Shape.FACE)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test that the history of Smash operation works correctly after movement of groups after this Smash feature
+
+# -*- coding: utf-8 -*-
+
+from salome.shaper import model
+from ModelAPI import *
+from GeomAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(26.49384236453203, 25.42805779478775, -23.25985221674878, 25.42805779478775)
+SketchLine_2 = Sketch_1.addLine(-23.25985221674878, 25.42805779478775, -23.25985221674878, -22.79086009461325)
+SketchLine_3 = Sketch_1.addLine(-23.25985221674878, -22.79086009461325, 26.49384236453203, -22.79086009461325)
+SketchLine_4 = Sketch_1.addLine(26.49384236453203, -22.79086009461325, 26.49384236453203, 25.42805779478775)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+SketchLine_5 = Sketch_1.addLine(-23.25985221674878, -22.79086009461325, -4.602216748768477, 25.42805779478775)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_1.result())
+SketchLine_6 = Sketch_1.addLine(-4.602216748768477, 25.42805779478775, 8.458128078817737, -22.79086009461324)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.result())
+SketchLine_7 = Sketch_1.addLine(8.458128078817737, -22.79086009461324, 26.49384236453203, 25.42805779478775)
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_7.endPoint())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_8 = Sketch_2.addLine(38.18596059113301, 15.79679802955666, -30.91800131851275, 15.79679802955666)
+SketchLine_9 = Sketch_2.addLine(-30.91800131851275, 15.79679802955666, -30.91800131851275, -10.07512315270936)
+SketchLine_10 = Sketch_2.addLine(-30.91800131851275, -10.07512315270936, 38.18596059113301, -10.07512315270936)
+SketchLine_11 = Sketch_2.addLine(38.18596059113301, -10.07512315270936, 38.18596059113301, 15.79679802955666)
+SketchConstraintCoincidence_11 = Sketch_2.setCoincident(SketchLine_11.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_12 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_13 = Sketch_2.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintCoincidence_14 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchLine_11.startPoint())
+SketchConstraintHorizontal_3 = Sketch_2.setHorizontal(SketchLine_8.result())
+SketchConstraintVertical_3 = Sketch_2.setVertical(SketchLine_9.result())
+SketchConstraintHorizontal_4 = Sketch_2.setHorizontal(SketchLine_10.result())
+SketchConstraintVertical_4 = Sketch_2.setVertical(SketchLine_11.result())
+SketchLine_12 = Sketch_2.addLine(38.18596059113301, 15.79679802955666, -30.91800131851275, 1.368226600985215)
+SketchConstraintCoincidence_15 = Sketch_2.setCoincident(SketchLine_8.startPoint(), SketchLine_12.startPoint())
+SketchConstraintCoincidence_16 = Sketch_2.setCoincident(SketchLine_12.endPoint(), SketchLine_9.result())
+SketchLine_13 = Sketch_2.addLine(-30.91800131851275, 1.368226600985215, 38.18596059113301, -10.07512315270936)
+SketchConstraintCoincidence_17 = Sketch_2.setCoincident(SketchLine_12.endPoint(), SketchLine_13.startPoint())
+SketchConstraintCoincidence_18 = Sketch_2.setCoincident(SketchLine_10.endPoint(), SketchLine_13.endPoint())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "all-in-Sketch_1")], model.selection(), 10, 0)
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "all-in-Sketch_2")], model.selection(), 5, 5)
+Group_1_objects = [model.selection("SOLID", "Extrusion_1_1_1"), model.selection("SOLID", "Extrusion_1_1_4"), model.selection("SOLID", "Extrusion_1_1_2"), model.selection("SOLID", "Extrusion_1_1_3")]
+Group_1 = model.addGroup(Part_1_doc, Group_1_objects)
+Group_2_objects = [model.selection("SOLID", "Extrusion_2_1_2"), model.selection("SOLID", "Extrusion_2_1_3"), model.selection("SOLID", "Extrusion_2_1_1")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Group_3_objects = [model.selection("FACE", "Extrusion_1_1_4/From_Face"), model.selection("FACE", "Extrusion_1_1_2/From_Face"), model.selection("FACE", "Extrusion_1_1_4/Generated_Face&Sketch_1/SketchLine_3"), model.selection("FACE", "Extrusion_1_1_2/Generated_Face&Sketch_1/SketchLine_1"), model.selection("FACE", "Extrusion_1_1_4/To_Face"), model.selection("FACE", "Extrusion_1_1_2/To_Face")]
+Group_3 = model.addGroup(Part_1_doc, Group_3_objects)
+Group_4_objects = [model.selection("FACE", "Extrusion_2_1_2/To_Face"), model.selection("FACE", "Extrusion_2_1_3/To_Face"), model.selection("FACE", "Extrusion_2_1_1/To_Face")]
+Group_4 = model.addGroup(Part_1_doc, Group_4_objects)
+Smash_1_objects_1 = [model.selection("SOLID", "Extrusion_1_1_1"), model.selection("SOLID", "Extrusion_1_1_4"), model.selection("SOLID", "Extrusion_1_1_2")]
+Smash_1 = model.addSmash(Part_1_doc, Smash_1_objects_1, [model.selection("SOLID", "Extrusion_2_1_1"), model.selection("SOLID", "Extrusion_2_1_2")])
+model.do()
+# move groups after the Smash
+Part_1_doc.moveFeature(Group_1.feature(), Smash_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
+Part_1_doc.moveFeature(Group_4.feature(), Group_3.feature())
+model.end()
+
+# check groups are correct
+aFactory = ModelAPI_Session.get().validators()
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 4)
+assert(aFactory.validate(Group_1.feature()))
+for i in range(4):
+ assert(Group_1.groupList().value(i).value().shapeType() == GeomAPI_Shape.SOLID)
+
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 2)
+assert(aFactory.validate(Group_2.feature()))
+for i in range(2):
+ assert(Group_2.groupList().value(i).value().shapeType() == GeomAPI_Shape.SOLID)
+
+selectionList = Group_3.feature().selectionList("group_list")
+assert(selectionList.size() == 10)
+assert(aFactory.validate(Group_3.feature()))
+for i in range(10):
+ assert(Group_3.groupList().value(i).value().shapeType() == GeomAPI_Shape.FACE)
+
+selectionList = Group_4.feature().selectionList("group_list")
+assert(selectionList.size() == 10)
+assert(aFactory.validate(Group_4.feature()))
+for i in range(10):
+ assert(Group_4.groupList().value(i).value().shapeType() == GeomAPI_Shape.FACE)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test that the history of Fillet operation works correctly after movement of groups after this Fillet feature:
+# Faces are modified, edges that were used for fillet are removed
+
+# -*- coding: utf-8 -*-
+
+from salome.shaper import model
+from ModelAPI import *
+from GeomAPI import *
+from SketchAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(23.0955987576144, 26.85924638608351, -23.50862068965518, 26.85924638608351)
+SketchLine_2 = Sketch_1.addLine(-23.50862068965518, 26.85924638608351, -23.50862068965518, -11.11713209726581)
+SketchLine_3 = Sketch_1.addLine(-23.50862068965518, -11.11713209726581, 23.0955987576144, -11.11713209726581)
+SketchLine_4 = Sketch_1.addLine(23.0955987576144, -11.11713209726581, 23.0955987576144, 26.85924638608351)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_3.setName("SketchConstraintCoincidence_4")
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+SketchLine_5 = Sketch_1.addLine(2.024890803123894, -11.11713209726581, 23.0955987576144, 26.85924638608351)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_5.endPoint())
+SketchConstraintCoincidence_4.setName("SketchConstraintCoincidence_6")
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_5.startPoint(), SketchLine_3.result())
+SketchConstraintCoincidence_5.setName("SketchConstraintCoincidence_5")
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_6.setName("SketchConstraintCoincidence_7")
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_3f-SketchLine_4f-SketchLine_5r"), model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2f-SketchLine_3f-SketchLine_5f")], model.selection(), 10, 0)
+Group_1_objects = [model.selection("FACE", "Extrusion_1_1_2/Generated_Face&Sketch_1/SketchLine_2"), model.selection("FACE", "Extrusion_1_1_2/To_Face"), model.selection("FACE", "Extrusion_1_1_2/Generated_Face&Sketch_1/SketchLine_3")]
+Group_1 = model.addGroup(Part_1_doc, Group_1_objects)
+Group_2_objects = [model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchLine_2][Extrusion_1_1_2/Generated_Face&Sketch_1/SketchLine_3]"), model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchLine_2][Extrusion_1_1_2/To_Face]"), model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchLine_1][Extrusion_1_1_2/Generated_Face&Sketch_1/SketchLine_2]"), model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchLine_5][Extrusion_1_1_2/To_Face]")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Fillet_1_objects = [model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchLine_2][Extrusion_1_1_2/To_Face]"), model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchLine_1][Extrusion_1_1_2/Generated_Face&Sketch_1/SketchLine_2]"), model.selection("EDGE", "[Extrusion_1_1_2/Generated_Face&Sketch_1/SketchLine_2][Extrusion_1_1_2/From_Face]")]
+Fillet_1 = model.addFillet(Part_1_doc, Fillet_1_objects, 2)
+model.do()
+# move groups after the Fillet
+Part_1_doc.moveFeature(Group_1.feature(), Fillet_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+model.end()
+
+# check groups are correct
+aFactory = ModelAPI_Session.get().validators()
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 3)
+assert(aFactory.validate(Group_1.feature()))
+for i in range(3):
+ assert(Group_1.groupList().value(i).value().shapeType() == GeomAPI_Shape.FACE)
+
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 2)
+assert(aFactory.validate(Group_2.feature()))
+for i in range(2):
+ assert(Group_2.groupList().value(i).value().shapeType() == GeomAPI_Shape.EDGE)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test that partition of solid works correctly after movement of groups after this partition
+
+# -*- coding: utf-8 -*-
+
+from salome.shaper import model
+from ModelAPI import *
+from GeomAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(-16.04556650246306, 45.15147783251232, -31.59359605911331, 45.15147783251232)
+SketchLine_2 = Sketch_1.addLine(-31.59359605911331, 45.15147783251232, -31.59359605911331, 29.10591133004927)
+SketchLine_3 = Sketch_1.addLine(-31.59359605911331, 29.10591133004927, -16.04556650246306, 29.10591133004927)
+SketchLine_4 = Sketch_1.addLine(-16.04556650246306, 29.10591133004927, -16.04556650246306, 45.15147783251232)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+SketchLine_5 = Sketch_1.addLine(12.4384236453202, 13.06034482758621, -5.846059113300496, 13.06034482758621)
+SketchLine_6 = Sketch_1.addLine(-5.846059113300496, 13.06034482758621, -5.846059113300496, -6.965517241379309)
+SketchLine_7 = Sketch_1.addLine(-5.846059113300496, -6.965517241379309, 12.4384236453202, -6.965517241379309)
+SketchLine_8 = Sketch_1.addLine(12.4384236453202, -6.965517241379309, 12.4384236453202, 13.06034482758621)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_6.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_8.result())
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_2.addCircle(-10.81448298196523, 20.3003568426161, 15.58088381891068)
+SketchLine_9 = Sketch_2.addLine(-19.86849367207068, 32.98061042849822, 0.2083042015703297, 9.288449501673265)
+SketchConstraintCoincidence_9 = Sketch_2.setCoincident(SketchLine_9.startPoint(), SketchCircle_1.results()[1])
+SketchConstraintCoincidence_10 = Sketch_2.setCoincident(SketchLine_9.endPoint(), SketchCircle_1.results()[1])
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1"), model.selection("COMPOUND", "Sketch_2")], model.selection(), 10, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_1_3_2")])
+Group_2_objects = [model.selection("FACE", "Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_4"), model.selection("FACE", "Extrusion_1_3_2/Generated_Face&Sketch_2/SketchCircle_1_2"), model.selection("FACE", "Extrusion_1_3_1/Generated_Face&Sketch_2/SketchCircle_1_2&weak_name_1"), model.selection("FACE", "Extrusion_1_2/To_Face")]
+Group_2 = model.addGroup(Part_1_doc, Group_2_objects)
+Partition_1_objects = [model.selection("SOLID", "Extrusion_1_1"), model.selection("SOLID", "Extrusion_1_2"), model.selection("COMPSOLID", "Extrusion_1_3")]
+Partition_1 = model.addPartition(Part_1_doc, Partition_1_objects)
+model.do()
+# move groups after the partitiion
+Part_1_doc.moveFeature(Group_1.feature(), Partition_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+model.end()
+
+# check groups are correct
+aFactory = ModelAPI_Session.get().validators()
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 5)
+assert(aFactory.validate(Group_1.feature()))
+for i in range(5):
+ assert(Group_1.groupList().value(i).value().shapeType() == GeomAPI_Shape.SOLID)
+
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 10)
+assert(aFactory.validate(Group_2.feature()))
+for i in range(10):
+ assert(Group_2.groupList().value(i).value().shapeType() == GeomAPI_Shape.FACE)
+
+assert(model.checkPythonDump())
return false;
}
+
+bool GeomAPI_Shape::Comparator::operator()(const std::shared_ptr<GeomAPI_Shape>& theShape1,
+ const std::shared_ptr<GeomAPI_Shape>& theShape2) const
+{
+ return theShape1->impl<TopoDS_Shape>().TShape() < theShape2->impl<TopoDS_Shape>().TShape();
+}
/// 8 - V/V, V/E, E/E, V/F, E/F, F/F, V/S, E/S and F/S;<br>
/// 9 - V/V, V/E, E/E, V/F, E/F, F/F, V/S, E/S, F/S and S/S - all interferences (Default value)
GEOMAPI_EXPORT bool isSelfIntersected(const int theLevelOfCheck = 9) const;
+
+public:
+ class Comparator
+ {
+ public:
+ /// Return \c true if the address of the first shape is less than the address of the second
+ GEOMAPI_EXPORT
+ bool operator ()(const std::shared_ptr<GeomAPI_Shape>& theShape1,
+ const std::shared_ptr<GeomAPI_Shape>& theShape2) const;
+ };
};
//! Pointer on list of shapes
%shared_ptr(GeomAlgoAPI_Revolution)
%shared_ptr(GeomAlgoAPI_Rotation)
%shared_ptr(GeomAlgoAPI_Sewing)
+%shared_ptr(GeomAlgoAPI_SketchBuilder)
%shared_ptr(GeomAlgoAPI_ShapeBuilder)
%shared_ptr(GeomAlgoAPI_Translation)
%shared_ptr(GeomAlgoAPI_Transform)
#include <BOPAlgo_BOP.hxx>
#include <TopTools_ListOfShape.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopExp_Explorer.hxx>
//=================================================================================================
GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const GeomShapePtr theObject,
this->setShape(aShape);
this->setDone(true);
}
+
+static bool isHistoryType(TopAbs_ShapeEnum theType) {
+ return theType == TopAbs_VERTEX || theType == TopAbs_EDGE ||
+ theType == TopAbs_FACE || theType == TopAbs_SOLID;
+}
+
+/// searches the corresponding result for theOld
+static void searchResult(const TopoDS_Shape& theOld, const TopoDS_Shape& theResult,
+ BOPAlgo_BOP* theBuilder, TopTools_MapOfShape& theNews)
+{
+ if (theResult.ShapeType() == theOld.ShapeType()) { // check some sub-shape produces a sub-result
+ if (theOld.IsSame(theResult)) {
+ theNews.Add(theResult);
+ return;
+ }
+ // searching for new result by sub-shapes of aSubType type
+ TopAbs_ShapeEnum aSubType = TopAbs_ShapeEnum(int(theOld.ShapeType()) + 1);
+ while(aSubType < TopAbs_VERTEX && !isHistoryType(aSubType))
+ aSubType = TopAbs_ShapeEnum(int(aSubType) + 1);
+ if (aSubType == TopAbs_SHAPE)
+ return;
+ TopTools_MapOfShape aResSubs;
+ for(TopExp_Explorer aResExp(theResult, aSubType); aResExp.More(); aResExp.Next())
+ aResSubs.Add(aResExp.Current());
+ for(TopExp_Explorer anExp(theOld, aSubType); anExp.More(); anExp.Next()) {
+ const TopTools_ListOfShape& aNewSubs = theBuilder->Modified(anExp.Current());
+ // searching for this new sub in theResult
+ for(TopTools_ListIteratorOfListOfShape aNewSub(aNewSubs); aNewSub.More(); aNewSub.Next()) {
+ if (aResSubs.Contains(aNewSub.Value())) {
+ theNews.Add(theResult);
+ return;
+ }
+ }
+ }
+ } else if (theResult.ShapeType() < theOld.ShapeType()) { // recursive search among sub-shapes
+ for(TopoDS_Iterator aSubResults(theResult); aSubResults.More(); aSubResults.Next()) {
+ searchResult(theOld, aSubResults.Value(), theBuilder, theNews);
+ }
+ }
+}
+
+// check the shape is on the higher level of compound or compsolid
+bool isInComp(const TopoDS_Shape& theComp, const TopoDS_Shape& theShape) {
+ if (theComp.ShapeType() == TopAbs_COMPOUND || theComp.ShapeType() == TopAbs_COMPSOLID) {
+ for(TopoDS_Iterator anIter(theComp); anIter.More(); anIter.Next()) {
+ if (isInComp(anIter.Value(), theShape))
+ return true;
+ }
+ } else return theShape.IsSame(theComp);
+ return false;
+}
+
+//=================================================================================================
+/// make arguments of Fuse produce result shapes with "modified" evolution
+void GeomAlgoAPI_Boolean::modified(const GeomShapePtr theOldShape, ListOfShape& theNewShapes)
+{
+ BOPAlgo_BOP* aBuilder = this->implPtr<BOPAlgo_BOP>();
+ if (aBuilder->Operation() == BOPAlgo_FUSE) { // only for fuse and when old is and argument
+ TopoDS_Shape anOld = theOldShape->impl<TopoDS_Shape>();
+ bool isOldComp = anOld.ShapeType() == TopAbs_COMPOUND || anOld.ShapeType() == TopAbs_COMPSOLID;
+ bool aFound = false;
+ TopTools_ListIteratorOfListOfShape anIter(aBuilder->Arguments());
+ for(; !aFound && anIter.More(); anIter.Next())
+ aFound = anOld.IsSame(anIter.Value()) || (!isOldComp && isInComp(anIter.Value(), anOld));
+ for(anIter.Initialize(aBuilder->Tools()); !aFound && anIter.More(); anIter.Next())
+ aFound = anOld.IsSame(anIter.Value()) || (!isOldComp && isInComp(anIter.Value(), anOld));
+ if (aFound) {
+ TopoDS_Shape aResult = aBuilder->Shape();
+ TopTools_MapOfShape aNewsMap;
+ searchResult(anOld, aResult, aBuilder, aNewsMap);
+ if (!aNewsMap.IsEmpty()) {
+ for(TopTools_MapIteratorOfMapOfShape aNewsIter(aNewsMap); aNewsIter.More(); aNewsIter.Next())
+ {
+ GeomShapePtr aShape(new GeomAPI_Shape);
+ aShape->setImpl<TopoDS_Shape>(new TopoDS_Shape(aNewsIter.Value()));
+ theNewShapes.push_back(aShape);
+ }
+ return;
+ }
+ }
+ }
+ GeomAlgoAPI_MakeShape::modified(theOldShape, theNewShapes); // default behavior
+}
const ListOfShape& theTools,
const OperationType theOperationType);
+ /// Redefinition of the generic method for the Fuse problem: OCCT 30481
+ GEOMALGOAPI_EXPORT virtual void modified(const GeomShapePtr theOldShape,
+ ListOfShape& theNewShapes);
+
private:
/// Builds resulting shape.
void build(const ListOfShape& theObjects,
#include "GeomAlgoAPI_MakeVolume.h"
+#include <GeomAPI_ShapeExplorer.h>
+
#include <GeomAlgoAPI_ShapeTools.h>
#include <BOPAlgo_MakerVolume.hxx>
this->setShape(aShape);
this->setDone(true);
}
+
+//=================================================================================================
+void GeomAlgoAPI_MakeVolume::modified(const GeomShapePtr theOldShape,
+ ListOfShape& theNewShapes)
+{
+ if (theOldShape->shapeType() == GeomAPI_Shape::SOLID) {
+ ListOfShape aNewShapes;
+ // collect faces and parent shapes, if it is not done yet
+ if (!isNewShapesCollected(theOldShape, GeomAPI_Shape::FACE))
+ collectNewShapes(theOldShape, GeomAPI_Shape::FACE);
+
+ for (GeomAPI_ShapeExplorer anIt(shape(), GeomAPI_Shape::SOLID); anIt.more(); anIt.next()) {
+ for (GeomAPI_ShapeExplorer anExp(anIt.current(), GeomAPI_Shape::FACE);
+ anExp.more(); anExp.next()) {
+ GeomShapePtr anOldShapesCompound =
+ oldShapesForNew(theOldShape, anExp.current(), GeomAPI_Shape::FACE);
+ if (!anOldShapesCompound->isNull()) {
+ aNewShapes.push_back(anIt.current());
+ break;
+ }
+ }
+ }
+
+ if (!aNewShapes.empty())
+ theNewShapes = aNewShapes;
+ }
+ else
+ GeomAlgoAPI_MakeShape::modified(theOldShape, theNewShapes);
+}
GEOMALGOAPI_EXPORT GeomAlgoAPI_MakeVolume(const ListOfShape& theFaces,
const bool theAvoidInternal);
+ /// \return the list of shapes modified from the shape \a theShape.
+ /// \param[in] theOldShape base shape.
+ /// \param[out] theNewShapes shapes modified from \a theShape. Does not cleared!
+ GEOMALGOAPI_EXPORT virtual void modified(const GeomShapePtr theOldShape,
+ ListOfShape& theNewShapes);
+
private:
/// Builds resulting shape.
void build(const ListOfShape& theFaces);
}
//==================================================================================================
+#include <GeomAPI_ShapeExplorer.h>
+#include <GeomAPI_ShapeIterator.h>
+
+typedef std::map<GeomShapePtr, ListOfShape, GeomAPI_Shape::Comparator> MapFaceSolid;
+static void facesBelongingToSolids(const GeomShapePtr& theShape,
+ MapFaceSolid& theShapeRelations)
+{
+ for (GeomAPI_ShapeExplorer aSolidExp(theShape, GeomAPI_Shape::SHELL);
+ aSolidExp.more(); aSolidExp.next()) {
+ GeomShapePtr aSolid = aSolidExp.current();
+ for (GeomAPI_ShapeExplorer aFaceExp(aSolid, GeomAPI_Shape::FACE);
+ aFaceExp.more(); aFaceExp.next())
+ theShapeRelations[aFaceExp.current()].push_back(aSolid);
+ }
+}
+
+static bool isShapeInList(const GeomShapePtr& theShape, const ListOfShape& theList)
+{
+ for (ListOfShape::const_iterator anIt = theList.begin(); anIt != theList.end(); ++anIt)
+ if (theShape->isEqual(*anIt))
+ return true;
+ return false;
+}
+
void GeomAlgoAPI_Sewing::modified(const std::shared_ptr<GeomAPI_Shape> theShape,
ListOfShape& theHistory)
{
aGeomShape->setImpl(new TopoDS_Shape(anExp.Current()));
theHistory.push_back(aGeomShape);
}
+
+ if (theShape->shapeType() < GeomAPI_Shape::FACE) {
+ ListOfShape aNewShapes;
+ // collect faces and parent shapes, if it is not done yet
+ if (!isNewShapesCollected(theShape, GeomAPI_Shape::FACE))
+ collectNewShapes(theShape, GeomAPI_Shape::FACE);
+
+ for (GeomAPI_ShapeIterator anIt(shape()); anIt.more(); anIt.next()) {
+ GeomShapePtr anOldShapesCompound =
+ oldShapesForNew(theShape, anIt.current(), GeomAPI_Shape::FACE);
+ if (!anOldShapesCompound->isNull())
+ aNewShapes.push_back(anIt.current());
+ }
+
+ if (!aNewShapes.empty())
+ theHistory = aNewShapes;
+ }
}
/// \return the total area of the faces of the current shape or 0.0 if it can be computed.
GEOMALGOAPI_EXPORT static double area(const std::shared_ptr<GeomAPI_Shape> theShape);
- /// \return the centre of mass of the current face.
+ /// \return the center of mass of the current face.
/// The coordinates returned for the center of mass
/// are expressed in the absolute Cartesian coordinate system.
/// (This function works only for surfaces).
/// \brief Enlarges or reduces plane to fit bounding box.
/// \return plane that fits to bounding box.
/// \param[in] thePlane base plane.
- /// \param[in] thePoints bounding box points (shoud be eight).
+ /// \param[in] thePoints bounding box points (should be eight).
GEOMALGOAPI_EXPORT static std::shared_ptr<GeomAPI_Face> fitPlaneToBox(
const std::shared_ptr<GeomAPI_Shape> thePlane,
const std::list<std::shared_ptr<GeomAPI_Pnt> >& thePoints);
/// \brief Return a plane for list of shapes if they are all planar.
/// \param[in] theShapes shapes to find plane.
- /// \return plane where all shapes lie or empty ptr if they not planar.
+ /// \return plane where all shapes lie or empty pointer if they not planar.
GEOMALGOAPI_EXPORT static std::shared_ptr<GeomAPI_Pln> findPlane(const ListOfShape& theShapes);
- /// \brief Checks that vertex/edge is inside face or vertext inside wire.
+ /// \brief Checks that vertex/edge is inside face or vertex inside wire.
/// \param[in] theSubShape shape that should be inside.
/// \param[in] theBaseShape base shape.
/// \return true if edge inside the face.
std::pair<std::list<std::shared_ptr<GeomDataAPI_Point2D> >,
std::list<std::shared_ptr<ModelAPI_Object> > > > PointToRefsMap;
/// \brief Performs the split of the shape by points.
- /// \param[in] theBaseShape shape that should be splitted.
+ /// \param[in] theBaseShape shape that should be divided.
/// \param[in] thePoints container of points to split
/// \param[out] theShapes container of shapes after split
GEOMALGOAPI_EXPORT static void splitShape(const std::shared_ptr<GeomAPI_Shape>& theBaseShape,
std::set<std::shared_ptr<GeomAPI_Shape> >& theShapes);
/// \brief Performs the split of the shape by points.
- /// \param[in] theBaseShape shape that should be splitted.
+ /// \param[in] theBaseShape shape that should be divided.
/// \param[in] thePoints container of points to split
/// \param[out] theShapes container of shapes after split
GEOMALGOAPI_EXPORT static void splitShape_p(const std::shared_ptr<GeomAPI_Shape>& theBaseShape,
const std::set<std::shared_ptr<GeomAPI_Shape> >& theShapes);
#ifdef FEATURE_MULTIROTATION_TWO_DIRECTIONS
- /// \brief Returns a dir from a shape and an axis.
+ /// \brief Returns a direction from a shape and an axis.
/// \param[in] theBaseShape shape whose center of mass serves as the starting point of the dir.
/// \param[in] theAxis axis that serves as a direction for the dir
/// \return dir that builds from center of mass of the base shape and the axis
const std::shared_ptr<GeomAPI_Ax1> theAxis);
#endif
- /// \brief Reapproximate a wire to build a single edge
+ /// \brief Re-approximate a wire to build a single edge
GEOMALGOAPI_EXPORT static std::shared_ptr<GeomAPI_Edge> wireToEdge(
const std::shared_ptr<GeomAPI_Wire>& theWire);
#include <GeomAlgoAPI_SketchBuilder.h>
#include <GeomAPI_PlanarEdges.h>
+#include <GeomAPI_Pln.h>
+
#include <BOPAlgo_Builder.hxx>
#include <BRep_Builder.hxx>
#include <BRepTools_WireExplorer.hxx>
}
}
-void GeomAlgoAPI_SketchBuilder::createFaces(
+void GeomAlgoAPI_SketchBuilder::build(
const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
const std::shared_ptr<GeomAPI_Dir>& theDirX,
const std::shared_ptr<GeomAPI_Dir>& theNorm,
- const std::list<std::shared_ptr<GeomAPI_Shape> >& theFeatures,
- std::list<std::shared_ptr<GeomAPI_Shape> >& theResultFaces)
+ const std::list<std::shared_ptr<GeomAPI_Shape> >& theEdges)
{
- if (theFeatures.empty())
+ myResultFaces.clear();
+ setDone(false);
+ if (theEdges.empty())
return;
BRep_Builder aBuilder;
aBuilder.MakeFace(aPlnFace, aPlane, Precision::Confusion());
// Use General Fuse algorithm to prepare all subfaces, bounded by given list of edges
- BOPAlgo_Builder aBB;
- aBB.AddArgument(aPlnFace);
+ BOPAlgo_Builder* aBB = new BOPAlgo_Builder;
+ aBB->AddArgument(aPlnFace);
+
+ setImpl(aBB);
+ setBuilderType(OCCT_BOPAlgo_Builder);
NCollection_List<TopoDS_Shape> anEdges;
NCollection_List<TopoDS_Shape>::Iterator aShapeIt;
- std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator aFeatIt = theFeatures.begin();
- for (; aFeatIt != theFeatures.end(); aFeatIt++) {
+ std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator aFeatIt = theEdges.begin();
+ for (; aFeatIt != theEdges.end(); aFeatIt++) {
std::shared_ptr<GeomAPI_Shape> aShape(*aFeatIt);
const TopoDS_Edge& anEdge = aShape->impl<TopoDS_Edge>();
if (anEdge.ShapeType() == TopAbs_EDGE)
- aBB.AddArgument(anEdge);
+ aBB->AddArgument(anEdge);
}
- aBB.Perform();
- if (aBB.HasErrors())
+ aBB->Perform();
+ if (aBB->HasErrors())
return;
+
+ TopoDS_Compound aResult;
+ aBuilder.MakeCompound(aResult);
+
// Collect faces
- TopTools_ListOfShape anAreas = aBB.Modified(aPlnFace);
- sortFaces(anAreas, theFeatures); // sort faces by the edges in them
+ TopTools_ListOfShape anAreas = aBB->Modified(aPlnFace);
+ sortFaces(anAreas, theEdges); // sort faces by the edges in them
TopTools_ListIteratorOfListOfShape anIt(anAreas);
for (; anIt.More(); anIt.Next()) {
TopoDS_Face aFace = TopoDS::Face(anIt.Value());
// to make faces equal on different platforms, we will find
// a vertex lying on an edge with the lowest index in the list of initial edges
- TopoDS_Vertex aStartVertex = findStartVertex(aWire, aFace, theFeatures);
+ TopoDS_Vertex aStartVertex = findStartVertex(aWire, aFace, theEdges);
TopoDS_Wire aNewWire;
aBuilder.MakeWire(aNewWire);
}
// store face
- aFace = aNewFace;
+ aBuilder.Add(aResult, aNewFace);
std::shared_ptr<GeomAPI_Shape> aResFace(new GeomAPI_Shape);
aResFace->setImpl(new TopoDS_Face(aFace));
- theResultFaces.push_back(aResFace);
+ myResultFaces.push_back(aResFace);
}
+
+ // update results
+ GeomShapePtr aResShape(new GeomAPI_Shape);
+ aResShape->setImpl(new TopoDS_Shape(aResult));
+ setShape(aResShape);
+ setDone(true);
}
-void GeomAlgoAPI_SketchBuilder::createFaces(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
- const std::shared_ptr<GeomAPI_Dir>& theDirX,
- const std::shared_ptr<GeomAPI_Dir>& theNorm,
- const std::shared_ptr<GeomAPI_Shape>& theWire,
- std::list<std::shared_ptr<GeomAPI_Shape> >& theResultFaces)
+GeomAlgoAPI_SketchBuilder::GeomAlgoAPI_SketchBuilder(
+ const std::shared_ptr<GeomAPI_Pln>& thePlane,
+ const std::list<std::shared_ptr<GeomAPI_Shape> >& theEdges)
+{
+ build(thePlane->location(), thePlane->xDirection(), thePlane->direction(), theEdges);
+}
+
+GeomAlgoAPI_SketchBuilder::GeomAlgoAPI_SketchBuilder(
+ const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+ const std::shared_ptr<GeomAPI_Dir>& theDirX,
+ const std::shared_ptr<GeomAPI_Dir>& theNorm,
+ const std::shared_ptr<GeomAPI_Shape>& theWire)
{
std::shared_ptr<GeomAPI_PlanarEdges> aWire =
std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(theWire);
if(aWire) {
// Filter wires, return only faces.
- createFaces(theOrigin, theDirX, theNorm, aWire->getEdges(), theResultFaces);
+ build(theOrigin, theDirX, theNorm, aWire->getEdges());
} else { // it may be only one circle
std::shared_ptr<GeomAPI_Edge> anEdge = std::dynamic_pointer_cast<GeomAPI_Edge>(theWire);
if (anEdge) {
std::list<std::shared_ptr<GeomAPI_Shape> > aList;
aList.push_back(anEdge);
- createFaces(theOrigin, theDirX, theNorm, aList, theResultFaces);
+ build(theOrigin, theDirX, theNorm, aList);
}
}
}
#define GeomAlgoAPI_SketchBuilder_H_
#include <GeomAlgoAPI.h>
+#include <GeomAlgoAPI_MakeShape.h>
#include <memory>
#include <list>
-#include <GeomAPI_Dir.h>
-#include <GeomAPI_Pnt.h>
-#include <GeomAPI_Shape.h>
+class GeomAPI_Dir;
+class GeomAPI_Pln;
+class GeomAPI_Pnt;
+class GeomAPI_Shape;
/** \class GeomAlgoAPI_SketchBuilder
* \ingroup DataAlgo
* \brief Creates planar faces based on the list of Sketch features
*/
-class GEOMALGOAPI_EXPORT GeomAlgoAPI_SketchBuilder
+class GeomAlgoAPI_SketchBuilder : public GeomAlgoAPI_MakeShape
{
- public:
- /** \brief Creates list of faces based on the features of the sketch
- * \param[in] theOrigin origin point of the sketch
- * \param[in] theDirX x-direction of the sketch
- * \param[in] theNorm normal of the sketch
- * \param[in] theFeatures initial features of the sketch
- * \param[out] theResultFaces faces based on closed wires
+public:
+ /** \brief Creates list of faces based on the edges of the sketch
+ * \param[in] thePlane plane of the sketch
+ * \param[in] theEdges initial edges of the sketch
*
* The algorithm searches all loops of edges surrounding lesser areas.
*/
- static void createFaces(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
- const std::shared_ptr<GeomAPI_Dir>& theDirX,
- const std::shared_ptr<GeomAPI_Dir>& theNorm,
- const std::list<std::shared_ptr<GeomAPI_Shape> >& theFeatures,
- std::list<std::shared_ptr<GeomAPI_Shape> >& theResultFaces);
+ GEOMALGOAPI_EXPORT
+ GeomAlgoAPI_SketchBuilder(const std::shared_ptr<GeomAPI_Pln>& thePlane,
+ const std::list<std::shared_ptr<GeomAPI_Shape> >& theEdges);
/** \brief Creates list of faces and unclosed wires on basis of the features of the sketch
* \param[in] theOrigin origin point of the sketch
* \param[in] theDirX x-direction of the sketch
* \param[in] theNorm normal of the sketch
* \param[in] theWire a wire which contains all edges
- * \param[out] theResultFaces faces based on closed wires
*
* The algorithm searches all loops of edges surrounding lesser areas.
*/
- static void createFaces(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
- const std::shared_ptr<GeomAPI_Dir>& theDirX,
- const std::shared_ptr<GeomAPI_Dir>& theNorm,
- const std::shared_ptr<GeomAPI_Shape>& theWire,
- std::list<std::shared_ptr<GeomAPI_Shape> >& theResultFaces);
+ GEOMALGOAPI_EXPORT
+ GeomAlgoAPI_SketchBuilder(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+ const std::shared_ptr<GeomAPI_Dir>& theDirX,
+ const std::shared_ptr<GeomAPI_Dir>& theNorm,
+ const std::shared_ptr<GeomAPI_Shape>& theWire);
+
+ /// Return list of created faces
+ GEOMALGOAPI_EXPORT const std::list<std::shared_ptr<GeomAPI_Shape> >& faces() const
+ { return myResultFaces; }
+
+private:
+ void build(const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
+ const std::shared_ptr<GeomAPI_Dir>& theDirX,
+ const std::shared_ptr<GeomAPI_Dir>& theNorm,
+ const std::list<std::shared_ptr<GeomAPI_Shape> >& theEdges);
+
+private:
+ std::list<std::shared_ptr<GeomAPI_Shape> > myResultFaces;
};
#endif
const ShapeUpgrade_UnifySameDomain& aUnifyAlgo = this->impl<ShapeUpgrade_UnifySameDomain>();
for (int aIsModified = 0; aIsModified <= 1; aIsModified++) {
+ if (!aUnifyAlgo.History()->IsSupportedType(aShape)) // to avoid crash in BRepTools_History
+ continue;
const TopTools_ListOfShape& aMList = aIsModified ?
aUnifyAlgo.History()->Modified(aShape) : aUnifyAlgo.History()->Generated(aShape);
for (TopTools_ListIteratorOfListOfShape aModified(aMList); aModified.More(); aModified.Next()) {
if (aWasWholeContext) {
theValShape = theOldContext->shape()->impl<TopoDS_Shape>();
}
+ TopAbs_ShapeEnum aValType = theValShape.ShapeType();
TopoDS_Shape aNewContShape = theNewContext->shape()->impl<TopoDS_Shape>();
// if a new value is unchanged in the new context, do nothing: value is correct
- TopExp_Explorer aSubExp(aNewContShape, theValShape.ShapeType());
+ TopExp_Explorer aSubExp(aNewContShape, aValType);
for(; aSubExp.More(); aSubExp.Next()) {
if (aSubExp.Current().IsSame(theValShape)) {
theShapes.Append(theValShape);
return;
}
// don't add edges generated from faces
- if (aPairIter.NewShape().ShapeType() <= theValShape.ShapeType())
+ if (aPairIter.NewShape().ShapeType() <= aValType)
theShapes.Append(aPairIter.NewShape());
}
} else if (!aPairIter.OldShape().IsNull()) { // search shape that contains this sub
- TopExp_Explorer anExp(aPairIter.OldShape(), theValShape.ShapeType());
+ TopExp_Explorer anExp(aPairIter.OldShape(), aValType);
for(; anExp.More(); anExp.Next()) {
if (anExp.Current().IsSame(theValShape)) { // found a new container
- if (aPairIter.NewShape().IsNull()) {// value was removed
- theShapes.Clear();
- return;
- }
+ if (aPairIter.NewShape().IsNull()) // skip removed high-level shape
+ continue;
aNewToOld.Bind(aPairIter.NewShape(), aPairIter.OldShape());
anOlds.Add(aPairIter.OldShape());
break;
}
}
if (aToFindPart == 2 && !aNewToOld.IsEmpty()) {
+ // also iterate the whole old shape to find not-modified shapes that contain this old
+ TopoDS_Shape anOldContShape = theOldContext->shape()->impl<TopoDS_Shape>();
+ NCollection_Map<TopAbs_ShapeEnum> aNewTypes; // types of shapes to iterate
+ TopTools_DataMapOfShapeShape::Iterator aNewTypeIter(aNewToOld);
+ for(; aNewTypeIter.More(); aNewTypeIter.Next()) {
+ if (aNewTypeIter.Key().ShapeType() != aValType)
+ aNewTypes.Add(aNewTypeIter.Key().ShapeType());
+ }
+ NCollection_Map<TopAbs_ShapeEnum>::Iterator aTypeIter(aNewTypes);
+ for(; aTypeIter.More(); aTypeIter.Next()) {
+ for(TopExp_Explorer anExp(anOldContShape, aTypeIter.Value()); anExp.More(); anExp.Next()) {
+ TopoDS_Shape anOld = anExp.Current();
+ if (aNewToOld.IsBound(anOld) || anOlds.Contains(anOld)) // this was modified
+ continue;
+ TopExp_Explorer aValExp(anOld, aValType);
+ for(; aValExp.More(); aValExp.Next()) {
+ const TopoDS_Shape& anUnchanged = aValExp.Current();
+ if (anUnchanged.IsSame(theValShape)) {
+ aNewToOld.Bind(anOld, anOld);
+ anOlds.Add(anOld);
+ break;
+ }
+ }
+ }
+ }
+
// map of sub-shapes -> number of occurrences of these shapes in containers
NCollection_DataMap<TopoDS_Shape, TopTools_MapOfShape, TopTools_ShapeMapHasher> aSubs;
TopTools_DataMapOfShapeShape::Iterator aContIter(aNewToOld);
for(; aContIter.More(); aContIter.Next()) {
- TopExp_Explorer aSubExp(aContIter.Key(), theValShape.ShapeType());
+ TopExp_Explorer aSubExp(aContIter.Key(), aValType);
for(; aSubExp.More(); aSubExp.Next()) {
if (!aSubs.IsBound(aSubExp.Current())) {
aSubs.Bind(aSubExp.Current(), TopTools_MapOfShape());
aSubsIter(aSubs);
for(; aSubsIter.More(); aSubsIter.Next()) {
if (aSubsIter.Value().Size() == aCountInOld) {
- theShapes.Append(aSubsIter.Key());
+ TopoDS_Shape anOld = aSubsIter.Key();
+ // check this exists in the new shape
+ TopExp_Explorer aNew(aNewContShape, anOld.ShapeType());
+ for (; aNew.More(); aNew.Next()) {
+ if (aNew.Current().IsSame(anOld))
+ break;
+ }
+ if (aNew.More())
+ theShapes.Append(anOld);
}
}
}
if (theShapes.IsEmpty()) { // nothing was changed
- theShapes.Append(aWasWholeContext ? TopoDS_Shape() : theValShape);
+ if (aWasWholeContext)
+ theShapes.Append(TopoDS_Shape());
+ else { // if theValShape exists in new context, add it without changes, otherwise - nothing
+ for (TopExp_Explorer aNew(aNewContShape, aValType); aNew.More(); aNew.Next()){
+ if (aNew.Current().IsSame(theValShape)) {
+ theShapes.Append(theValShape);
+ break;
+ }
+ }
+ }
+ } else if (theShapes.Size() > 1) {
+ // check it is possible to remove extra sub-shapes:
+ // keep only shapes with the same number of containers if possible
+ TopAbs_ShapeEnum anAncType = TopAbs_FACE;
+ if (aValType == TopAbs_VERTEX)
+ anAncType = TopAbs_EDGE;
+ TopoDS_Shape anOldContext = theOldContext->shape()->impl<TopoDS_Shape>();
+ TopTools_IndexedDataMapOfShapeListOfShape anOldMap;
+ TopExp::MapShapesAndUniqueAncestors(anOldContext, aValType, anAncType, anOldMap);
+ if (anOldMap.Contains(theValShape)) {
+ int aNumInOld = anOldMap.FindFromKey(theValShape).Extent();
+ TopTools_IndexedDataMapOfShapeListOfShape aNewMap;
+ TopExp::MapShapesAndUniqueAncestors(aNewContShape, aValType, anAncType, aNewMap);
+ TopTools_ListOfShape aNewResults;
+ for(TopTools_ListOfShape::Iterator aNewSubs(theShapes); aNewSubs.More(); aNewSubs.Next()) {
+ TopoDS_Shape aCand = aNewSubs.Value();
+ if (aNewMap.Contains(aCand) && aNewMap.FindFromKey(aCand).Extent() == aNumInOld)
+ aNewResults.Append(aCand);
+ }
+ if (!aNewResults.IsEmpty() && aNewResults.Size() < theShapes.Size())
+ theShapes = aNewResults;
+ }
}
}
std::list<ResultPtr>& theResults, TopTools_ListOfShape& theValShapes)
{
std::set<ResultPtr> aResults; // to avoid duplicates, new context, null if deleted
- TopTools_ListOfShape aResContShapes;
// iterate context and shape, but also if it is sub-shape of main shape, check also it
TopTools_ListOfShape aContextList;
aContextList.Append(theContShape);
aModifIter.Label().FindAttribute(TNaming_NamedShape::GetID(), aNewNS);
if (aNewNS->Evolution() == TNaming_MODIFY || aNewNS->Evolution() == TNaming_GENERATED) {
aResults.insert(aModifierObj);
- aResContShapes.Append(aModifierObj->shape()->impl<TopoDS_Shape>());
} else if (aNewNS->Evolution() == TNaming_DELETE) { // a shape was deleted => result is empty
aResults.insert(ResultPtr());
} else { // not-processed modification => don't support it
}
}
}
- if (aResults.empty())
+ // if there exist context composite and sub-result(s), leave only sub(s)
+ for(std::set<ResultPtr>::iterator aResIter = aResults.begin(); aResIter != aResults.end();) {
+ ResultPtr aParent = ModelAPI_Tools::bodyOwner(*aResIter);
+ for(; aParent.get(); aParent = ModelAPI_Tools::bodyOwner(aParent))
+ if (aResults.count(aParent))
+ break;
+ if (aParent.get()) { // erase from set, so, restart iteration
+ aResults.erase(aParent);
+ aResIter = aResults.begin();
+ } else aResIter++;
+ }
+
+ if (aResults.empty()) {
+ // check the context become concealed by operation which is earlier than this selection
+ std::list<ResultPtr> allRes;
+ ResultPtr aRoot = ModelAPI_Tools::bodyOwner(theContext, true);
+ if (!aRoot.get())
+ aRoot = theContext;
+ ResultBodyPtr aRootBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aRoot);
+ if (aRootBody.get()) {
+ ModelAPI_Tools::allSubs(aRootBody, allRes);
+ allRes.push_back(aRootBody);
+ } else
+ allRes.push_back(aRoot);
+
+ FeaturePtr aThisFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
+ for (std::list<ResultPtr>::iterator aSub = allRes.begin(); aSub != allRes.end(); aSub++) {
+ ResultPtr aResCont = *aSub;
+ const std::set<AttributePtr>& aRefs = aResCont->data()->refsToMe();
+ std::set<AttributePtr>::const_iterator aRef = aRefs.begin();
+ for (; aRef != aRefs.end(); aRef++) {
+ if (!aRef->get() || !(*aRef)->owner().get())
+ continue;
+ // concealed attribute only
+ FeaturePtr aRefFeat = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRef)->owner());
+ if (aRefFeat == aThisFeature)
+ continue;
+ if (!ModelAPI_Session::get()->validators()->isConcealed(
+ aRefFeat->getKind(), (*aRef)->id()))
+ continue;
+ if (theDoc->isLaterByDep(aThisFeature, aRefFeat)) {
+ // for extrusion cut in python script the nested sketch reference may be concealed before
+ // it is nested, so, check this composite feature is valid
+ static ModelAPI_ValidatorsFactory* aFactory = ModelAPI_Session::get()->validators();
+ // need to be validated to update the "Apply" state if not previewed
+ if (aFactory->validate(aRefFeat))
+ return true; // feature conceals result, return true, so the context will be removed
+ }
+ }
+ }
return false; // no modifications found, must stay the same
+ }
// iterate all results to find further modifications
std::set<ResultPtr>::iterator aResIter = aResults.begin();
for(; aResIter != aResults.end(); aResIter++) {
return true; // theResults must be empty: everything is deleted
}
-void Model_AttributeSelection::updateInHistory()
+void Model_AttributeSelection::updateInHistory(bool& theRemove)
{
ResultPtr aContext = std::dynamic_pointer_cast<ModelAPI_Result>(myRef.value());
// only bodies and parts may be modified later in the history, don't do anything otherwise
TopTools_ListOfShape aValShapes;
if (searchNewContext(aDoc, aNewCShape, aContext, aValShape, aContLab, aNewContexts, aValShapes))
{
+ std::set<ResultPtr> allContexts, aSkippedContext;
+ std::list<ResultPtr>::iterator aNewContext = aNewContexts.begin();
+ for(; aNewContext != aNewContexts.end(); aNewContext++)
+ allContexts.insert(*aNewContext);
+
+ // if there exist context composite and sub-result(s), leave only sub(s)
+ std::set<ResultPtr>::iterator aResIter = allContexts.begin();
+ for(; aResIter != allContexts.end(); aResIter++) {
+ ResultPtr aParent = ModelAPI_Tools::bodyOwner(*aResIter);
+ for(; aParent.get(); aParent = ModelAPI_Tools::bodyOwner(aParent))
+ if (allContexts.count(aParent))
+ aSkippedContext.insert(aParent);
+ }
+
GeomAPI_Shape::ShapeType aListShapeType = GeomAPI_Shape::SHAPE;
if (myParent) {
- if (myParent->selectionType() == "VERTEX") aListShapeType = GeomAPI_Shape::VERTEX;
- else if (myParent->selectionType() == "EDGE") aListShapeType = GeomAPI_Shape::EDGE;
- else if (myParent->selectionType() == "FACE") aListShapeType = GeomAPI_Shape::FACE;
+ if (myParent->selectionType() == "VERTEX" || myParent->selectionType() == "Vertices")
+ aListShapeType = GeomAPI_Shape::VERTEX;
+ else if (myParent->selectionType() == "EDGE" || myParent->selectionType() == "Edges")
+ aListShapeType = GeomAPI_Shape::EDGE;
+ else if (myParent->selectionType() == "FACE" || myParent->selectionType() == "Faces")
+ aListShapeType = GeomAPI_Shape::FACE;
}
std::list<ResultPtr>::iterator aNewCont = aNewContexts.begin();
TopTools_ListIteratorOfListOfShape aNewValues(aValShapes);
bool aFirst = true; // first is set to this, next are appended to parent
for(; aNewCont != aNewContexts.end(); aNewCont++, aNewValues.Next()) {
+ if (aSkippedContext.count(*aNewCont))
+ continue;
GeomShapePtr aValueShape;
if (!aNewValues.Value().IsNull()) {
continue;
}
- ResultPtr aSetContext;
if (aFirst) {
setValue(*aNewCont, aValueShape);
- aSetContext = context();
+ aFirst = false;
} else if (myParent) {
- myParent->append(*aNewCont, aValueShape);
- aSetContext = myParent->value(myParent->size() - 1)->context();
- }
-
- // #2826 : error if context is concealed by new context where the value is not presented
- if (aSetContext.get()) {
- bool anError = false;
- std::list<ResultPtr> allRes;
- ResultPtr aCompContext;
- ResultBodyPtr aCompBody = ModelAPI_Tools::bodyOwner(aSetContext, true);
- if (aCompBody.get()) {
- ModelAPI_Tools::allSubs(aCompBody, allRes);
- allRes.push_back(aCompBody);
- aCompContext = aCompBody;
- }
- if (allRes.empty())
- allRes.push_back(aSetContext);
-
- std::list<ResultPtr>::iterator aSub = allRes.begin();
- for (; !anError && aSub != allRes.end(); aSub++) {
- ResultPtr aResCont = *aSub;
- ResultBodyPtr aResBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aResCont);
- const std::set<AttributePtr>& aRefs = aResCont->data()->refsToMe();
- std::set<AttributePtr>::const_iterator aRef = aRefs.begin();
- for (; aRef != aRefs.end(); aRef++) {
- if (!aRef->get() || !(*aRef)->owner().get())
- continue;
- // concealed attribute only
- FeaturePtr aRefFeat = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRef)->owner());
- if (!aRefFeat.get())
- continue;
- if (!ModelAPI_Session::get()->validators()->isConcealed(
- aRefFeat->getKind(), (*aRef)->id()))
- continue;
- // check the found feature is older than this attribute
- if (aRefFeat == aThisFeature || aDoc->isLaterByDep(aRefFeat, aThisFeature))
- continue;
- // check the found feature don't have the value-shape
- GeomShapePtr aValue = aFirst ? value() : myParent->value(myParent->size() - 1)->value();
- if (aValue.get()) {
- std::list<ResultPtr>::const_iterator aRefResults = aRefFeat->results().cbegin();
- for(; aRefResults != aRefFeat->results().cend(); aRefResults++) {
- if ((*aRefResults)->shape().get() &&
- !(*aRefResults)->shape()->isSubShape(aValue, false)) { // set error
- ResultPtr anEmptyContext;
- std::shared_ptr<GeomAPI_Shape> anEmptyShape;
- if (aFirst) {
- setValue(anEmptyContext, anEmptyShape); // nullify the selection
- } else {
- myParent->value(myParent->size() - 1)->setValue(anEmptyContext, anEmptyShape);
- }
- Events_InfoMessage("Model_AttributeSelection",
- "Selection of sub-shape of already modified result").send();
- anError = true;
- break;
- }
- }
- if (anError)
- break;
- }
- }
- }
+ if (!myParent->isInList(*aNewCont, aValueShape)) // avoid addition of duplicates
+ myParent->append(*aNewCont, aValueShape);
}
- aFirst = false;
}
if (aFirst) { // nothing was added, all results were deleted
- ResultPtr anEmptyContext;
- std::shared_ptr<GeomAPI_Shape> anEmptyShape;
- setValue(anEmptyContext, anEmptyShape); // nullify the selection
- return;
+ if (myParent) {
+ theRemove = true;
+ } else {
+ ResultPtr anEmptyContext;
+ std::shared_ptr<GeomAPI_Shape> anEmptyShape;
+ setValue(anEmptyContext, anEmptyShape); // nullify the selection
+ return;
+ }
}
}
}
/// Updates the arguments of selection if something was affected by creation
/// or reorder of features upper in the history line (issue #1757)
- MODEL_EXPORT virtual void updateInHistory();
+ /// Returns theRemove true if this attribute must be removed (become deleted)
+ MODEL_EXPORT virtual void updateInHistory(bool& theRemove);
// Implementation of the name generator method from the Selector package
// This method returns the context name by the label of the sub-selected shape
MODEL_EXPORT virtual std::wstring valueW();
protected:
- /// Initializes attibutes
+ /// Initializes attributes
Model_AttributeString(TDF_Label& theLabel);
/// Reinitializes the internal state of the attribute (may be needed on undo/redo, abort, etc)
virtual void reinit();
{
}
+/// Checks that shape is presented in the tree with not-selection evolution
+/// In theOriginalLabel it returns label where NS of old sub-shape is stored
+static bool isShapeInTree(const TDF_Label& theAccess1, const TDF_Label& theAccess2,
+ TopoDS_Shape theShape, TDF_Label& theOriginalLabel)
+{
+ bool aResult = TNaming_Tool::HasLabel(theAccess1, theShape);
+ if (aResult) { //check evolution and a label of this shape
+ for(TNaming_SameShapeIterator aShapes(theShape, theAccess1); aShapes.More(); aShapes.Next())
+ {
+ static Handle(TNaming_NamedShape) aNS;
+ if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
+ if (aNS->Evolution() != TNaming_SELECTED) {
+ theOriginalLabel = aNS->Label();
+ return true;
+ }
+ }
+ }
+ }
+ if (!theAccess2.IsNull()) {
+ static const TDF_Label anEmpty;
+ return isShapeInTree(theAccess2, anEmpty, theShape, theOriginalLabel);
+ }
+ return false;
+}
+
+/// Stores entry to the external label in the entries list at this label
+static void storeExternalReference(const TDF_Label& theExternal, const TDF_Label theThis)
+{
+ // store information about the external document reference to restore old shape on open
+ if (!theExternal.IsNull() && !theExternal.Root().IsEqual(theThis.Root())) {
+ Handle(TDataStd_ExtStringList) anEntries;
+ if (!theThis.FindAttribute(kEXTERNAL_SHAPE_REF, anEntries)) {
+ anEntries = TDataStd_ExtStringList::Set(theThis, kEXTERNAL_SHAPE_REF);
+ }
+ TCollection_AsciiString anEntry;
+ TDF_Tool::Entry(theExternal, anEntry);
+ // check it already contains this entry
+ TDataStd_ListOfExtendedString::Iterator anIter(anEntries->List());
+ for(; anIter.More(); anIter.Next())
+ if (anIter.Value() == anEntry)
+ break;
+ if (!anIter.More()) {
+ anEntries->Append(anEntry);
+ }
+ }
+}
+
void Model_BodyBuilder::store(const GeomShapePtr& theShape,
const bool theIsStoreSameShapes)
{
}
void Model_BodyBuilder::storeGenerated(const GeomShapePtr& theFromShape,
- const GeomShapePtr& theToShape)
+ const GeomShapePtr& theToShape, const bool theIsCleanStored)
{
std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
if (aData) {
TDF_Label aShapeLab = aData->shapeLab();
// clean builders
- clean();
- // store the new shape as primitive
- TNaming_Builder aBuilder(aShapeLab);
+ if (theIsCleanStored)
+ clean();
+ TNaming_Builder* aBuilder = builder(0);
if (!theFromShape || !theToShape)
return; // bad shape
TopoDS_Shape aShapeBasis = theFromShape->impl<TopoDS_Shape>();
TopoDS_Shape aShapeNew = theToShape->impl<TopoDS_Shape>();
if (aShapeNew.IsNull())
return; // null shape inside
- aBuilder.Generated(aShapeBasis, aShapeNew);
+
+ // There is no sense to write history if old shape does not exist in the document.
+ TDF_Label anAccess2 = std::dynamic_pointer_cast<Model_Document>(
+ ModelAPI_Session::get()->moduleDocument())->generalLabel();
+ TDF_Label anOriginalLabel;
+ if (!isShapeInTree(aData->shapeLab(), anAccess2, aShapeBasis, anOriginalLabel)) {
+ if (aBuilder->NamedShape()->Get().IsNull()) { // store as primitive if alone anyway
+ aBuilder->Generated(aShapeNew);
+ }
+ } else {
+ if (aBuilder->NamedShape()->Evolution() == TNaming_PRIMITIVE) { // erase primitive before
+ myBuilders.erase(0);
+ aBuilder = builder(0);
+ }
+
+ aBuilder->Generated(aShapeBasis, aShapeNew);
+ // store information about the external document reference to restore old shape on open
+ storeExternalReference(anOriginalLabel, aBuilder->NamedShape()->Label());
+ }
+
// register name
- if(!aBuilder.NamedShape()->IsEmpty()) {
+ if(!aBuilder->NamedShape()->IsEmpty()) {
Handle(TDataStd_Name) anAttr;
- if(aBuilder.NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) {
+ if(aBuilder->NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) {
std::string aName (TCollection_AsciiString(anAttr->Get()).ToCString());
if(!aName.empty()) {
std::shared_ptr<Model_Document> aDoc =
std::dynamic_pointer_cast<Model_Document>(document());
- aDoc->addNamingName(aBuilder.NamedShape()->Label(), aName);
+ aDoc->addNamingName(aBuilder->NamedShape()->Label(), aName);
}
}
}
}
}
+void Model_BodyBuilder::storeGenerated(const std::list<GeomShapePtr>& theFromShapes,
+ const GeomShapePtr& theToShape, const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape)
+{
+ bool aStored = false;
+ std::list<GeomShapePtr>::const_iterator anOldIter = theFromShapes.cbegin();
+ for (; anOldIter != theFromShapes.cend(); anOldIter++) {
+ bool aStore = (*anOldIter)->isCompound() || (*anOldIter)->isShell() || (*anOldIter)->isWire();
+ if (!aStore) {
+ ListOfShape aNews; // check this old really generates theToShape
+ theMakeShape->generated(*anOldIter, aNews);
+ ListOfShape::iterator aNewIter = aNews.begin();
+ for (; aNewIter != aNews.end(); aNewIter++) {
+ if (theToShape->isSame(*aNewIter))
+ break;
+ }
+ aStore = aNewIter != aNews.end();
+ }
+ if (aStore) {
+ storeGenerated(*anOldIter, theToShape, !aStored);
+ TNaming_Builder* aBuilder = builder(0);
+ aStored = !aBuilder->NamedShape()->IsEmpty();
+ }
+ }
+ if (!aStored) { // store as PRIMITIVE, but clean in any way
+ store(theToShape);
+ return;
+ }
+}
+
TNaming_Builder* Model_BodyBuilder::builder(const int theTag)
{
std::map<int, TNaming_Builder*>::iterator aFind = myBuilders.find(theTag);
if (aData) {
// clean builders
if (theIsCleanStored) clean();
- // store the new shape as primitive
TNaming_Builder* aBuilder = builder(0);
if (!theOldShape || !theNewShape)
return; // bad shape
TopoDS_Shape aShapeNew = theNewShape->impl<TopoDS_Shape>();
if (aShapeNew.IsNull())
return; // null shape inside
- aBuilder->Modify(aShapeOld, aShapeNew);
+
+ // There is no sense to write history if old shape does not exist in the document.
+ TDF_Label anAccess2 = std::dynamic_pointer_cast<Model_Document>(
+ ModelAPI_Session::get()->moduleDocument())->generalLabel();
+ TDF_Label anOriginalLabel;
+ if (!isShapeInTree(aData->shapeLab(), anAccess2, aShapeOld, anOriginalLabel)) {
+ if (aBuilder->NamedShape()->Get().IsNull()) { // store as primitive if alone anyway
+ aBuilder->Generated(aShapeNew);
+ }
+ } else {
+ if (aBuilder->NamedShape()->Evolution() == TNaming_PRIMITIVE) { // erase primitive before
+ myBuilders.erase(0);
+ aBuilder = builder(0);
+ }
+
+ aBuilder->Modify(aShapeOld, aShapeNew);
+ // store information about the external document reference to restore old shape on open
+ storeExternalReference(anOriginalLabel, aBuilder->NamedShape()->Label());
+ }
+
if(!aBuilder->NamedShape()->IsEmpty()) {
Handle(TDataStd_Name) anAttr;
- if(aBuilder->NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) {
+ if(aBuilder->NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(), anAttr)) {
std::string aName (TCollection_AsciiString(anAttr->Get()).ToCString());
if(!aName.empty()) {
std::shared_ptr<Model_Document> aDoc =
}
}
+void Model_BodyBuilder::storeModified(const std::list<GeomShapePtr>& theOldShapes,
+ const GeomShapePtr& theNewShape, const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape)
+{
+ bool aStored = false;
+ std::list<GeomShapePtr>::const_iterator anOldIter = theOldShapes.cbegin();
+ for(; anOldIter != theOldShapes.cend(); anOldIter++) {
+ // compounds may cause crash if call "modified"
+ bool aStore = (*anOldIter)->isCompound() || (*anOldIter)->isShell() || (*anOldIter)->isWire();
+ if (!aStore) {
+ ListOfShape aNews; // check this old really modifies theNewShape
+ theMakeShape->modified(*anOldIter, aNews);
+ ListOfShape::iterator aNewIter = aNews.begin();
+ for(; aNewIter != aNews.end(); aNewIter++) {
+ if (theNewShape->isSame(*aNewIter))
+ break;
+ }
+ aStore = aNewIter != aNews.end();
+ }
+ if (aStore) {
+ storeModified(*anOldIter, theNewShape, !aStored);
+ TNaming_Builder* aBuilder = builder(0);
+ aStored = !aBuilder->NamedShape()->IsEmpty();
+ }
+ }
+ if (!aStored) { // store as PRIMITIVE, but clean in any way
+ store(theNewShape);
+ return;
+ }
+}
+
void Model_BodyBuilder::clean()
{
TDF_Label aLab = std::dynamic_pointer_cast<Model_Data>(data())->shapeLab();
}
}
-/// Checks that shape is presented in the tree with not-selection evolution
-/// In theOriginalLabel it returns label where NS of old sub-shape is stored
-static bool isShapeInTree(const TDF_Label& theAccess1, const TDF_Label& theAccess2,
- TopoDS_Shape theShape, TDF_Label& theOriginalLabel)
-{
- bool aResult = TNaming_Tool::HasLabel(theAccess1, theShape);
- if (aResult) { //check evolution and a label of this shape
- for(TNaming_SameShapeIterator aShapes(theShape, theAccess1); aShapes.More(); aShapes.Next())
- {
- static Handle(TNaming_NamedShape) aNS;
- if (aShapes.Label().FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
- if (aNS->Evolution() != TNaming_SELECTED) {
- theOriginalLabel = aNS->Label();
- return true;
- }
- }
- }
- }
- if (!theAccess2.IsNull()) {
- static const TDF_Label anEmpty;
- return isShapeInTree(theAccess2, anEmpty, theShape, theOriginalLabel);
- }
- return false;
-}
-
-/// Stores entry to the external label in the entries list at this label
-static void storeExternalReference(const TDF_Label& theExternal, const TDF_Label theThis)
-{
- // store information about the external document reference to restore old shape on open
- if (!theExternal.IsNull() && !theExternal.Root().IsEqual(theThis.Root())) {
- Handle(TDataStd_ExtStringList) anEntries;
- if (!theThis.FindAttribute(kEXTERNAL_SHAPE_REF, anEntries)) {
- anEntries = TDataStd_ExtStringList::Set(theThis, kEXTERNAL_SHAPE_REF);
- }
- TCollection_AsciiString anEntry;
- TDF_Tool::Entry(theExternal, anEntry);
- // check it already contains this entry
- TDataStd_ListOfExtendedString::Iterator anIter(anEntries->List());
- for(; anIter.More(); anIter.Next())
- if (anIter.Value() == anEntry)
- break;
- if (!anIter.More()) {
- anEntries->Append(anEntry);
- }
- }
-}
-
void Model_BodyBuilder::loadModifiedShapes(const GeomMakeShapePtr& theAlgo,
const GeomShapePtr& theOldShape,
const GeomAPI_Shape::ShapeType theShapeTypeToExplore,
bool aNewShapeIsSameAsOldShape = anOldSubShape->isSame(aNewShape);
bool aNewShapeIsNotInResultShape = !aResultShape->isSubShape(aNewShape, false);
- if (aNewShapeIsSameAsOldShape
- || aNewShapeIsNotInResultShape)
- {
+ if (aNewShapeIsSameAsOldShape || aNewShapeIsNotInResultShape)
continue;
- }
- TNaming_Builder* aBuilder;
- if (aResultShape->isSame(aNewShape)) {
- // keep the modification evolution on the root level (2241 - history propagation issue)
- aBuilder = builder(0);
- TDF_Label aShapeLab = aBuilder->NamedShape()->Label();
- Handle(TDF_Reference) aRef;
- if (aShapeLab.FindAttribute(TDF_Reference::GetID(), aRef)) {
- // Store only in case if it does not have reference.
- continue;
- }
+ if (aResultShape->isSame(aNewShape))
+ continue; // it is stored on the root level (2241 - history propagation issue)
- // Check if new shape was already stored.
- if (isAlreadyStored(aBuilder, anOldSubShape_, aNewShape_)) continue;
-
- if (!aBuilder->NamedShape().IsNull() &&
- ((isGenerated && aBuilder->NamedShape()->Evolution() != TNaming_GENERATED)
- || (!isGenerated && aBuilder->NamedShape()->Evolution() != TNaming_MODIFY)))
- {
- myBuilders.erase(0); // clear old builder to avoid different evolutions crash
- aBuilder = builder(0);
- }
- } else {
- int aTag = isGenerated ? getGenerationTag(aNewShape_)
- : getModificationTag(aNewShape_);
- aBuilder = builder(aTag);
-
- // Check if new shape was already stored.
- if (isAlreadyStored(aBuilder, anOldSubShape_, aNewShape_)) continue;
-
- buildName(aTag, theName);
- }
+ int aTag = isGenerated ? getGenerationTag(aNewShape_) : getModificationTag(aNewShape_);
+ TNaming_Builder*aBuilder = builder(aTag);
+ if (isAlreadyStored(aBuilder, anOldSubShape_, aNewShape_))
+ continue; // new shape was already stored.
+ buildName(aTag, theName);
isGenerated ? aBuilder->Generated(anOldSubShape_, aNewShape_)
: aBuilder->Modify(anOldSubShape_, aNewShape_);
// store information about the external document reference to restore old shape on open
void Model_BodyBuilder::loadGeneratedShapes(const GeomMakeShapePtr& theAlgo,
const GeomShapePtr& theOldShape,
const GeomAPI_Shape::ShapeType theShapeTypeToExplore,
- const std::string& theName)
+ const std::string& theName,
+ const bool theSaveOldIfNotInTree)
{
GeomShapePtr aResultShape = shape();
TopTools_MapOfShape anAlreadyProcessedShapes;
bool anOldSubShapeNotInTree =
!isShapeInTree(aData->shapeLab(), anAccess2, anOldSubShape_, anOriginalLabel);
if (anOldSubShapeAlreadyProcessed || anOldSubShapeNotInTree) {
- continue;
+ if (theSaveOldIfNotInTree) {
+ std::string aSelectionName = theName + "Selected";
+ generated(anOldSubShape, aSelectionName, false);
+ } else
+ continue;
}
// Get new shapes.
continue;
}
+ if (aResultShape->isSame(aNewShape))
+ continue; // it is stored on the root level
+
TopAbs_ShapeEnum aNewShapeType = aNewShape_.ShapeType();
if (aNewShapeType == TopAbs_WIRE || aNewShapeType == TopAbs_SHELL) {
// TODO: This is a workaround. New shape should be only edge or face.
storeExternalReference(anOriginalLabel, builder(aTag)->NamedShape()->Label());
}
buildName(aTag, theName);
- } if (aResultShape->isSame(aNewShape)) {
- // keep the generation evolution on the root level (2397 - for intersection feature)
- TNaming_Builder* aBuilder = builder(0);
- TDF_Label aShapeLab = aBuilder->NamedShape()->Label();
- Handle(TDF_Reference) aRef;
- if (aShapeLab.FindAttribute(TDF_Reference::GetID(), aRef)) {
- // Store only in case if it does not have reference.
- continue;
- }
-
- // Check if new shape was already stored.
- if (isAlreadyStored(aBuilder, anOldSubShape_, aNewShape_)) continue;
-
- if (!aBuilder->NamedShape().IsNull() &&
- aBuilder->NamedShape()->Evolution() != TNaming_GENERATED) {
- myBuilders.erase(0); // clear old builder to avoid different evolutions crash
- aBuilder = builder(0);
- }
- aBuilder->Generated(anOldSubShape_, aNewShape_);
} else {
int aTag = getGenerationTag(aNewShape_);
if (aTag == INVALID_TAG) return;
public:
/// Stores the shape (called by the execution method).
MODEL_EXPORT virtual void store(const GeomShapePtr& theShape,
- const bool theIsStoreSameShapes = true);
+ const bool theIsStoreSameShapes = true) override;
/// Stores the generated shape (called by the execution method).
MODEL_EXPORT virtual void storeGenerated(const GeomShapePtr& theFromShape,
- const GeomShapePtr& theToShape);
+ const GeomShapePtr& theToShape,
+ const bool theIsCleanStored = true) override;
+
+ /// Stores the root generated shapes (called by the execution method).
+ MODEL_EXPORT virtual void storeGenerated(const std::list<GeomShapePtr>& theFromShapes,
+ const GeomShapePtr& theToShape,
+ const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape) override;
/// Stores the modified shape (called by the execution method).
/// \param theOldShape shape that produces result
/// \param theNewShape resulting shape
- /// \param theDecomposeSolidsTag tag for starting of solids sub-elements placement in case
- /// theNewShape is compound of solids, if zero it is not used
+ /// \param theIsCleanStored erases all previous data structure of this body if true
MODEL_EXPORT virtual void storeModified(const GeomShapePtr& theOldShape,
const GeomShapePtr& theNewShape,
const bool theIsCleanStored = true) override;
+ /// Stores the root modified shape (called by the execution method).
+ /// \param theOldShapes all shapes that produce result
+ /// \param theNewShape resulting shape
+ /// \param theIsCleanStored erases all previous data structure of this body if true
+ MODEL_EXPORT virtual void storeModified(const std::list<GeomShapePtr>& theOldShapes,
+ const GeomShapePtr& theNewShape,
+ const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape) override;
+
/// Returns the shape-result produced by this feature
MODEL_EXPORT virtual GeomShapePtr shape();
virtual void loadGeneratedShapes(const GeomMakeShapePtr& theAlgo,
const GeomShapePtr& theOldShape,
const GeomAPI_Shape::ShapeType theShapeTypeToExplore,
- const std::string& theName = "") override;
+ const std::string& theName = "",
+ const bool theSaveOldIfNotInTree = false) override;
/// Loads shapes of the first level (to be used during shape import)
MODEL_EXPORT virtual void loadFirstLevel(GeomShapePtr theShape,
#include <ModelAPI_Tools.h>
#include <Model_Data.h>
#include <Events_Loop.h>
+#include <GeomAPI_ShapeIterator.h>
+#include <GeomAPI_ShapeExplorer.h>
#include <TopoDS_Shape.hxx>
#include <TopExp_Explorer.hxx>
+#include <TopTools_MapOfShape.hxx>
#include <TDataStd_UAttribute.hxx>
// if this attribute exists, the shape is connected topology
void Model_ResultBody::loadGeneratedShapes(const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgo,
const GeomShapePtr& theOldShape,
const GeomAPI_Shape::ShapeType theShapeTypeToExplore,
- const std::string& theName)
+ const std::string& theName,
+ const bool theSaveOldIfNotInTree)
{
if (mySubs.size()) { // consists of subs
for (std::vector<ResultBodyPtr>::const_iterator aSubIter = mySubs.cbegin();
++aSubIter)
{
const ResultBodyPtr& aSub = *aSubIter;
- aSub->loadGeneratedShapes(theAlgo, theOldShape, theShapeTypeToExplore, theName);
+ aSub->loadGeneratedShapes(
+ theAlgo, theOldShape, theShapeTypeToExplore, theName, theSaveOldIfNotInTree);
}
} else { // do for this directly
- myBuilder->loadGeneratedShapes(theAlgo, theOldShape, theShapeTypeToExplore, theName);
+ myBuilder->loadGeneratedShapes(
+ theAlgo, theOldShape, theShapeTypeToExplore, theName, theSaveOldIfNotInTree);
}
}
const GeomAPI_Shape::ShapeType theShapeTypeToExplore,
const std::string& theName)
{
- if (/*theSplitInSubs &&*/ mySubs.size()) { // consists of subs
+ if (mySubs.size()) { // consists of subs
// optimization of getting of new shapes for specific sub-result
if (!theAlgo->isNewShapesCollected(theOldShape, theShapeTypeToExplore))
theAlgo->collectNewShapes(theOldShape, theShapeTypeToExplore);
std::vector<ResultBodyPtr>::const_iterator aSubIter = mySubs.cbegin();
for(; aSubIter != mySubs.cend(); aSubIter++) {
- // check that sub-shape was also created as modification of ShapeIn
- /* to find when it is needed later to enable: to store modification of sub-bodies not only as primitives
- GeomShapePtr aSubGeomShape = (*aSubIter)->shape();
- if (!theIsStoreAsGenerated && aSubGeomShape.get() && !aSubGeomShape->isNull()) {
- TopoDS_Shape aSubShape = aSubGeomShape->impl<TopoDS_Shape>();
- TopoDS_Shape aWholeIn = theShapeIn->impl<TopoDS_Shape>();
- for(TopExp_Explorer anExp(aWholeIn, aSubShape.ShapeType()); anExp.More(); anExp.Next()) {
- ListOfShape aHistory;
- std::shared_ptr<GeomAPI_Shape> aSubIn(new GeomAPI_Shape());
- aSubIn->setImpl((new TopoDS_Shape(anExp.Current())));
- theMS->modified(aSubIn, aHistory);
- std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator anIt = aHistory.begin();
- for (; anIt != aHistory.end(); anIt++) {
- if ((*anIt)->isSame(aSubGeomShape)) {
- (*aSubIter)->storeModified(aSubIn, aSubGeomShape, -2); // -2 is to avoid clearing
- }
- }
- }
- }*/
(*aSubIter)->loadModifiedShapes(theAlgo, theOldShape, theShapeTypeToExplore, theName);
}
} else { // do for this directly
}
GeomShapePtr anOldSubShape = aSub->shape();
if (!aShape->isEqual(anOldSubShape)) {
- aSub->store(aShape, false);
+ if (myAlgo.get()) {
+ std::list<GeomShapePtr> anOldForSub;
+ computeOldForSub(aShape, myOlds, anOldForSub);
+ myIsGenerated ? aSub->storeGenerated(anOldForSub, aShape, myAlgo) :
+ aSub->storeModified(anOldForSub, aShape, myAlgo);
+ } else {
+ aSub->store(aShape, false);
+ }
aECreator->sendUpdated(aSub, EVENT_DISP);
aECreator->sendUpdated(aSub, EVENT_UPD);
}
}
}
+void Model_ResultBody::updateSubs(
+ const GeomShapePtr& theThisShape, const std::list<GeomShapePtr>& theOlds,
+ const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape, const bool isGenerated)
+{
+ myAlgo = theMakeShape;
+ myOlds = theOlds;
+ myIsGenerated = isGenerated;
+ // to avoid changing of "isDisabled" flag in the "updateSubs" cycle
+ isDisabled();
+
+ updateSubs(theThisShape, true);
+ myAlgo.reset();
+ myOlds.clear();
+ myHistoryCash.Clear();
+}
+
+
bool Model_ResultBody::isConnectedTopology()
{
TDF_Label aDataLab = std::dynamic_pointer_cast<Model_Data>(data())->label();
aSub->cleanCash();
}
}
+
+// adds to the theSubSubs map all sub-shapes of theSub if it is compound of compsolid
+static void collectSubs(
+ const GeomShapePtr theSub, TopTools_MapOfShape& theSubSubs, const bool theOneLevelMore)
+{
+ if (theSub->isNull())
+ return;
+ if (theSubSubs.Add(theSub->impl<TopoDS_Shape>())) {
+ bool aIsComp = theSub->isCompound() || theSub->isCompSolid();
+ if (aIsComp) {
+ for(GeomAPI_ShapeIterator anIter(theSub); anIter.more(); anIter.next())
+ collectSubs(anIter.current(), theSubSubs, theOneLevelMore);
+ } else if (theOneLevelMore) {
+ GeomAPI_Shape::ShapeType aSubType = GeomAPI_Shape::ShapeType(int(theSub->shapeType()) + 1);
+ if (aSubType == GeomAPI_Shape::SHAPE)
+ return;
+ if (aSubType == GeomAPI_Shape::SHELL)
+ aSubType = GeomAPI_Shape::FACE;
+ if (aSubType == GeomAPI_Shape::WIRE)
+ aSubType = GeomAPI_Shape::EDGE;
+
+ for(GeomAPI_ShapeExplorer anExp(theSub, aSubType); anExp.more(); anExp.next()) {
+ collectSubs(anExp.current(), theSubSubs, false);
+ }
+ }
+ }
+}
+
+void Model_ResultBody::computeOldForSub(const GeomShapePtr& theSub,
+ const std::list<GeomShapePtr>& theAllOlds, std::list<GeomShapePtr>& theOldForSub)
+{
+ // the old can be also used for sub-shape of theSub; collect all subs of compound or compsolid
+ TopTools_MapOfShape aSubSubs;
+ collectSubs(theSub, aSubSubs, false);
+
+ std::list<GeomShapePtr>::const_iterator aRootOlds = theAllOlds.cbegin();
+ for (; aRootOlds != theAllOlds.cend(); aRootOlds++) {
+ // use sub-shapes of olds too if they are compounds or compsolids
+ TopTools_MapOfShape anOldSubs;
+ // iterate one level more (for intersection of solids this is face)
+ collectSubs(*aRootOlds, anOldSubs, true);
+ for (TopTools_MapOfShape::Iterator anOldIter(anOldSubs); anOldIter.More(); anOldIter.Next()) {
+ TopoDS_Shape anOldShape = anOldIter.Value();
+ if (anOldShape.ShapeType() == TopAbs_COMPOUND || anOldShape.ShapeType() == TopAbs_SHELL ||
+ anOldShape.ShapeType() == TopAbs_WIRE)
+ continue; // container old-shapes are not supported by the history, may cause crash
+ GeomShapePtr anOldSub(new GeomAPI_Shape);
+ anOldSub->setImpl<TopoDS_Shape>(new TopoDS_Shape(anOldShape));
+
+ ListOfShape aNews;
+ if (myHistoryCash.IsBound(anOldShape)) {
+ const TopTools_ListOfShape& aList = myHistoryCash.Find(anOldShape);
+ for(TopTools_ListIteratorOfListOfShape anIter(aList); anIter.More(); anIter.Next()) {
+ GeomShapePtr aShape(new GeomAPI_Shape);
+ aShape->setImpl<TopoDS_Shape>(new TopoDS_Shape(anIter.Value()));
+ aNews.push_back(aShape);
+ }
+ } else {
+ myIsGenerated ? myAlgo->generated(anOldSub, aNews) : myAlgo->modified(anOldSub, aNews);
+ // MakeShape may return alone old shape if there is no history information for this input
+ if (aNews.size() == 1 && aNews.front()->isEqual(anOldSub))
+ aNews.clear();
+ // store result in the history
+ TopTools_ListOfShape aList;
+ for (ListOfShape::iterator aNewIter = aNews.begin(); aNewIter != aNews.end(); aNewIter++) {
+ aList.Append((*aNewIter)->impl<TopoDS_Shape>());
+ }
+ myHistoryCash.Bind(anOldShape, aList);
+ }
+
+ for (ListOfShape::iterator aNewIter = aNews.begin(); aNewIter != aNews.end(); aNewIter++) {
+ if (aSubSubs.Contains((*aNewIter)->impl<TopoDS_Shape>())) {
+ // check list already contains this sub
+ std::list<GeomShapePtr>::iterator aResIter = theOldForSub.begin();
+ for(; aResIter != theOldForSub.end(); aResIter++)
+ if ((*aResIter)->isSame(anOldSub))
+ break;
+ if (aResIter == theOldForSub.end())
+ theOldForSub.push_back(anOldSub); // found old used for new theSubShape creation
+ break;
+ }
+ }
+ }
+ }
+}
#include <vector>
#include <map>
+#include <TopTools_DataMapOfShapeListOfShape.hxx>
+
/**\class Model_ResultBody
* \ingroup DataModel
* \brief The body (shape) result of a feature.
std::map<ObjectPtr, int> mySubsMap;
/// Keeps the last state of the concealment flag in order to update it when needed.
bool myLastConcealed;
+ /// History information for update subs
+ std::shared_ptr<GeomAlgoAPI_MakeShape> myAlgo;
+ /// All old shapes used for the root result construction
+ std::list<GeomShapePtr> myOlds;
+ /// Information about the kind of the history information: modified or generated
+ bool myIsGenerated;
+ /// Map from old shape to list of new shapes, cash for computeOldForSub method
+ TopTools_DataMapOfShapeListOfShape myHistoryCash;
public:
virtual void loadGeneratedShapes(const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgo,
const GeomShapePtr& theOldShape,
const GeomAPI_Shape::ShapeType theShapeTypeToExplore,
- const std::string& theName = "") override;
+ const std::string& theName = "",
+ const bool theSaveOldIfNotInTree = false) override;
/// load modified shapes for sub-objects
MODEL_EXPORT
void updateSubs(const std::shared_ptr<GeomAPI_Shape>& theThisShape,
const bool theShapeChanged = true);
+ /// Updates the sub-bodies in accordance to the algorithm history information
+ void updateSubs(
+ const GeomShapePtr& theThisShape, const std::list<GeomShapePtr>& theOlds,
+ const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape, const bool isGenerated);
+
// Checks the state of children and parents to send events of creation/erase when needed
void updateConcealment();
+ /// Adds to theOldForSub only old shapes that where used for theSub creation
+ void computeOldForSub(const GeomShapePtr& theSub,
+ const std::list<GeomShapePtr>& theAllOlds, std::list<GeomShapePtr>& theOldForSub);
+
friend class Model_Objects;
};
}
}
- std::list<std::shared_ptr<GeomAPI_Shape> > aFaces;
- GeomAlgoAPI_SketchBuilder::createFaces(aWirePtr->origin(), aWirePtr->dirX(),
- aWirePtr->norm(), aWirePtr, aFaces);
+ GeomAlgoAPI_SketchBuilder aSketchBuilder(aWirePtr->origin(), aWirePtr->dirX(),
+ aWirePtr->norm(), aWirePtr);
+ const ListOfShape& aFaces = aSketchBuilder.faces();
// order is important to store faces in the same order if sketch is created from scratch
NCollection_IndexedDataMap<TopoDS_Face, TColStd_ListOfInteger> aNewIndices; // edges indices
- std::list<std::shared_ptr<GeomAPI_Shape> >::iterator aFIter = aFaces.begin();
+ std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator aFIter = aFaces.begin();
for (; aFIter != aFaces.end(); aFIter++) {
std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(*aFIter));
// put them to a label, trying to keep the same faces on the same labels
for (; aRefsIter != aRefs.end(); aRefsIter++) {
std::shared_ptr<Model_AttributeSelection> aSel =
std::dynamic_pointer_cast<Model_AttributeSelection>(*aRefsIter);
- aSel->updateInHistory();
+ bool aRemove = false;
+ aSel->updateInHistory(aRemove);
}
// update the selection list attributes if any
aRefs = (*anObj)->data()->attributes(ModelAPI_AttributeSelectionList::typeId());
for (aRefsIter = aRefs.begin(); aRefsIter != aRefs.end(); aRefsIter++) {
+ std::set<int> aRemoveSet;
std::shared_ptr<ModelAPI_AttributeSelectionList> aSel =
std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(*aRefsIter);
for(int a = aSel->size() - 1; a >= 0; a--) {
std::shared_ptr<Model_AttributeSelection> aSelAttr =
std::dynamic_pointer_cast<Model_AttributeSelection>(aSel->value(a));
- if (aSelAttr.get())
- aSelAttr->updateInHistory();
+ if (aSelAttr.get()) {
+ bool theRemove = false;
+ aSelAttr->updateInHistory(theRemove);
+ if (theRemove) {
+ aRemoveSet.insert(a);
+ }
+ }
}
+ aSel->remove(aRemoveSet);
}
}
}
/// Stores the generated shape (called by the execution method).
virtual void storeGenerated(const GeomShapePtr& theFromShape,
- const GeomShapePtr& theToShape) = 0;
+ const GeomShapePtr& theToShape,
+ const bool theIsCleanStored = true) = 0;
+
+ /// Stores the root generated shapes (called by the execution method).
+ virtual void storeGenerated(const std::list<GeomShapePtr>& theFromShapes,
+ const GeomShapePtr& theToShape, const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape) = 0;
/// Stores the modified shape (called by the execution method).
virtual void storeModified(const GeomShapePtr& theOldShape,
const GeomShapePtr& theNewShape,
const bool theIsCleanStored = true) = 0;
+ /// Stores the root modified shapes (called by the execution method).
+ virtual void storeModified(const std::list<GeomShapePtr>& theOldShapes,
+ const GeomShapePtr& theNewShape, const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape)=0;
+
/// Returns the shape-result produced by this feature
virtual GeomShapePtr shape() = 0;
virtual void loadGeneratedShapes(const GeomMakeShapePtr& theAlgo,
const GeomShapePtr& theOldShape,
const GeomAPI_Shape::ShapeType theShapeTypeToExplore,
- const std::string& theName = "") = 0;
+ const std::string& theName = "",
+ const bool theSaveOldIfNotInTree = false) = 0;
/// load shapes of the first level (to be used during shape import)
virtual void loadFirstLevel(GeomShapePtr theShape,
updateSubs(theToShape);
}
+void ModelAPI_ResultBody::storeGenerated(
+ const std::list<GeomShapePtr>& theFromShapes, const GeomShapePtr& theToShape,
+ const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape)
+{
+ myBuilder->storeGenerated(theFromShapes, theToShape, theMakeShape);
+ myConnect = ConnectionNotComputed;
+
+ static Events_Loop* aLoop = Events_Loop::loop();
+ static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
+ aECreator->sendUpdated(data()->owner(), aRedispEvent);
+
+ updateSubs(theToShape, theFromShapes, theMakeShape, true);
+}
+
void ModelAPI_ResultBody::storeModified(const GeomShapePtr& theOldShape,
const GeomShapePtr& theNewShape,
const bool theIsCleanStored)
updateSubs(theNewShape);
}
+void ModelAPI_ResultBody::storeModified(
+ const std::list<GeomShapePtr>& theOldShapes, const GeomShapePtr& theNewShape,
+ const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape)
+{
+ myBuilder->storeModified(theOldShapes, theNewShape, theMakeShape);
+ myConnect = ConnectionNotComputed;
+
+ static Events_Loop* aLoop = Events_Loop::loop();
+ static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+ static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
+ aECreator->sendUpdated(data()->owner(), aRedispEvent);
+
+ updateSubs(theNewShape, theOldShapes, theMakeShape, false);
+}
+
GeomShapePtr ModelAPI_ResultBody::shape()
{
return myBuilder->shape();
MODELAPI_EXPORT virtual void storeGenerated(const GeomShapePtr& theFromShape,
const GeomShapePtr& theToShape);
+ /// Stores the root modified shapes (called by the execution method).
+ MODELAPI_EXPORT virtual void storeGenerated(
+ const std::list<GeomShapePtr>& theFromShapes, const GeomShapePtr& theToShape,
+ const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape);
+
/// Stores the modified shape (called by the execution method).
MODELAPI_EXPORT virtual void storeModified(const GeomShapePtr& theOldShape,
const GeomShapePtr& theNewShape,
const bool theIsCleanStored = true);
+ /// Stores the root modified shapes (called by the execution method).
+ MODELAPI_EXPORT virtual void storeModified(
+ const std::list<GeomShapePtr>& theOldShapes, const GeomShapePtr& theNewShape,
+ const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape);
+
/// Returns the shape-result produced by this feature
MODELAPI_EXPORT virtual GeomShapePtr shape();
virtual void loadGeneratedShapes(const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgo,
const GeomShapePtr& theOldShape,
const GeomAPI_Shape::ShapeType theShapeTypeToExplore,
- const std::string& theName = "") = 0;
+ const std::string& theName = "",
+ const bool theSaveOldIfNotInTree = false) = 0;
/// load shapes of the first level (to be used during shape import)
MODELAPI_EXPORT virtual void loadFirstLevel(GeomShapePtr theShape,
MODELAPI_EXPORT virtual void updateSubs(const GeomShapePtr& theThisShape,
const bool theShapeChanged = true) = 0;
+ /// Updates the sub-bodies in accordance to the algorithm history information
+ MODELAPI_EXPORT virtual void updateSubs(
+ const GeomShapePtr& theThisShape, const std::list<GeomShapePtr>& theOlds,
+ const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape, const bool isGenerated) = 0;
+
/// Cleans cash related to the already stored elements
MODELAPI_EXPORT virtual void cleanCash() = 0;
ExtrusionCut_2 = model.addExtrusionCut(Part_1_doc, [model.selection("COMPOUND", "Sketch_4")], model.selection(), "h", 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
Fillet_1_objects = [model.selection("EDGE", "[ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/To_Face][(ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_1)(ExtrusionCut_2_1/Modified_Face&Sketch_3/SketchLine_12)(ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/To_Face)]"), model.selection("EDGE", "[(ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_3)(ExtrusionCut_2_1/Modified_Face&Sketch_3/SketchLine_12)(ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/To_Face)][ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/To_Face]"), model.selection("EDGE", "[Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_2][ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/To_Face]"), model.selection("EDGE", "[ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/From_Face][Extrusion_1_1/Generated_Face&Sketch_1/SketchLine_2]"), model.selection("EDGE", "[(ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/From_Face)(ExtrusionCut_2_1/Modified_Face&Sketch_3/SketchLine_9)(ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_3)][ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/From_Face]"), model.selection("EDGE", "[ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/From_Face][(ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/From_Face)(ExtrusionCut_2_1/Modified_Face&Sketch_3/SketchLine_9)(ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_1)]"), model.selection("EDGE", "[ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/From_Face][ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_3]"), model.selection("EDGE", "[ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/From_Face][ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_1]"), model.selection("EDGE", "[ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_3][ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/To_Face]"), model.selection("EDGE", "[ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_1][ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/To_Face]"), model.selection("EDGE", "[ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_3][(ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_3)(ExtrusionCut_2_1/Modified_Face&Sketch_3/SketchLine_12)(ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/To_Face)]"), model.selection("EDGE", "[(ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/From_Face)(ExtrusionCut_2_1/Modified_Face&Sketch_3/SketchLine_9)(ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_3)][ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_3]"), model.selection("EDGE", "[(ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/From_Face)(ExtrusionCut_2_1/Modified_Face&Sketch_3/SketchLine_9)(ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_1)][ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_1]"), model.selection("EDGE", "[ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_1][(ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_1)(ExtrusionCut_2_1/Modified_Face&Sketch_3/SketchLine_12)(ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/To_Face)]"), model.selection("EDGE", "[(ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_1)(ExtrusionCut_2_1/Modified_Face&Sketch_3/SketchLine_12)(ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/To_Face)][ExtrusionCut_2_1/Generated_Face&Sketch_4/SketchLine_16&weak_name_2]"), model.selection("EDGE", "[(ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_3)(ExtrusionCut_2_1/Modified_Face&Sketch_3/SketchLine_12)(ExtrusionCut_2_1/Modified_Face&Extrusion_1_1/To_Face)][ExtrusionCut_2_1/Generated_Face&Sketch_4/SketchLine_18&weak_name_2]")]
Fillet_1 = model.addFillet(Part_1_doc, Fillet_1_objects, 2)
-Group_1_objects = [model.selection("FACE", "Fillet_1_1/Modified_Face&Sketch_1/SketchLine_4&weak_name_1"), model.selection("FACE", "Fillet_1_1/Modified_Face&Sketch_1/SketchLine_4&weak_name_4"), model.selection("FACE", "Fillet_1_1/Modified_Face&Sketch_1/SketchLine_4&weak_name_2"), model.selection("FACE", "Fillet_1_1/Modified_Face&Sketch_1/SketchLine_4&weak_name_3")]
+Group_1_objects = [
+model.selection("FACE", "(Fillet_1_1/GF:Fillet&Fillet_1_1/FilletSelected_14)(Fillet_1_1/MF:Fillet_Face&Sketch_3/SketchLine_12)(Fillet_1_1/GF:Fillet&Fillet_1_1/FilletSelected_15)(Fillet_1_1/GF:Fillet&Fillet_1_1/FilletSelected_1)"),
+model.selection("FACE", "(Fillet_1_1/MF:Fillet_Face&Sketch_3/SketchLine_12)(Fillet_1_1/GF:Fillet&Fillet_1_1/FilletSelected_11)(Fillet_1_1/GF:Fillet&Fillet_1_1/FilletSelected_16)(Fillet_1_1/GF:Fillet&Fillet_1_1/FilletSelected_2)"),
+model.selection("FACE", "(Fillet_1_1/MF:Fillet_Face&Sketch_3/SketchLine_9)(Fillet_1_1/GF:Fillet&Fillet_1_1/FilletSelected_13)(Fillet_1_1/GF:Fillet&Fillet_1_1/FilletSelected_6)"),
+model.selection("FACE", "(Fillet_1_1/GF:Fillet&Fillet_1_1/FilletSelected_5)(Fillet_1_1/MF:Fillet_Face&Sketch_3/SketchLine_9)(Fillet_1_1/GF:Fillet&Fillet_1_1/FilletSelected_12)")
+]
Group_1 = model.addGroup(Part_1_doc, Group_1_objects)
-Group_2 = model.addGroup(Part_1_doc, [model.selection("EDGE", "[(Fillet_1_1/Modified_Face&Sketch_1/SketchLine_3)(Fillet_1_1/Modified_Face&Extrusion_1_1/To_Face)][Fillet_1_1/Modified_Face&Extrusion_1_1/To_Face]"), model.selection("EDGE", "[Fillet_1_1/Modified_Face&Sketch_1/SketchLine_3][(Fillet_1_1/Modified_Face&Sketch_1/SketchLine_3)(Fillet_1_1/Modified_Face&Extrusion_1_1/To_Face)]")])
-Group_3 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "[Fillet_1_1/Modified_Face&Sketch_3/SketchLine_9][ExtrusionCut_1_1/Generated_Face&Sketch_3/SketchLine_13][Fillet_1_1/Modified_Face&Sketch_1/SketchLine_3]"), model.selection("VERTEX", "[ExtrusionCut_1_1/Generated_Face&Sketch_3/SketchLine_13][Fillet_1_1/Modified_Face&Sketch_1/SketchLine_3][Fillet_1_1/Modified_Face&Sketch_3/SketchLine_12]")])
+Group_2 = model.addGroup(Part_1_doc, [model.selection("EDGE", "[Fillet_1_1/GF:Fillet&Fillet_1_1/FilletSelected_9][Fillet_1_1/MF:Fillet_Face&Extrusion_1_1/To_Face]"), model.selection("EDGE", "[Fillet_1_1/MF:Fillet_Face&Sketch_1/SketchLine_3][Fillet_1_1/GF:Fillet&Fillet_1_1/FilletSelected_9]")])
+Group_3 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "[Fillet_1_1/MF:Fillet_Face&Sketch_3/SketchLine_9][ExtrusionCut_1_1/Generated_Face&Sketch_3/SketchLine_13][Fillet_1_1/MF:Fillet_Face&Sketch_1/SketchLine_3]"), model.selection("VERTEX", "[ExtrusionCut_1_1/Generated_Face&Sketch_3/SketchLine_13][Fillet_1_1/MF:Fillet_Face&Sketch_1/SketchLine_3][Fillet_1_1/MF:Fillet_Face&Sketch_3/SketchLine_12]")])
model.do()
Folder_1 = model.addFolder(Part_1_doc, Sketch_3, ExtrusionCut_2)
Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchLine_9r-SketchLine_8r-SketchLine_7r-SketchLine_6r-SketchLine_14f-SketchLine_16r-SketchArc_3_2r-SketchLine_15f-SketchLine_13r-SketchArc_2_2r-SketchCircle_2_2r")], model.selection(), -165, 155)
Boolean_1 = model.addFuse(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], [model.selection("SOLID", "Extrusion_2_1")])
-Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "(Fuse_1_1/Modified_Face&Extrusion_1_1/To_Face)(Extrusion_1_1/Generated_Face&Sketch_1/SketchArc_1_2)(Fuse_1_1/Modified_Face&Sketch_1/SketchLine_5&Sketch_2/SketchLine_7)"))
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "(Fuse_1_1/Modified_Face&Extrusion_1_1/To_Face)(Extrusion_1_1/Generated_Face&Sketch_1/SketchArc_1_2)(Fuse_1_1/Modified_Face&Sketch_2/SketchLine_7&Sketch_1/SketchLine_5)"))
SketchLine_17 = Sketch_3.addLine(145, 0, 165, 0)
-SketchProjection_2 = Sketch_3.addProjection(model.selection("VERTEX", "[Fuse_1_1/Modified_Face&Extrusion_1_1/From_Face&Sketch_2/SketchLine_6][Fuse_1_1/Modified_Face&Sketch_1/SketchLine_1&Extrusion_2_1/To_Face][Fuse_1_1/Modified_Face&Sketch_1/SketchLine_5&Sketch_2/SketchLine_7]"))
+SketchProjection_2 = Sketch_3.addProjection(model.selection("VERTEX", "[Fuse_1_1/Modified_Face&Sketch_2/SketchLine_6&Extrusion_1_1/From_Face][Fuse_1_1/Modified_Face&Extrusion_2_1/To_Face&Sketch_1/SketchLine_1][Fuse_1_1/Modified_Face&Sketch_2/SketchLine_7&Sketch_1/SketchLine_5]"))
SketchPoint_2 = SketchProjection_2.createdFeature()
SketchConstraintCoincidence_23 = Sketch_3.setCoincident(SketchLine_17.endPoint(), SketchAPI_Point(SketchPoint_2).result())
SketchLine_18 = Sketch_3.addLine(165, 0, 165, -20)
SketchConstraintCoincidence_31 = Sketch_3.setCoincident(SketchLine_19.endPoint(), SketchArc_5.center())
SketchConstraintCoincidence_32 = Sketch_3.setCoincident(SketchLine_20.result(), SketchArc_5.endPoint())
SketchConstraintCoincidence_33 = Sketch_3.setCoincident(SketchArc_5.startPoint(), SketchLine_19.result())
-SketchLine_21 = Sketch_3.addLine(model.selection("EDGE", "[Fuse_1_1/Modified_Face&Extrusion_2_1/From_Face][(Fuse_1_1/Modified_Face&Extrusion_2_1/From_Face)(Extrusion_2_1/Generated_Face&Sketch_2/SketchLine_8)(Fuse_1_1/Modified_Face&Sketch_1/SketchLine_5&Sketch_2/SketchLine_7)]"))
+SketchLine_21 = Sketch_3.addLine(model.selection("EDGE", "[Fuse_1_1/Modified_Face&Extrusion_2_1/From_Face][(Fuse_1_1/Modified_Face&Extrusion_2_1/From_Face)(Extrusion_2_1/Generated_Face&Sketch_2/SketchLine_8)(Fuse_1_1/Modified_Face&Sketch_2/SketchLine_7&Sketch_1/SketchLine_5)]"))
SketchConstraintTangent_5 = Sketch_3.setTangent(SketchArc_5.results()[1], SketchLine_21.result())
model.do()
-ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchArc_4_2r-SketchLine_18r-SketchLine_17r")], model.selection(), model.selection("FACE", "Fuse_1_1/Modified_Face&Sketch_1/SketchLine_2&Sketch_2/SketchLine_9"), 0, model.selection(), 0, [model.selection("SOLID", "Fuse_1_1")])
-ExtrusionFuse_1 = model.addExtrusionFuse(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchArc_4_2f-SketchLine_20r-SketchArc_5_2r-SketchLine_19r")], model.selection(), model.selection("FACE", "(Fuse_1_1/Modified_Face&Extrusion_2_1/From_Face)(ExtrusionCut_1_1/Modified_Face&Sketch_1/SketchLine_2&Sketch_2/SketchLine_9)(ExtrusionCut_1_1/Generated_Face&Sketch_3/SketchArc_4_2)(ExtrusionCut_1_1/Modified_Face&Extrusion_2_1/To_Face)(Extrusion_2_1/Generated_Face&Sketch_2/SketchLine_8)"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
+ExtrusionCut_1 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchArc_4_2r-SketchLine_18r-SketchLine_17r")], model.selection(), model.selection("FACE", "Fuse_1_1/Modified_Face&Sketch_2/SketchLine_9&Sketch_1/SketchLine_2"), 0, model.selection(), 0, [model.selection("SOLID", "Fuse_1_1")])
+ExtrusionFuse_1 = model.addExtrusionFuse(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchArc_4_2f-SketchLine_20r-SketchArc_5_2r-SketchLine_19r")], model.selection(), model.selection("FACE", "(Fuse_1_1/Modified_Face&Extrusion_2_1/From_Face)(ExtrusionCut_1_1/Modified_Face&Sketch_2/SketchLine_9&Sketch_1/SketchLine_2)(ExtrusionCut_1_1/Generated_Face&Sketch_3/SketchArc_4_2)(ExtrusionCut_1_1/Modified_Face&Extrusion_2_1/To_Face)(Extrusion_2_1/Generated_Face&Sketch_2/SketchLine_8)"), 0, model.selection(), 0, [model.selection("SOLID", "ExtrusionCut_1_1")])
model.do()
model.end()