Refactoring the Placement feature.
%feature("kwargs") addCut;
%feature("kwargs") addFuse;
%feature("kwargs") addPartition;
+%feature("kwargs") addPlacement;
%feature("kwargs") addSplit;
%feature("kwargs") addSmash;
%feature("kwargs") addUnion;
AttributeBooleanPtr anAttrCentering = aBase->boolean(FeaturesPlugin_Placement::CENTERING_ID());
theDumper << aBase << " = model.addPlacement(" << aDocName << ", "
- << anAttrObjects << ", " << anAttrStartShape << ", " << anAttrEndShape << ", "
- << anAttrReverse << ", " << anAttrCentering << ")" << std::endl;
+ << anAttrObjects << ", " << anAttrStartShape << ", " << anAttrEndShape;
+
+ if (anAttrReverse->value())
+ theDumper << ", reverse = " << anAttrReverse;
+ if (anAttrCentering->value())
+ theDumper << ", centering = " << anAttrCentering;
+ if (!aBase->data()->version().empty())
+ theDumper << ", keepSubResults = True";
+
+ theDumper << ")" << std::endl;
}
//==================================================================================================
const ModelHighAPI_Selection& theStartShape,
const ModelHighAPI_Selection& theEndShape,
const bool theReverseDirection,
- const bool theCentering)
+ const bool theCentering,
+ const bool keepSubResults)
{
std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(FeaturesAPI_Placement::ID());
+ if (!keepSubResults)
+ aFeature->data()->setVersion("");
return PlacementPtr(new FeaturesAPI_Placement(aFeature,
theObjects,
theStartShape,
const std::list<ModelHighAPI_Selection>& theObjects,
const ModelHighAPI_Selection& theStartShape,
const ModelHighAPI_Selection& theEndShape,
- const bool theReverseDirection = false,
- const bool theCentering = false);
+ const bool reverse = false,
+ const bool centering = false,
+ const bool keepSubResults = false);
#endif // FeaturesAPI_Placement_H_
Test3137_1.py
Test3137_2.py
Test3139.py
+ TestPlacement_MultiLevelCompound_v0_1.py
+ TestPlacement_MultiLevelCompound_v0_2.py
+ TestPlacement_MultiLevelCompound_v0_3.py
+ TestPlacement_MultiLevelCompound_v0_4.py
+ TestPlacement_MultiLevelCompound_v0_5.py
+ TestPlacement_MultiLevelCompound_v0_6.py
+ TestPlacement_MultiLevelCompound_v95_1.py
+ TestPlacement_MultiLevelCompound_v95_2.py
+ TestPlacement_MultiLevelCompound_v95_3.py
+ TestPlacement_MultiLevelCompound_v95_4.py
+ TestPlacement_MultiLevelCompound_v95_5.py
+ TestPlacement_MultiLevelCompound_v95_6.py
)
#include <ModelAPI_AttributeBoolean.h>
#include <ModelAPI_AttributeSelectionList.h>
#include <ModelAPI_BodyBuilder.h>
+#include <ModelAPI_Tools.h>
#include <GeomAPI_Edge.h>
#include <GeomAPI_Face.h>
#include <GeomAPI_Pln.h>
+#include <GeomAPI_ShapeHierarchy.h>
#include <GeomAPI_ShapeIterator.h>
+
+#include <GeomAlgoAPI_MakeShapeList.h>
#include <GeomAlgoAPI_Placement.h>
#include <GeomAlgoAPI_Transform.h>
#include <GeomAlgoAPI_Tools.h>
#include <FeaturesPlugin_Tools.h>
+static const std::string PLACEMENT_VERSION_1("v9.5");
+
FeaturesPlugin_Placement::FeaturesPlugin_Placement()
{
}
void FeaturesPlugin_Placement::initAttributes()
{
-
AttributeSelectionListPtr aSelection =
std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
OBJECTS_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
data()->addAttribute(END_SHAPE_ID(), ModelAPI_AttributeSelection::typeId());
data()->addAttribute(REVERSE_ID(), ModelAPI_AttributeBoolean::typeId());
data()->addAttribute(CENTERING_ID(), ModelAPI_AttributeBoolean::typeId());
+
+ if (!aSelection->isInitialized()) {
+ // new feature, not read from file
+ data()->setVersion(PLACEMENT_VERSION_1);
+ }
}
void FeaturesPlugin_Placement::execute()
{
+ bool isKeepSubShapes = data()->version() == PLACEMENT_VERSION_1;
+
// Getting objects.
- ListOfShape anObjects;
- std::list<ResultPtr> aContextes;
+ GeomAPI_ShapeHierarchy anObjects;
+ std::list<ResultPtr> aParts;
AttributeSelectionListPtr anObjectsSelList = selectionList(OBJECTS_LIST_ID());
if(anObjectsSelList->size() == 0) {
return;
if(!anObject.get()) { // may be for not-activated parts
return;
}
- anObjects.push_back(anObject);
- aContextes.push_back(anObjectAttr->context());
+ ResultPtr aContext = anObjectAttr->context();
+ if (aContext->groupName() == ModelAPI_ResultPart::group())
+ aParts.push_back(aContext);
+ else {
+ // store full shape hierarchy for the corresponding version only
+ anObjects.addObject(anObject);
+ if (isKeepSubShapes)
+ ModelAPI_Tools::fillShapeHierarchy(anObject, aContext, anObjects);
+ }
}
// Verify the start shape
}
std::shared_ptr<GeomAPI_Trsf> aTrsf = aPlacementAlgo.transformation();
- // Applying transformation to each object.
int aResultIndex = 0;
std::string anError;
- std::list<ResultPtr>::iterator aContext = aContextes.begin();
- for(ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end();
- anObjectsIt++, aContext++) {
-
- // for part results just set transformation
- if (aContext->get() && (*aContext)->groupName() == ModelAPI_ResultPart::group()) {
- ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aContext);
- ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
- aResultPart->setTrsf(aContextRes, aTrsf);
- setResult(aResultPart, aResultIndex);
- } else {
- std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
- std::shared_ptr<GeomAlgoAPI_Transform> aTransformAlgo(new GeomAlgoAPI_Transform(aBaseShape,
- aTrsf));
-
- // Checking that the algorithm worked properly.
- if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aTransformAlgo, getKind(), anError)) {
- setError(anError);
- break;
- }
+ for (std::list<ResultPtr>::iterator aPRes = aParts.begin(); aPRes != aParts.end(); ++aPRes) {
+ // Applying transformation to each part.
+ ResultPartPtr anOrigin = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aPRes);
+ ResultPartPtr aResultPart = document()->copyPart(anOrigin, data(), aResultIndex);
+ aResultPart->setTrsf(aContextRes, aTrsf);
+ setResult(aResultPart, aResultIndex++);
+ }
+
+ // Collect transformations for each object.
+ std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList);
- //LoadNamingDS
- ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+ for(GeomAPI_ShapeHierarchy::iterator anObjectsIt = anObjects.begin();
+ anObjectsIt != anObjects.end(); anObjectsIt++) {
+ std::shared_ptr<GeomAPI_Shape> aBaseShape = *anObjectsIt;
+ std::shared_ptr<GeomAlgoAPI_Transform> aTransformAlgo(
+ new GeomAlgoAPI_Transform(aBaseShape, aTrsf));
- ListOfShape aShapes;
- aShapes.push_back(aBaseShape);
- FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, aShapes, ListOfShape(),
- aTransformAlgo, aTransformAlgo->shape(), "Placed");
- setResult(aResultBody, aResultIndex);
+ // Checking that the algorithm worked properly.
+ if (GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aTransformAlgo, getKind(), anError)) {
+ setError(anError);
+ break;
}
- aResultIndex++;
+
+ anObjects.markModified(aBaseShape, aTransformAlgo->shape());
+ aMakeShapeList->appendAlgo(aTransformAlgo);
+ }
+
+ // Build results of the operation.
+ const ListOfShape& anOriginalShapes = anObjects.objects();
+ ListOfShape aTopLevel;
+ anObjects.topLevelObjects(aTopLevel);
+ for (ListOfShape::iterator anIt = aTopLevel.begin(); anIt != aTopLevel.end(); ++anIt) {
+ //LoadNamingDS
+ ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
+ FeaturesPlugin_Tools::loadModifiedShapes(aResultBody, anOriginalShapes, ListOfShape(),
+ aMakeShapeList, *anIt, "Placed");
+ setResult(aResultBody, aResultIndex++);
}
// Remove the rest results if there were produced in the previous pass.
#include <Events_InfoMessage.h>
-#include "ModelAPI_AttributeSelectionList.h"
-#include "ModelAPI_ResultPart.h"
-#include "ModelAPI_ResultBody.h"
-#include "ModelAPI_Session.h"
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_ResultPart.h>
+#include <ModelAPI_ResultBody.h>
+#include <ModelAPI_Session.h>
+#include <ModelAPI_Tools.h>
bool FeaturesPlugin_ValidatorTransform::isValid(const AttributePtr& theAttribute,
const std::list<std::string>& theArguments,
DocumentPtr aDocument = theAttribute->owner()->document();
SessionPtr aMgr = ModelAPI_Session::get();
bool isPartSetDocument = aDocument == aMgr->moduleDocument();
+ bool isCheckCompsolid = !theAttribute->owner()->data()->version().empty();
std::string anErrorGroupName;
for(int i = 0; i < aCurSelList->size() && aValid; i++) {
}
if (isPartSetDocument) // PartSet document: Result Part is valid
aValid = aResult->groupName() == ModelAPI_ResultPart::group();
- else { // Part document: Result CompSolid is valid
+ else { // Part document: Result CompSolid is valid, but the solid in compsolid is forbidden
aValid = aResult->groupName() == ModelAPI_ResultBody::group();
- if (aValid) {
- ResultBodyPtr aComp = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aResult);
- aValid = aComp.get() != NULL;
+ if (aValid && isCheckCompsolid) {
+ ResultBodyPtr aComp = ModelAPI_Tools::bodyOwner(aResult);
+ if (aComp && aComp->shape()->shapeType() == GeomAPI_Shape::COMPSOLID) {
+ theError = "Selecting a part of compsolid is forbidden.";
+ return false;
+ }
}
}
if (!aValid)
<translation>Objects from the %1 group can be selected in the %2 document, but an objects from the %3 group is selected.</translation>
</message>
</context>
+ <context>
+ <name>Placement:placement_objects_list:FeaturesPlugin_ValidatorTransform</name>
+ <message>
+ <source>Selecting a part of compsolid is forbidden.</source>
+ <translation>Selecting a part of compsolid is forbidden.</translation>
+ </message>
+ </context>
<context>
<name>Placement:Model_FeatureValidator</name>
<message>
<translation>Les objets du groupe %1 peuvent être sélectionnés dans le document %2, mais un objet du groupe %3 est sélectionné.</translation>
</message>
</context>
+ <context>
+ <name>Placement:placement_objects_list:FeaturesPlugin_ValidatorTransform</name>
+ <message>
+ <source>Selecting a part of compsolid is forbidden.</source>
+ <translation>La sélection d'une partie de solide composite est interdite.</translation>
+ </message>
+ </context>
<context>
<name>Placement:Model_FeatureValidator</name>
<message>
--- /dev/null
+# Copyright (C) 2020 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
+#
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], model.selection("EDGE", "PartSet/OX"), 20, 2)
+LinearCopy_2 = model.addMultiTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_1_1")], model.selection("EDGE", "PartSet/OY"), 20, 2)
+Sketch_1 = model.addSketch(Part_1_doc, model.standardPlane("XOY"))
+SketchEllipse_1 = Sketch_1.addEllipse(11.18033988749894, -50, 22.36067977499789, -50, 10)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_1, SketchLine_2] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 20)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_3 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_3).coordinates(), SketchLine_3.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_3).startPoint(), SketchAPI_Point(SketchPoint_3).coordinates(), 50, True)
+SketchCircle_1 = Sketch_1.addCircle(41.18033988749897, -50, 5)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_1.result())
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchEllipse_1.majorAxisPositive(), SketchCircle_1.center(), 15, True)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 5)
+SketchMultiRotation_1 = Sketch_1.addRotation([SketchEllipse_1.result(), SketchCircle_1.results()[1]], SketchAPI_Point(SketchPoint_3).coordinates(), 360, 3, True)
+[SketchEllipse_2, SketchEllipse_3, SketchCircle_2, SketchCircle_3] = SketchMultiRotation_1.rotated()
+model.do()
+Sketch_1.changeFacesOrder([[SketchEllipse_1.result(), SketchEllipse_1.result(), SketchEllipse_2.result(), SketchEllipse_3.result()],
+ [SketchCircle_1.results()[1]],
+ [SketchEllipse_2.result(), SketchEllipse_2.result(), SketchEllipse_3.result(), SketchEllipse_1.result()],
+ [SketchEllipse_1.result(), SketchEllipse_3.result(), SketchEllipse_2.result()],
+ [SketchEllipse_3.result(), SketchEllipse_2.result(), SketchEllipse_1.result()],
+ [SketchEllipse_1.result(), SketchEllipse_2.result(), SketchEllipse_3.result()],
+ [SketchEllipse_1.result(), SketchEllipse_3.result(), SketchEllipse_2.result()],
+ [SketchEllipse_2.result(), SketchEllipse_3.result(), SketchEllipse_3.result(), SketchEllipse_1.result()],
+ [SketchCircle_2.results()[1]],
+ [SketchCircle_3.results()[1]]
+ ])
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0)
+Compound_1 = model.addCompound(Part_1_doc, [model.selection("SOLID", "Extrusion_1_2"), model.selection("SOLID", "Extrusion_1_3")])
+Compound_2_objects = [model.selection("COMPSOLID", "Extrusion_1_1"), model.selection("COMPOUND", "Compound_1_1"), model.selection("SOLID", "Extrusion_1_4")]
+Compound_2 = model.addCompound(Part_1_doc, Compound_2_objects)
+Placement_1 = model.addPlacement(Part_1_doc, [model.selection("SOLID", "LinearCopy_2_1_1_1")], model.selection("FACE", "LinearCopy_2_1_1_1/MF:Translated&Cylinder_1_1/Face_2"), model.selection("FACE", "Compound_2_1_2_1/Modified_Face&Extrusion_1_2/To_Face"), False, True)
+
+model.end()
+
+from GeomAPI import *
+
+model.testNbResults(Placement_1, 1)
+model.testNbSubResults(Placement_1, [0])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.FACE, [3])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.EDGE, [6])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.VERTEX, [12])
+model.testResultsVolumes(Placement_1, [785.39816339745])
+
+TOLERANCE = 1.e-7
+REFERENCE = GeomAPI_Pnt(41.18033988749897, -50, 15)
+midPoint = Placement_1.defaultResult().shape().middlePoint()
+assert(midPoint.distance(REFERENCE) < TOLERANCE)
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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
+#
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], model.selection("EDGE", "PartSet/OX"), 20, 2)
+LinearCopy_2 = model.addMultiTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_1_1")], model.selection("EDGE", "PartSet/OY"), 20, 2)
+Sketch_1 = model.addSketch(Part_1_doc, model.standardPlane("XOY"))
+SketchEllipse_1 = Sketch_1.addEllipse(11.18033988749894, -50, 22.36067977499789, -50, 10)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_1, SketchLine_2] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 20)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_3 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_3).coordinates(), SketchLine_3.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_3).startPoint(), SketchAPI_Point(SketchPoint_3).coordinates(), 50, True)
+SketchCircle_1 = Sketch_1.addCircle(41.18033988749897, -50, 5)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_1.result())
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchEllipse_1.majorAxisPositive(), SketchCircle_1.center(), 15, True)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 5)
+SketchMultiRotation_1 = Sketch_1.addRotation([SketchEllipse_1.result(), SketchCircle_1.results()[1]], SketchAPI_Point(SketchPoint_3).coordinates(), 360, 3, True)
+[SketchEllipse_2, SketchEllipse_3, SketchCircle_2, SketchCircle_3] = SketchMultiRotation_1.rotated()
+model.do()
+Sketch_1.changeFacesOrder([[SketchEllipse_1.result(), SketchEllipse_1.result(), SketchEllipse_2.result(), SketchEllipse_3.result()],
+ [SketchCircle_1.results()[1]],
+ [SketchEllipse_2.result(), SketchEllipse_2.result(), SketchEllipse_3.result(), SketchEllipse_1.result()],
+ [SketchEllipse_1.result(), SketchEllipse_3.result(), SketchEllipse_2.result()],
+ [SketchEllipse_3.result(), SketchEllipse_2.result(), SketchEllipse_1.result()],
+ [SketchEllipse_1.result(), SketchEllipse_2.result(), SketchEllipse_3.result()],
+ [SketchEllipse_1.result(), SketchEllipse_3.result(), SketchEllipse_2.result()],
+ [SketchEllipse_2.result(), SketchEllipse_3.result(), SketchEllipse_3.result(), SketchEllipse_1.result()],
+ [SketchCircle_2.results()[1]],
+ [SketchCircle_3.results()[1]]
+ ])
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0)
+Compound_1 = model.addCompound(Part_1_doc, [model.selection("SOLID", "Extrusion_1_2"), model.selection("SOLID", "Extrusion_1_3")])
+Compound_2_objects = [model.selection("COMPSOLID", "Extrusion_1_1"), model.selection("COMPOUND", "Compound_1_1"), model.selection("SOLID", "Extrusion_1_4")]
+Compound_2 = model.addCompound(Part_1_doc, Compound_2_objects)
+Placement_1 = model.addPlacement(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_2_1_1")], model.selection("FACE", "LinearCopy_2_1_1_1/MF:Translated&Cylinder_1_1/Face_2"), model.selection("FACE", "Compound_2_1_2_1/Modified_Face&Extrusion_1_2/To_Face"), False, True)
+
+model.end()
+
+from GeomAPI import *
+
+model.testNbResults(Placement_1, 1)
+model.testNbSubResults(Placement_1, [2])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.SOLID, [2])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.FACE, [6])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.EDGE, [12])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.VERTEX, [24])
+model.testResultsVolumes(Placement_1, [1570.7963267949])
+
+TOLERANCE = 1.e-7
+REFERENCE = GeomAPI_Pnt(31.18033988749897, -50, 15)
+midPoint = Placement_1.defaultResult().shape().middlePoint()
+assert(midPoint.distance(REFERENCE) < TOLERANCE)
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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
+#
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], model.selection("EDGE", "PartSet/OX"), 20, 2)
+LinearCopy_2 = model.addMultiTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_1_1")], model.selection("EDGE", "PartSet/OY"), 20, 2)
+Sketch_1 = model.addSketch(Part_1_doc, model.standardPlane("XOY"))
+SketchEllipse_1 = Sketch_1.addEllipse(11.18033988749894, -50, 22.36067977499789, -50, 10)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_1, SketchLine_2] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 20)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_3 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_3).coordinates(), SketchLine_3.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_3).startPoint(), SketchAPI_Point(SketchPoint_3).coordinates(), 50, True)
+SketchCircle_1 = Sketch_1.addCircle(41.18033988749897, -50, 5)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_1.result())
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchEllipse_1.majorAxisPositive(), SketchCircle_1.center(), 15, True)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 5)
+SketchMultiRotation_1 = Sketch_1.addRotation([SketchEllipse_1.result(), SketchCircle_1.results()[1]], SketchAPI_Point(SketchPoint_3).coordinates(), 360, 3, True)
+[SketchEllipse_2, SketchEllipse_3, SketchCircle_2, SketchCircle_3] = SketchMultiRotation_1.rotated()
+model.do()
+Sketch_1.changeFacesOrder([[SketchEllipse_1.result(), SketchEllipse_1.result(), SketchEllipse_2.result(), SketchEllipse_3.result()],
+ [SketchCircle_1.results()[1]],
+ [SketchEllipse_2.result(), SketchEllipse_2.result(), SketchEllipse_3.result(), SketchEllipse_1.result()],
+ [SketchEllipse_1.result(), SketchEllipse_3.result(), SketchEllipse_2.result()],
+ [SketchEllipse_3.result(), SketchEllipse_2.result(), SketchEllipse_1.result()],
+ [SketchEllipse_1.result(), SketchEllipse_2.result(), SketchEllipse_3.result()],
+ [SketchEllipse_1.result(), SketchEllipse_3.result(), SketchEllipse_2.result()],
+ [SketchEllipse_2.result(), SketchEllipse_3.result(), SketchEllipse_3.result(), SketchEllipse_1.result()],
+ [SketchCircle_2.results()[1]],
+ [SketchCircle_3.results()[1]]
+ ])
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0)
+Compound_1 = model.addCompound(Part_1_doc, [model.selection("SOLID", "Extrusion_1_2"), model.selection("SOLID", "Extrusion_1_3")])
+Compound_2_objects = [model.selection("COMPSOLID", "Extrusion_1_1"), model.selection("COMPOUND", "Compound_1_1"), model.selection("SOLID", "Extrusion_1_4")]
+Compound_2 = model.addCompound(Part_1_doc, Compound_2_objects)
+Placement_1 = model.addPlacement(Part_1_doc, [model.selection("SOLID", "Compound_2_1_1_5"), model.selection("SOLID", "Compound_2_1_2_1")], model.selection("FACE", "Compound_2_1_2_1/Modified_Face&Extrusion_1_2/From_Face"), model.selection("FACE", "LinearCopy_2_1_1_1/MF:Translated&Cylinder_1_1/Face_2"), False, False)
+
+model.end()
+
+from GeomAPI import *
+
+model.testNbResults(Placement_1, 2)
+model.testNbSubResults(Placement_1, [0, 0])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.SOLID, [1, 1])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.FACE, [5, 3])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.EDGE, [18, 6])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.VERTEX, [36, 12])
+model.testResultsVolumes(Placement_1, [542.746463956, 785.39816339745])
+
+TOLERANCE = 1.e-7
+REFERENCE = [GeomAPI_Pnt(0, -50, 15), GeomAPI_Pnt(41.18033988749897, -50, 15)]
+for res, ref in zip(Placement_1.results(), REFERENCE):
+ midPoint = res.resultSubShapePair()[0].shape().middlePoint()
+ assert(midPoint.distance(ref) < TOLERANCE)
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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
+#
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], model.selection("EDGE", "PartSet/OX"), 20, 2)
+LinearCopy_2 = model.addMultiTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_1_1")], model.selection("EDGE", "PartSet/OY"), 20, 2)
+Sketch_1 = model.addSketch(Part_1_doc, model.standardPlane("XOY"))
+SketchEllipse_1 = Sketch_1.addEllipse(11.18033988749894, -50, 22.36067977499789, -50, 10)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_1, SketchLine_2] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 20)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_3 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_3).coordinates(), SketchLine_3.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_3).startPoint(), SketchAPI_Point(SketchPoint_3).coordinates(), 50, True)
+SketchCircle_1 = Sketch_1.addCircle(41.18033988749897, -50, 5)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_1.result())
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchEllipse_1.majorAxisPositive(), SketchCircle_1.center(), 15, True)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 5)
+SketchMultiRotation_1 = Sketch_1.addRotation([SketchEllipse_1.result(), SketchCircle_1.results()[1]], SketchAPI_Point(SketchPoint_3).coordinates(), 360, 3, True)
+[SketchEllipse_2, SketchEllipse_3, SketchCircle_2, SketchCircle_3] = SketchMultiRotation_1.rotated()
+model.do()
+Sketch_1.changeFacesOrder([[SketchEllipse_1.result(), SketchEllipse_1.result(), SketchEllipse_2.result(), SketchEllipse_3.result()],
+ [SketchCircle_1.results()[1]],
+ [SketchEllipse_2.result(), SketchEllipse_2.result(), SketchEllipse_3.result(), SketchEllipse_1.result()],
+ [SketchEllipse_1.result(), SketchEllipse_3.result(), SketchEllipse_2.result()],
+ [SketchEllipse_3.result(), SketchEllipse_2.result(), SketchEllipse_1.result()],
+ [SketchEllipse_1.result(), SketchEllipse_2.result(), SketchEllipse_3.result()],
+ [SketchEllipse_1.result(), SketchEllipse_3.result(), SketchEllipse_2.result()],
+ [SketchEllipse_2.result(), SketchEllipse_3.result(), SketchEllipse_3.result(), SketchEllipse_1.result()],
+ [SketchCircle_2.results()[1]],
+ [SketchCircle_3.results()[1]]
+ ])
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0)
+Compound_1 = model.addCompound(Part_1_doc, [model.selection("SOLID", "Extrusion_1_2"), model.selection("SOLID", "Extrusion_1_3")])
+Compound_2_objects = [model.selection("COMPSOLID", "Extrusion_1_1"), model.selection("COMPOUND", "Compound_1_1"), model.selection("SOLID", "Extrusion_1_4")]
+Compound_2 = model.addCompound(Part_1_doc, Compound_2_objects)
+Placement_1 = model.addPlacement(Part_1_doc, [model.selection("COMPSOLID", "Compound_2_1_1"), model.selection("SOLID", "Compound_2_1_3")], model.selection("FACE", "Compound_2_1_2_1/Modified_Face&Extrusion_1_2/From_Face"), model.selection("FACE", "LinearCopy_2_1_1_1/MF:Translated&Cylinder_1_1/Face_2"), False, False)
+
+model.end()
+
+from GeomAPI import *
+
+model.testNbResults(Placement_1, 2)
+model.testNbSubResults(Placement_1, [7, 0])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.SOLID, [7, 1])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.FACE, [38, 3])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.EDGE, [144, 6])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.VERTEX, [288, 12])
+model.testResultsVolumes(Placement_1, [11963.80153655, 785.39816339745])
+
+TOLERANCE = 1.e-7
+REFERENCE = [GeomAPI_Pnt(4.5668653531, -50, 15), GeomAPI_Pnt(-20.59016994374951, -85.663220479, 15)]
+for res, ref in zip(Placement_1.results(), REFERENCE):
+ midPoint = res.resultSubShapePair()[0].shape().middlePoint()
+ assert(midPoint.distance(ref) < TOLERANCE)
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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
+#
+
+from salome.shaper import model
+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(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = 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", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")])
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+model.end()
+
+Z_SHIFT = 10
+TOLERANCE = 1.e-7
+
+model.begin()
+Placement_1 = model.addPlacement(Part_1_doc, [model.selection("VERTEX", "Vertex_1_1")], model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Bottom"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Top"), False, False)
+model.testNbResults(Placement_1, 1)
+model.testNbSubResults(Placement_1, [0])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.SOLID, [0])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.FACE, [0])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.EDGE, [0])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.VERTEX, [1])
+model.testResultsVolumes(Placement_1, [0])
+refPoint = Vertex_1.defaultResult().shape().middlePoint()
+refPoint.setZ(refPoint.z() + Z_SHIFT)
+midPoint = Placement_1.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Placement_2 = model.addPlacement(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Bottom"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Top"), False, False)
+model.testNbResults(Placement_2, 1)
+model.testNbSubResults(Placement_2, [0])
+model.testNbSubShapes(Placement_2, GeomAPI_Shape.SOLID, [0])
+model.testNbSubShapes(Placement_2, GeomAPI_Shape.FACE, [0])
+model.testNbSubShapes(Placement_2, GeomAPI_Shape.EDGE, [1])
+model.testNbSubShapes(Placement_2, GeomAPI_Shape.VERTEX, [2])
+model.testResultsVolumes(Placement_2, [0])
+refPoint = Edge_1.defaultResult().shape().middlePoint()
+refPoint.setZ(refPoint.z() + Z_SHIFT)
+midPoint = Placement_2.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Placement_3 = model.addPlacement(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Bottom"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Top"), False, False)
+model.testNbResults(Placement_3, 1)
+model.testNbSubResults(Placement_3, [0])
+model.testNbSubShapes(Placement_3, GeomAPI_Shape.SOLID, [0])
+model.testNbSubShapes(Placement_3, GeomAPI_Shape.FACE, [0])
+model.testNbSubShapes(Placement_3, GeomAPI_Shape.EDGE, [2])
+model.testNbSubShapes(Placement_3, GeomAPI_Shape.VERTEX, [4])
+model.testResultsVolumes(Placement_3, [0])
+refPoint = Wire_1.defaultResult().shape().middlePoint()
+refPoint.setZ(refPoint.z() + Z_SHIFT)
+midPoint = Placement_3.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Placement_4 = model.addPlacement(Part_1_doc, [model.selection("FACE", "Face_1_1")], model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Bottom"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Top"), False, False)
+model.testNbResults(Placement_4, 1)
+model.testNbSubResults(Placement_4, [0])
+model.testNbSubShapes(Placement_4, GeomAPI_Shape.SOLID, [0])
+model.testNbSubShapes(Placement_4, GeomAPI_Shape.FACE, [1])
+model.testNbSubShapes(Placement_4, GeomAPI_Shape.EDGE, [4])
+model.testNbSubShapes(Placement_4, GeomAPI_Shape.VERTEX, [8])
+model.testResultsVolumes(Placement_4, [109.154152964914914])
+refPoint = Face_1.defaultResult().shape().middlePoint()
+refPoint.setZ(refPoint.z() + Z_SHIFT)
+midPoint = Placement_4.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Placement_5 = model.addPlacement(Part_1_doc, [model.selection("SHELL", "Shell_1_1")], model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Bottom"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Top"), False, False)
+model.testNbResults(Placement_5, 1)
+model.testNbSubResults(Placement_5, [0])
+model.testNbSubShapes(Placement_5, GeomAPI_Shape.SOLID, [0])
+model.testNbSubShapes(Placement_5, GeomAPI_Shape.FACE, [2])
+model.testNbSubShapes(Placement_5, GeomAPI_Shape.EDGE, [8])
+model.testNbSubShapes(Placement_5, GeomAPI_Shape.VERTEX, [16])
+model.testResultsVolumes(Placement_5, [182.822012116])
+refPoint = Shell_1.defaultResult().shape().middlePoint()
+refPoint.setZ(refPoint.z() + Z_SHIFT)
+midPoint = Placement_5.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Placement_6 = model.addPlacement(Part_1_doc, [model.selection("SOLID", "Translation_1_1")], model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Bottom"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Top"), False, False)
+model.testNbResults(Placement_6, 1)
+model.testNbSubResults(Placement_6, [0])
+model.testNbSubShapes(Placement_6, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Placement_6, GeomAPI_Shape.FACE, [6])
+model.testNbSubShapes(Placement_6, GeomAPI_Shape.EDGE, [24])
+model.testNbSubShapes(Placement_6, GeomAPI_Shape.VERTEX, [48])
+model.testResultsVolumes(Placement_6, [1000])
+refPoint = Translation_1.defaultResult().shape().middlePoint()
+refPoint.setZ(refPoint.z() + Z_SHIFT)
+midPoint = Placement_6.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Placement_7 = model.addPlacement(Part_1_doc, [model.selection("COMPSOLID", "Partition_1_1")], model.selection("FACE", "AngularCopy_1_1_1/MF:Rotated&Box_3_1/Bottom"), model.selection("FACE", "AngularCopy_1_1_1/MF:Rotated&Box_3_1/Top"), False, False)
+model.testNbResults(Placement_7, 1)
+model.testNbSubResults(Placement_7, [3])
+model.testNbSubShapes(Placement_7, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Placement_7, GeomAPI_Shape.FACE, [17])
+model.testNbSubShapes(Placement_7, GeomAPI_Shape.EDGE, [66])
+model.testNbSubShapes(Placement_7, GeomAPI_Shape.VERTEX, [132])
+model.testResultsVolumes(Placement_7, [1589.0486226])
+refPoint = Partition_1.defaultResult().shape().middlePoint()
+refPoint.setZ(refPoint.z() + Z_SHIFT)
+midPoint = Placement_7.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Placement_8 = model.addPlacement(Part_1_doc, [model.selection("COMPOUND", "AngularCopy_1_1")],model.selection("FACE", "AngularCopy_1_1_1/MF:Rotated&Box_3_1/Bottom"), model.selection("FACE", "AngularCopy_1_1_1/MF:Rotated&Box_3_1/Top"), False, False)
+model.testNbResults(Placement_8, 1)
+model.testNbSubResults(Placement_8, [3])
+model.testNbSubShapes(Placement_8, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Placement_8, GeomAPI_Shape.FACE, [18])
+model.testNbSubShapes(Placement_8, GeomAPI_Shape.EDGE, [72])
+model.testNbSubShapes(Placement_8, GeomAPI_Shape.VERTEX, [144])
+model.testResultsVolumes(Placement_8, [3000])
+refPoint = AngularCopy_1.defaultResult().shape().middlePoint()
+refPoint.setZ(refPoint.z() + Z_SHIFT)
+midPoint = Placement_8.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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
+#
+
+from salome.shaper import model
+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(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = 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", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")])
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+Compound_1_objects = [model.selection("VERTEX", "Vertex_1_1"), model.selection("EDGE", "Edge_1_1"), model.selection("WIRE", "Wire_1_1"), model.selection("FACE", "Face_1_1"), model.selection("SHELL", "Shell_1_1"), model.selection("SOLID", "Translation_1_1"), model.selection("COMPSOLID", "Partition_1_1"), model.selection("COMPOUND", "AngularCopy_1_1")]
+Compound_1 = model.addCompound(Part_1_doc, Compound_1_objects)
+model.end()
+
+# collect reference data
+Z_SHIFT = 10
+REFERENCE = []
+TOLERANCE = 1.e-7
+for ind in range(0, Compound_1.result().numberOfSubs()):
+ p = Compound_1.result().subResult(ind).resultSubShapePair()[1].middlePoint()
+ p.setZ(p.z() + Z_SHIFT)
+ REFERENCE.append(p)
+
+index = 0
+
+model.begin()
+Placement_1 = model.addPlacement(Part_1_doc, [model.selection("VERTEX", "Compound_1_1_1")], model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Bottom"), model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Top"), False, False)
+model.testNbResults(Placement_1, 1)
+model.testNbSubResults(Placement_1, [0])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.SOLID, [0])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.FACE, [0])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.EDGE, [0])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.VERTEX, [1])
+model.testResultsVolumes(Placement_1, [0])
+midPoint = Placement_1.defaultResult().shape().middlePoint()
+assert(midPoint.distance(REFERENCE[index]) < TOLERANCE)
+index += 1
+
+Recover_1 = model.addRecover(Part_1_doc, Placement_1, [Compound_1.result()], True)
+Placement_2 = model.addPlacement(Part_1_doc, [model.selection("EDGE", "Recover_1_1_2")], model.selection("FACE", "Recover_1_1_6/Modified_Face&Box_1_1/Bottom"), model.selection("FACE", "Recover_1_1_6/Modified_Face&Box_1_1/Top"), False, False)
+model.testNbResults(Placement_2, 1)
+model.testNbSubResults(Placement_2, [0])
+model.testNbSubShapes(Placement_2, GeomAPI_Shape.SOLID, [0])
+model.testNbSubShapes(Placement_2, GeomAPI_Shape.FACE, [0])
+model.testNbSubShapes(Placement_2, GeomAPI_Shape.EDGE, [1])
+model.testNbSubShapes(Placement_2, GeomAPI_Shape.VERTEX, [2])
+model.testResultsVolumes(Placement_2, [0])
+midPoint = Placement_2.defaultResult().shape().middlePoint()
+assert(midPoint.distance(REFERENCE[index]) < TOLERANCE)
+index += 1
+
+Recover_2 = model.addRecover(Part_1_doc, Placement_2, [Recover_1.result()])
+Placement_3 = model.addPlacement(Part_1_doc, [model.selection("WIRE", "Recover_2_1_3")], model.selection("FACE", "Recover_2_1_6/Modified_Face&Box_1_1/Bottom"), model.selection("FACE", "Recover_2_1_6/Modified_Face&Box_1_1/Top"), False, False)
+model.testNbResults(Placement_3, 1)
+model.testNbSubResults(Placement_3, [0])
+model.testNbSubShapes(Placement_3, GeomAPI_Shape.SOLID, [0])
+model.testNbSubShapes(Placement_3, GeomAPI_Shape.FACE, [0])
+model.testNbSubShapes(Placement_3, GeomAPI_Shape.EDGE, [2])
+model.testNbSubShapes(Placement_3, GeomAPI_Shape.VERTEX, [4])
+model.testResultsVolumes(Placement_3, [0])
+midPoint = Placement_3.defaultResult().shape().middlePoint()
+assert(midPoint.distance(REFERENCE[index]) < TOLERANCE)
+index += 1
+
+Recover_3 = model.addRecover(Part_1_doc, Placement_3, [Recover_2.result()])
+Placement_4 = model.addPlacement(Part_1_doc, [model.selection("FACE", "Recover_3_1_4")], model.selection("FACE", "Recover_3_1_6/Modified_Face&Box_1_1/Bottom"), model.selection("FACE", "Recover_3_1_6/Modified_Face&Box_1_1/Top"), False, False)
+model.testNbResults(Placement_4, 1)
+model.testNbSubResults(Placement_4, [0])
+model.testNbSubShapes(Placement_4, GeomAPI_Shape.SOLID, [0])
+model.testNbSubShapes(Placement_4, GeomAPI_Shape.FACE, [1])
+model.testNbSubShapes(Placement_4, GeomAPI_Shape.EDGE, [4])
+model.testNbSubShapes(Placement_4, GeomAPI_Shape.VERTEX, [8])
+model.testResultsVolumes(Placement_4, [109.154152964914914])
+midPoint = Placement_4.defaultResult().shape().middlePoint()
+assert(midPoint.distance(REFERENCE[index]) < TOLERANCE)
+index += 1
+
+Recover_4 = model.addRecover(Part_1_doc, Placement_4, [Recover_3.result()])
+Placement_5 = model.addPlacement(Part_1_doc, [model.selection("SHELL", "Recover_4_1_5")], model.selection("FACE", "Recover_4_1_6/Modified_Face&Box_1_1/Bottom"), model.selection("FACE", "Recover_4_1_6/Modified_Face&Box_1_1/Top"), False, False)
+model.testNbResults(Placement_5, 1)
+model.testNbSubResults(Placement_5, [0])
+model.testNbSubShapes(Placement_5, GeomAPI_Shape.SOLID, [0])
+model.testNbSubShapes(Placement_5, GeomAPI_Shape.FACE, [2])
+model.testNbSubShapes(Placement_5, GeomAPI_Shape.EDGE, [8])
+model.testNbSubShapes(Placement_5, GeomAPI_Shape.VERTEX, [16])
+model.testResultsVolumes(Placement_5, [182.822012116])
+midPoint = Placement_5.defaultResult().shape().middlePoint()
+assert(midPoint.distance(REFERENCE[index]) < TOLERANCE)
+index += 1
+
+Recover_5 = model.addRecover(Part_1_doc, Placement_5, [Recover_4.result()])
+Placement_6 = model.addPlacement(Part_1_doc, [model.selection("SOLID", "Recover_5_1_6")], model.selection("FACE", "Recover_5_1_6/Modified_Face&Box_1_1/Bottom"), model.selection("FACE", "Recover_5_1_6/Modified_Face&Box_1_1/Top"), False, False)
+model.testNbResults(Placement_6, 1)
+model.testNbSubResults(Placement_6, [0])
+model.testNbSubShapes(Placement_6, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Placement_6, GeomAPI_Shape.FACE, [6])
+model.testNbSubShapes(Placement_6, GeomAPI_Shape.EDGE, [24])
+model.testNbSubShapes(Placement_6, GeomAPI_Shape.VERTEX, [48])
+model.testResultsVolumes(Placement_6, [1000])
+midPoint = Placement_6.defaultResult().shape().middlePoint()
+assert(midPoint.distance(REFERENCE[index]) < TOLERANCE)
+index += 1
+
+Recover_6 = model.addRecover(Part_1_doc, Placement_6, [Recover_5.result()])
+Placement_7 = model.addPlacement(Part_1_doc, [model.selection("COMPSOLID", "Recover_6_1_7")], model.selection("FACE", "Recover_6_1_6/Modified_Face&Box_1_1/Bottom"), model.selection("FACE", "Recover_6_1_6/Modified_Face&Box_1_1/Top"), False, False)
+model.testNbResults(Placement_7, 1)
+model.testNbSubResults(Placement_7, [3])
+model.testNbSubShapes(Placement_7, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Placement_7, GeomAPI_Shape.FACE, [17])
+model.testNbSubShapes(Placement_7, GeomAPI_Shape.EDGE, [66])
+model.testNbSubShapes(Placement_7, GeomAPI_Shape.VERTEX, [132])
+model.testResultsVolumes(Placement_7, [1589.0486226])
+midPoint = Placement_7.defaultResult().shape().middlePoint()
+assert(midPoint.distance(REFERENCE[index]) < TOLERANCE)
+index += 1
+
+Recover_7 = model.addRecover(Part_1_doc, Placement_7, [Recover_6.result()])
+Placement_8 = model.addPlacement(Part_1_doc, [model.selection("COMPOUND", "Recover_7_1_8")], model.selection("FACE", "Recover_7_1_6/Modified_Face&Box_1_1/Bottom"), model.selection("FACE", "Recover_7_1_6/Modified_Face&Box_1_1/Top"), False, False)
+model.testNbResults(Placement_8, 1)
+model.testNbSubResults(Placement_8, [3])
+model.testNbSubShapes(Placement_8, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Placement_8, GeomAPI_Shape.FACE, [18])
+model.testNbSubShapes(Placement_8, GeomAPI_Shape.EDGE, [72])
+model.testNbSubShapes(Placement_8, GeomAPI_Shape.VERTEX, [144])
+model.testResultsVolumes(Placement_8, [3000])
+midPoint = Placement_8.defaultResult().shape().middlePoint()
+assert(midPoint.distance(REFERENCE[index]) < TOLERANCE)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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
+#
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], model.selection("EDGE", "PartSet/OX"), 20, 2)
+LinearCopy_2 = model.addMultiTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_1_1")], model.selection("EDGE", "PartSet/OY"), 20, 2)
+Sketch_1 = model.addSketch(Part_1_doc, model.standardPlane("XOY"))
+SketchEllipse_1 = Sketch_1.addEllipse(11.18033988749894, -50, 22.36067977499789, -50, 10)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_1, SketchLine_2] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 20)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_3 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_3).coordinates(), SketchLine_3.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_3).startPoint(), SketchAPI_Point(SketchPoint_3).coordinates(), 50, True)
+SketchCircle_1 = Sketch_1.addCircle(41.18033988749897, -50, 5)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_1.result())
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchEllipse_1.majorAxisPositive(), SketchCircle_1.center(), 15, True)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 5)
+SketchMultiRotation_1 = Sketch_1.addRotation([SketchEllipse_1.result(), SketchCircle_1.results()[1]], SketchAPI_Point(SketchPoint_3).coordinates(), 360, 3, True)
+[SketchEllipse_2, SketchEllipse_3, SketchCircle_2, SketchCircle_3] = SketchMultiRotation_1.rotated()
+model.do()
+Sketch_1.changeFacesOrder([[SketchEllipse_1.result(), SketchEllipse_1.result(), SketchEllipse_2.result(), SketchEllipse_3.result()],
+ [SketchCircle_1.results()[1]],
+ [SketchEllipse_2.result(), SketchEllipse_2.result(), SketchEllipse_3.result(), SketchEllipse_1.result()],
+ [SketchEllipse_1.result(), SketchEllipse_3.result(), SketchEllipse_2.result()],
+ [SketchEllipse_3.result(), SketchEllipse_2.result(), SketchEllipse_1.result()],
+ [SketchEllipse_1.result(), SketchEllipse_2.result(), SketchEllipse_3.result()],
+ [SketchEllipse_1.result(), SketchEllipse_3.result(), SketchEllipse_2.result()],
+ [SketchEllipse_2.result(), SketchEllipse_3.result(), SketchEllipse_3.result(), SketchEllipse_1.result()],
+ [SketchCircle_2.results()[1]],
+ [SketchCircle_3.results()[1]]
+ ])
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0)
+Compound_1 = model.addCompound(Part_1_doc, [model.selection("SOLID", "Extrusion_1_2"), model.selection("SOLID", "Extrusion_1_3")])
+Compound_2_objects = [model.selection("COMPSOLID", "Extrusion_1_1"), model.selection("COMPOUND", "Compound_1_1"), model.selection("SOLID", "Extrusion_1_4")]
+Compound_2 = model.addCompound(Part_1_doc, Compound_2_objects)
+Placement_1 = model.addPlacement(Part_1_doc, [model.selection("SOLID", "LinearCopy_2_1_1_1")], model.selection("FACE", "LinearCopy_2_1_1_1/MF:Translated&Cylinder_1_1/Face_2"), model.selection("FACE", "Compound_2_1_2_1/Modified_Face&Extrusion_1_2/To_Face"), centering = True, keepSubResults = True)
+
+model.end()
+
+from GeomAPI import *
+
+model.testNbResults(Placement_1, 1)
+model.testNbSubResults(Placement_1, [2])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.SOLID, [4])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.FACE, [12])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.EDGE, [24])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.VERTEX, [48])
+model.testResultsVolumes(Placement_1, [3141.592653589793])
+
+TOLERANCE = 1.e-7
+REF_C = GeomAPI_Pnt(20.590169943749483, -15, 10)
+midPoint = Placement_1.defaultResult().shape().middlePoint()
+assert(midPoint.distance(REF_C) < TOLERANCE)
+
+REF_SUB = [GeomAPI_Pnt(30.590169943749483, -25, 10), GeomAPI_Pnt(10, 20, 5)]
+for ind in range(0, len(REF_SUB)):
+ midPoint = Placement_1.result().subResult(ind).resultSubShapePair()[0].shape().middlePoint()
+ assert(midPoint.distance(REF_SUB[ind]) < TOLERANCE)
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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
+#
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], model.selection("EDGE", "PartSet/OX"), 20, 2)
+LinearCopy_2 = model.addMultiTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_1_1")], model.selection("EDGE", "PartSet/OY"), 20, 2)
+Sketch_1 = model.addSketch(Part_1_doc, model.standardPlane("XOY"))
+SketchEllipse_1 = Sketch_1.addEllipse(11.18033988749894, -50, 22.36067977499789, -50, 10)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_1, SketchLine_2] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 20)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_3 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_3).coordinates(), SketchLine_3.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_3).startPoint(), SketchAPI_Point(SketchPoint_3).coordinates(), 50, True)
+SketchCircle_1 = Sketch_1.addCircle(41.18033988749897, -50, 5)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_1.result())
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchEllipse_1.majorAxisPositive(), SketchCircle_1.center(), 15, True)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 5)
+SketchMultiRotation_1 = Sketch_1.addRotation([SketchEllipse_1.result(), SketchCircle_1.results()[1]], SketchAPI_Point(SketchPoint_3).coordinates(), 360, 3, True)
+[SketchEllipse_2, SketchEllipse_3, SketchCircle_2, SketchCircle_3] = SketchMultiRotation_1.rotated()
+model.do()
+Sketch_1.changeFacesOrder([[SketchEllipse_1.result(), SketchEllipse_1.result(), SketchEllipse_2.result(), SketchEllipse_3.result()],
+ [SketchCircle_1.results()[1]],
+ [SketchEllipse_2.result(), SketchEllipse_2.result(), SketchEllipse_3.result(), SketchEllipse_1.result()],
+ [SketchEllipse_1.result(), SketchEllipse_3.result(), SketchEllipse_2.result()],
+ [SketchEllipse_3.result(), SketchEllipse_2.result(), SketchEllipse_1.result()],
+ [SketchEllipse_1.result(), SketchEllipse_2.result(), SketchEllipse_3.result()],
+ [SketchEllipse_1.result(), SketchEllipse_3.result(), SketchEllipse_2.result()],
+ [SketchEllipse_2.result(), SketchEllipse_3.result(), SketchEllipse_3.result(), SketchEllipse_1.result()],
+ [SketchCircle_2.results()[1]],
+ [SketchCircle_3.results()[1]]
+ ])
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0)
+Compound_1 = model.addCompound(Part_1_doc, [model.selection("SOLID", "Extrusion_1_2"), model.selection("SOLID", "Extrusion_1_3")])
+Compound_2_objects = [model.selection("COMPSOLID", "Extrusion_1_1"), model.selection("COMPOUND", "Compound_1_1"), model.selection("SOLID", "Extrusion_1_4")]
+Compound_2 = model.addCompound(Part_1_doc, Compound_2_objects)
+Placement_1 = model.addPlacement(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_2_1_1")], model.selection("FACE", "LinearCopy_2_1_1_1/MF:Translated&Cylinder_1_1/Face_2"), model.selection("FACE", "Compound_2_1_2_1/Modified_Face&Extrusion_1_2/To_Face"), reverse = False, centering = True, keepSubResults = True)
+
+model.end()
+
+from GeomAPI import *
+
+model.testNbResults(Placement_1, 1)
+model.testNbSubResults(Placement_1, [2])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.SOLID, [4])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.FACE, [12])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.EDGE, [24])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.VERTEX, [48])
+model.testResultsVolumes(Placement_1, [3141.592653589793])
+
+TOLERANCE = 1.e-7
+REF_C = GeomAPI_Pnt(20.590169943749483, -15, 10)
+midPoint = Placement_1.defaultResult().shape().middlePoint()
+assert(midPoint.distance(REF_C) < TOLERANCE)
+
+REF_SUB = [GeomAPI_Pnt(31.18033988749897, -50, 15), GeomAPI_Pnt(10, 20, 5)]
+for ind in range(0, len(REF_SUB)):
+ midPoint = Placement_1.result().subResult(ind).resultSubShapePair()[0].shape().middlePoint()
+ assert(midPoint.distance(REF_SUB[ind]) < TOLERANCE)
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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
+#
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], model.selection("EDGE", "PartSet/OX"), 20, 2)
+LinearCopy_2 = model.addMultiTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_1_1")], model.selection("EDGE", "PartSet/OY"), 20, 2)
+Sketch_1 = model.addSketch(Part_1_doc, model.standardPlane("XOY"))
+SketchEllipse_1 = Sketch_1.addEllipse(11.18033988749894, -50, 22.36067977499789, -50, 10)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_1, SketchLine_2] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 20)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_3 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_3).coordinates(), SketchLine_3.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_3).startPoint(), SketchAPI_Point(SketchPoint_3).coordinates(), 50, True)
+SketchCircle_1 = Sketch_1.addCircle(41.18033988749897, -50, 5)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_1.result())
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchEllipse_1.majorAxisPositive(), SketchCircle_1.center(), 15, True)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 5)
+SketchMultiRotation_1 = Sketch_1.addRotation([SketchEllipse_1.result(), SketchCircle_1.results()[1]], SketchAPI_Point(SketchPoint_3).coordinates(), 360, 3, True)
+[SketchEllipse_2, SketchEllipse_3, SketchCircle_2, SketchCircle_3] = SketchMultiRotation_1.rotated()
+model.do()
+Sketch_1.changeFacesOrder([[SketchEllipse_1.result(), SketchEllipse_1.result(), SketchEllipse_2.result(), SketchEllipse_3.result()],
+ [SketchCircle_1.results()[1]],
+ [SketchEllipse_2.result(), SketchEllipse_2.result(), SketchEllipse_3.result(), SketchEllipse_1.result()],
+ [SketchEllipse_1.result(), SketchEllipse_3.result(), SketchEllipse_2.result()],
+ [SketchEllipse_3.result(), SketchEllipse_2.result(), SketchEllipse_1.result()],
+ [SketchEllipse_1.result(), SketchEllipse_2.result(), SketchEllipse_3.result()],
+ [SketchEllipse_1.result(), SketchEllipse_3.result(), SketchEllipse_2.result()],
+ [SketchEllipse_2.result(), SketchEllipse_3.result(), SketchEllipse_3.result(), SketchEllipse_1.result()],
+ [SketchCircle_2.results()[1]],
+ [SketchCircle_3.results()[1]]
+ ])
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0)
+Compound_1 = model.addCompound(Part_1_doc, [model.selection("SOLID", "Extrusion_1_2"), model.selection("SOLID", "Extrusion_1_3")])
+Compound_2_objects = [model.selection("COMPSOLID", "Extrusion_1_1"), model.selection("COMPOUND", "Compound_1_1"), model.selection("SOLID", "Extrusion_1_4")]
+Compound_2 = model.addCompound(Part_1_doc, Compound_2_objects)
+Placement_1 = model.addPlacement(Part_1_doc, [model.selection("SOLID", "Compound_2_1_1_5"), model.selection("SOLID", "Compound_2_1_2_1")], model.selection("FACE", "Compound_2_1_2_1/Modified_Face&Extrusion_1_2/From_Face"), model.selection("FACE", "LinearCopy_2_1_1_1/MF:Translated&Cylinder_1_1/Face_2"), centering = False, keepSubResults = True)
+
+model.end()
+
+# selection of a compound part is prohibited
+assert(Placement_1.feature().error() != "")
+
+# change the placement arguments
+model.begin()
+Placement_1.setObjects([model.selection("COMPSOLID", "Compound_2_1_1"), model.selection("SOLID", "Compound_2_1_2_1")])
+model.end()
+
+from GeomAPI import *
+
+model.testNbResults(Placement_1, 1)
+model.testNbSubResults(Placement_1, [3])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.SOLID, [10])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.FACE, [47])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.EDGE, [162])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.VERTEX, [324])
+model.testResultsVolumes(Placement_1, [14319.996])
+
+TOLERANCE = 1.e-7
+REF_C = GeomAPI_Pnt(10.29508497187, -50, 10)
+midPoint = Placement_1.defaultResult().shape().middlePoint()
+assert(midPoint.distance(REF_C) < TOLERANCE)
+
+REF_SUB = [GeomAPI_Pnt(4.566865353179923, -50, 15),
+ GeomAPI_Pnt(10.29508497, -32.16838976, 10),
+ GeomAPI_Pnt(-20.59016994, -85.663220479, 5)]
+for ind in range(0, len(REF_SUB)):
+ midPoint = Placement_1.result().subResult(ind).resultSubShapePair()[0].shape().middlePoint()
+ assert(midPoint.distance(REF_SUB[ind]) < TOLERANCE)
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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
+#
+
+from SketchAPI import *
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Cylinder_1 = model.addCylinder(Part_1_doc, model.selection("VERTEX", "PartSet/Origin"), model.selection("EDGE", "PartSet/OZ"), 5, 10)
+LinearCopy_1 = model.addMultiTranslation(Part_1_doc, [model.selection("SOLID", "Cylinder_1_1")], model.selection("EDGE", "PartSet/OX"), 20, 2)
+LinearCopy_2 = model.addMultiTranslation(Part_1_doc, [model.selection("COMPOUND", "LinearCopy_1_1")], model.selection("EDGE", "PartSet/OY"), 20, 2)
+Sketch_1 = model.addSketch(Part_1_doc, model.standardPlane("XOY"))
+SketchEllipse_1 = Sketch_1.addEllipse(11.18033988749894, -50, 22.36067977499789, -50, 10)
+[SketchPoint_1, SketchPoint_2, SketchPoint_3, SketchPoint_4, SketchPoint_5, SketchPoint_6, SketchPoint_7, SketchLine_1, SketchLine_2] = SketchEllipse_1.construction(center = "aux", firstFocus = "aux", secondFocus = "aux", majorAxisStart = "aux", majorAxisEnd = "aux", minorAxisStart = "aux", minorAxisEnd = "aux", majorAxis = "aux", minorAxis = "aux")
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_1.result(), 30)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_2.result(), 20)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("EDGE", "PartSet/OY"), False)
+SketchLine_3 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchAPI_Point(SketchPoint_3).coordinates(), SketchLine_3.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchAPI_Line(SketchLine_3).startPoint(), SketchAPI_Point(SketchPoint_3).coordinates(), 50, True)
+SketchCircle_1 = Sketch_1.addCircle(41.18033988749897, -50, 5)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_1.result())
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchEllipse_1.majorAxisPositive(), SketchCircle_1.center(), 15, True)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 5)
+SketchMultiRotation_1 = Sketch_1.addRotation([SketchEllipse_1.result(), SketchCircle_1.results()[1]], SketchAPI_Point(SketchPoint_3).coordinates(), 360, 3, True)
+[SketchEllipse_2, SketchEllipse_3, SketchCircle_2, SketchCircle_3] = SketchMultiRotation_1.rotated()
+model.do()
+Sketch_1.changeFacesOrder([[SketchEllipse_1.result(), SketchEllipse_1.result(), SketchEllipse_2.result(), SketchEllipse_3.result()],
+ [SketchCircle_1.results()[1]],
+ [SketchEllipse_2.result(), SketchEllipse_2.result(), SketchEllipse_3.result(), SketchEllipse_1.result()],
+ [SketchEllipse_1.result(), SketchEllipse_3.result(), SketchEllipse_2.result()],
+ [SketchEllipse_3.result(), SketchEllipse_2.result(), SketchEllipse_1.result()],
+ [SketchEllipse_1.result(), SketchEllipse_2.result(), SketchEllipse_3.result()],
+ [SketchEllipse_1.result(), SketchEllipse_3.result(), SketchEllipse_2.result()],
+ [SketchEllipse_2.result(), SketchEllipse_3.result(), SketchEllipse_3.result(), SketchEllipse_1.result()],
+ [SketchCircle_2.results()[1]],
+ [SketchCircle_3.results()[1]]
+ ])
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0)
+Compound_1 = model.addCompound(Part_1_doc, [model.selection("SOLID", "Extrusion_1_2"), model.selection("SOLID", "Extrusion_1_3")])
+Compound_2_objects = [model.selection("COMPSOLID", "Extrusion_1_1"), model.selection("COMPOUND", "Compound_1_1"), model.selection("SOLID", "Extrusion_1_4")]
+Compound_2 = model.addCompound(Part_1_doc, Compound_2_objects)
+Placement_1 = model.addPlacement(Part_1_doc, [model.selection("COMPSOLID", "Compound_2_1_1"), model.selection("SOLID", "Compound_2_1_3")], model.selection("FACE", "Compound_2_1_2_1/Modified_Face&Extrusion_1_2/From_Face"), model.selection("FACE", "LinearCopy_2_1_1_1/MF:Translated&Cylinder_1_1/Face_2"), keepSubResults = True)
+
+model.end()
+
+from GeomAPI import *
+
+model.testNbResults(Placement_1, 1)
+model.testNbSubResults(Placement_1, [3])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.SOLID, [10])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.FACE, [47])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.EDGE, [162])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.VERTEX, [324])
+model.testResultsVolumes(Placement_1, [14319.996])
+
+TOLERANCE = 1.e-7
+REF_C = GeomAPI_Pnt(10.29508497187, -50, 10)
+midPoint = Placement_1.defaultResult().shape().middlePoint()
+assert(midPoint.distance(REF_C) < TOLERANCE)
+
+REF_SUB = [GeomAPI_Pnt(4.566865353179923, -50, 15),
+ GeomAPI_Pnt(10.29508497, -32.16838976, 5),
+ GeomAPI_Pnt(-20.59016994, -85.663220479, 15)]
+for ind in range(0, len(REF_SUB)):
+ midPoint = Placement_1.result().subResult(ind).resultSubShapePair()[0].shape().middlePoint()
+ assert(midPoint.distance(REF_SUB[ind]) < TOLERANCE)
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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
+#
+
+from salome.shaper import model
+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(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = 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", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")], keepSubResults = True)
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+model.end()
+
+Z_SHIFT = 10
+TOLERANCE = 1.e-7
+
+model.begin()
+Placement_1 = model.addPlacement(Part_1_doc, [model.selection("VERTEX", "Vertex_1_1")], model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Bottom"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Top"), keepSubResults = True)
+model.testNbResults(Placement_1, 1)
+model.testNbSubResults(Placement_1, [0])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.SOLID, [0])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.FACE, [0])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.EDGE, [0])
+model.testNbSubShapes(Placement_1, GeomAPI_Shape.VERTEX, [1])
+model.testResultsVolumes(Placement_1, [0])
+refPoint = Vertex_1.defaultResult().shape().middlePoint()
+refPoint.setZ(refPoint.z() + Z_SHIFT)
+midPoint = Placement_1.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Placement_2 = model.addPlacement(Part_1_doc, [model.selection("EDGE", "Edge_1_1")], model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Bottom"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Top"), keepSubResults = True)
+model.testNbResults(Placement_2, 1)
+model.testNbSubResults(Placement_2, [0])
+model.testNbSubShapes(Placement_2, GeomAPI_Shape.SOLID, [0])
+model.testNbSubShapes(Placement_2, GeomAPI_Shape.FACE, [0])
+model.testNbSubShapes(Placement_2, GeomAPI_Shape.EDGE, [1])
+model.testNbSubShapes(Placement_2, GeomAPI_Shape.VERTEX, [2])
+model.testResultsVolumes(Placement_2, [0])
+refPoint = Edge_1.defaultResult().shape().middlePoint()
+refPoint.setZ(refPoint.z() + Z_SHIFT)
+midPoint = Placement_2.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Placement_3 = model.addPlacement(Part_1_doc, [model.selection("WIRE", "Wire_1_1")], model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Bottom"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Top"), keepSubResults = True)
+model.testNbResults(Placement_3, 1)
+model.testNbSubResults(Placement_3, [0])
+model.testNbSubShapes(Placement_3, GeomAPI_Shape.SOLID, [0])
+model.testNbSubShapes(Placement_3, GeomAPI_Shape.FACE, [0])
+model.testNbSubShapes(Placement_3, GeomAPI_Shape.EDGE, [2])
+model.testNbSubShapes(Placement_3, GeomAPI_Shape.VERTEX, [4])
+model.testResultsVolumes(Placement_3, [0])
+refPoint = Wire_1.defaultResult().shape().middlePoint()
+refPoint.setZ(refPoint.z() + Z_SHIFT)
+midPoint = Placement_3.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Placement_4 = model.addPlacement(Part_1_doc, [model.selection("FACE", "Face_1_1")], model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Bottom"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Top"), keepSubResults = True)
+model.testNbResults(Placement_4, 1)
+model.testNbSubResults(Placement_4, [0])
+model.testNbSubShapes(Placement_4, GeomAPI_Shape.SOLID, [0])
+model.testNbSubShapes(Placement_4, GeomAPI_Shape.FACE, [1])
+model.testNbSubShapes(Placement_4, GeomAPI_Shape.EDGE, [4])
+model.testNbSubShapes(Placement_4, GeomAPI_Shape.VERTEX, [8])
+model.testResultsVolumes(Placement_4, [109.154152964914914])
+refPoint = Face_1.defaultResult().shape().middlePoint()
+refPoint.setZ(refPoint.z() + Z_SHIFT)
+midPoint = Placement_4.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Placement_5 = model.addPlacement(Part_1_doc, [model.selection("SHELL", "Shell_1_1")], model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Bottom"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Top"), keepSubResults = True)
+model.testNbResults(Placement_5, 1)
+model.testNbSubResults(Placement_5, [0])
+model.testNbSubShapes(Placement_5, GeomAPI_Shape.SOLID, [0])
+model.testNbSubShapes(Placement_5, GeomAPI_Shape.FACE, [2])
+model.testNbSubShapes(Placement_5, GeomAPI_Shape.EDGE, [8])
+model.testNbSubShapes(Placement_5, GeomAPI_Shape.VERTEX, [16])
+model.testResultsVolumes(Placement_5, [182.822012116])
+refPoint = Shell_1.defaultResult().shape().middlePoint()
+refPoint.setZ(refPoint.z() + Z_SHIFT)
+midPoint = Placement_5.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Placement_6 = model.addPlacement(Part_1_doc, [model.selection("SOLID", "Translation_1_1")], model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Bottom"), model.selection("FACE", "Translation_1_1/MF:Translated&Box_1_1/Top"), keepSubResults = True)
+model.testNbResults(Placement_6, 1)
+model.testNbSubResults(Placement_6, [0])
+model.testNbSubShapes(Placement_6, GeomAPI_Shape.SOLID, [1])
+model.testNbSubShapes(Placement_6, GeomAPI_Shape.FACE, [6])
+model.testNbSubShapes(Placement_6, GeomAPI_Shape.EDGE, [24])
+model.testNbSubShapes(Placement_6, GeomAPI_Shape.VERTEX, [48])
+model.testResultsVolumes(Placement_6, [1000])
+refPoint = Translation_1.defaultResult().shape().middlePoint()
+refPoint.setZ(refPoint.z() + Z_SHIFT)
+midPoint = Placement_6.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Placement_7 = model.addPlacement(Part_1_doc, [model.selection("COMPSOLID", "Partition_1_1")], model.selection("FACE", "AngularCopy_1_1_1/MF:Rotated&Box_3_1/Bottom"), model.selection("FACE", "AngularCopy_1_1_1/MF:Rotated&Box_3_1/Top"), keepSubResults = True)
+model.testNbResults(Placement_7, 1)
+model.testNbSubResults(Placement_7, [3])
+model.testNbSubShapes(Placement_7, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Placement_7, GeomAPI_Shape.FACE, [17])
+model.testNbSubShapes(Placement_7, GeomAPI_Shape.EDGE, [66])
+model.testNbSubShapes(Placement_7, GeomAPI_Shape.VERTEX, [132])
+model.testResultsVolumes(Placement_7, [1589.0486226])
+refPoint = Partition_1.defaultResult().shape().middlePoint()
+refPoint.setZ(refPoint.z() + Z_SHIFT)
+midPoint = Placement_7.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+Placement_8 = model.addPlacement(Part_1_doc, [model.selection("COMPOUND", "AngularCopy_1_1")],model.selection("FACE", "AngularCopy_1_1_1/MF:Rotated&Box_3_1/Bottom"), model.selection("FACE", "AngularCopy_1_1_1/MF:Rotated&Box_3_1/Top"), keepSubResults = True)
+model.testNbResults(Placement_8, 1)
+model.testNbSubResults(Placement_8, [3])
+model.testNbSubShapes(Placement_8, GeomAPI_Shape.SOLID, [3])
+model.testNbSubShapes(Placement_8, GeomAPI_Shape.FACE, [18])
+model.testNbSubShapes(Placement_8, GeomAPI_Shape.EDGE, [72])
+model.testNbSubShapes(Placement_8, GeomAPI_Shape.VERTEX, [144])
+model.testResultsVolumes(Placement_8, [3000])
+refPoint = AngularCopy_1.defaultResult().shape().middlePoint()
+refPoint.setZ(refPoint.z() + Z_SHIFT)
+midPoint = Placement_8.defaultResult().shape().middlePoint()
+assert(midPoint.distance(refPoint) < TOLERANCE)
+
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+# Copyright (C) 2020 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
+#
+
+from salome.shaper import model
+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(44.29784155360136, 17.09942588468031)
+SketchArc_1 = Sketch_1.addArc(44.29784155360136, 17.09942588468031, 47.1668727423061, 12.27945348765633, 45.38299232715926, 22.60269052200972, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchArc_1.center())
+SketchLine_1 = Sketch_1.addLine(42.5764228403785, 22.14892077680068, 39.70739165167375, 16.41085839939117)
+SketchLine_2 = Sketch_1.addLine(39.70739165167375, 16.41085839939117, 43.03546783057126, 12.04993099255995)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(28.57555063949931, 12.96802097294547, 15.72229091410204, 12.96802097294547)
+SketchLine_4 = Sketch_1.addLine(15.72229091410204, 12.96802097294547, 15.72229091410204, 21.46035329151154)
+SketchLine_5 = Sketch_1.addLine(15.72229091410204, 21.46035329151154, 28.57555063949931, 21.46035329151154)
+SketchLine_6 = Sketch_1.addLine(28.57555063949931, 21.46035329151154, 28.57555063949931, 12.96802097294547)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchLine_7 = Sketch_1.addLine(-10.67279602198167, 14.78814178154371, -28.34602814440294, 14.78814178154371)
+SketchLine_8 = Sketch_1.addLine(-28.34602814440294, 14.78814178154371, -28.34602814440294, 25.13271321305362)
+SketchLine_9 = Sketch_1.addLine(-28.34602814440294, 25.13271321305362, -10.67279602198167, 25.13271321305362)
+SketchLine_10 = Sketch_1.addLine(-10.67279602198167, 25.13271321305362, -10.67279602198167, 14.78814178154371)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_8.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchLine_11 = Sketch_1.addLine(-17.67323212242127, 25.13271321305362, -21.80463703415611, 14.78814178154371)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_11.startPoint(), SketchLine_9.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_7.result())
+model.do()
+Vertex_1 = model.addVertex(Part_1_doc, [model.selection("VERTEX", "Sketch_1/SketchArc_1")], False)
+Edge_1 = model.addEdge(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchArc_1_2")], False)
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_1/SketchLine_1"), model.selection("EDGE", "Sketch_1/SketchLine_2")], False)
+Face_1 = model.addFace(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_6r-SketchLine_5r-SketchLine_4r-SketchLine_3r")])
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_10r-SketchLine_9r-SketchLine_11f-SketchLine_7r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11r-SketchLine_9r-SketchLine_8r-SketchLine_7r")])
+Box_1 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_1_1")], model.selection("EDGE", "PartSet/OX"), 50)
+Box_2 = 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", "Box_2_1"), model.selection("SOLID", "Cylinder_1_1")], keepSubResults = True)
+Box_3 = model.addBox(Part_1_doc, 10, 10, 10)
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_3_1")], model.selection("EDGE", "PartSet/OY"), 50)
+AngularCopy_1 = model.addMultiRotation(Part_1_doc, [model.selection("SOLID", "Translation_2_1")], model.selection("EDGE", "PartSet/OZ"), 30, 3)
+Compound_1_objects = [model.selection("VERTEX", "Vertex_1_1"), model.selection("EDGE", "Edge_1_1"), model.selection("WIRE", "Wire_1_1"), model.selection("FACE", "Face_1_1"), model.selection("SHELL", "Shell_1_1"), model.selection("SOLID", "Translation_1_1"), model.selection("COMPSOLID", "Partition_1_1"), model.selection("COMPOUND", "AngularCopy_1_1")]
+Compound_1 = model.addCompound(Part_1_doc, Compound_1_objects)
+model.end()
+
+# collect reference data
+Z_SHIFT = 10
+REFERENCE = []
+TOLERANCE = 1.e-7
+for ind in range(0, Compound_1.result().numberOfSubs()):
+ p = Compound_1.result().subResult(ind).resultSubShapePair()[1].middlePoint()
+ REFERENCE.append(p)
+
+def assertResult(thePlacement, theNbMoved):
+ model.testNbResults(thePlacement, 1)
+ model.testNbSubResults(thePlacement, [8])
+ model.testNbSubShapes(thePlacement, GeomAPI_Shape.SOLID, [7])
+ model.testNbSubShapes(thePlacement, GeomAPI_Shape.FACE, [44])
+ model.testNbSubShapes(thePlacement, GeomAPI_Shape.EDGE, [177])
+ model.testNbSubShapes(thePlacement, GeomAPI_Shape.VERTEX, [355])
+ model.testResultsVolumes(thePlacement, [5589.0486226])
+
+ for ind in range(0, thePlacement.result().numberOfSubs()):
+ ref = GeomAPI_Pnt(REFERENCE[ind].x(), REFERENCE[ind].y(), REFERENCE[ind].z())
+ if ind < theNbMoved:
+ ref.setZ(ref.z() + Z_SHIFT)
+ midPoint = thePlacement.result().subResult(ind).resultSubShapePair()[0].shape().middlePoint()
+ assert(midPoint.distance(ref) < TOLERANCE), "Sub-result {}; actual ({}, {}, {}) != expected ({}, {}, {})".format(ind, midPoint.x(), midPoint.y(), midPoint.z(), ref.x(), ref.y(), ref.z())
+
+
+model.begin()
+Placement_1 = model.addPlacement(Part_1_doc, [model.selection("VERTEX", "Compound_1_1_1")], model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Bottom"), model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Top"), keepSubResults = True)
+assertResult(Placement_1, 1)
+
+Placement_2 = model.addPlacement(Part_1_doc, [model.selection("EDGE", "Placement_1_1_2")], model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Bottom"), model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Top"), keepSubResults = True)
+assertResult(Placement_2, 2)
+
+Placement_3 = model.addPlacement(Part_1_doc, [model.selection("WIRE", "Placement_2_1_3")], model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Bottom"), model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Top"), keepSubResults = True)
+assertResult(Placement_3, 3)
+
+Placement_4 = model.addPlacement(Part_1_doc, [model.selection("FACE", "Placement_3_1_4")], model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Bottom"), model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Top"), keepSubResults = True)
+assertResult(Placement_4, 4)
+
+Placement_5 = model.addPlacement(Part_1_doc, [model.selection("SHELL", "Placement_4_1_5")], model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Bottom"), model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Top"), keepSubResults = True)
+assertResult(Placement_5, 5)
+
+Placement_6 = model.addPlacement(Part_1_doc, [model.selection("SOLID", "Placement_5_1_6")], model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Bottom"), model.selection("FACE", "Compound_1_1_6/Modified_Face&Box_1_1/Top"), keepSubResults = True)
+assertResult(Placement_6, 6)
+
+Placement_7 = model.addPlacement(Part_1_doc, [model.selection("COMPSOLID", "Placement_6_1_7")], model.selection("FACE", "Placement_6_1_6/MF:Placed&Box_1_1/Bottom"), model.selection("FACE", "Placement_6_1_6/MF:Placed&Box_1_1/Top"), keepSubResults = True)
+assertResult(Placement_7, 7)
+
+Placement_8 = model.addPlacement(Part_1_doc, [model.selection("COMPOUND", "Placement_7_1_8")], model.selection("FACE", "Placement_6_1_6/MF:Placed&Box_1_1/Bottom"), model.selection("FACE", "Placement_6_1_6/MF:Placed&Box_1_1/Top"), keepSubResults = True)
+assertResult(Placement_8, 8)
+
+model.end()
+
+assert(model.checkPythonDump())
GeomShapePtr GeomAPI_ShapeHierarchy::parent(const GeomShapePtr& theShape,
bool theMarkProcessed)
{
- MapShapeToParent::const_iterator aFound = myParent.find(theShape);
+ MapShapeToShape::const_iterator aFound = myParent.find(theShape);
GeomShapePtr aParent;
if (aFound != myParent.end()) {
aParent = aFound->second;
if (theMarkProcessed) {
// mark the parent and all its subs as processed by Boolean algorithm
markProcessed(aParent);
- const ListOfShape& aSubs = mySubshapes[myParentIndices[aParent]].second;
- for (ListOfShape::const_iterator anIt = aSubs.begin(); anIt != aSubs.end(); ++anIt)
- markProcessed(*anIt);
}
}
return aParent;
void GeomAPI_ShapeHierarchy::markProcessed(const GeomShapePtr& theShape)
{
myProcessedObjects.insert(theShape);
+ // mark sub-shapes of the compound as processed too
+ MapShapeToIndex::iterator aFoundInd = myParentIndices.find(theShape);
+ if (aFoundInd != myParentIndices.end()) {
+ const ListOfShape& aSubs = mySubshapes[aFoundInd->second].second;
+ for (ListOfShape::const_iterator anIt = aSubs.begin(); anIt != aSubs.end(); ++anIt)
+ markProcessed(*anIt);
+ }
}
void GeomAPI_ShapeHierarchy::markProcessed(const ListOfShape& theShapes)
markProcessed(*anIt);
}
+void GeomAPI_ShapeHierarchy::markModified(const GeomShapePtr& theSource,
+ const GeomShapePtr& theModified)
+{
+ myModifiedObjects[theSource] = theModified;
+}
+
void GeomAPI_ShapeHierarchy::objectsByType(
ListOfShape& theShapesByType,
ListOfShape& theOtherShapes,
return myObjects.empty();
}
+void GeomAPI_ShapeHierarchy::topLevelObjects(ListOfShape& theDestination) const
+{
+ GeomAPI_ShapeHierarchy* aThis = const_cast<GeomAPI_ShapeHierarchy*>(this);
+ SetOfShape aProcessed = myProcessedObjects;
+ aThis->myProcessedObjects.clear();
+
+ iterator anIt = aThis->begin(), aEnd = aThis->end();
+ for (; anIt != aEnd; ++anIt) {
+ GeomShapePtr aShape = *anIt;
+ GeomShapePtr aParent = aThis->parent(aShape);
+ GeomShapePtr aRoot = aParent;
+ while (aParent) {
+ aParent = aThis->parent(aRoot);
+ if (aParent)
+ aRoot = aParent;
+ }
+
+ if (aRoot) {
+ // compose a compund with the modified shapes
+ aShape = collectSubs(aRoot, SetOfShape(), myModifiedObjects);
+ }
+ else {
+ // check the current shape was modified
+ MapShapeToShape::const_iterator aFound = myModifiedObjects.find(aShape);
+ if (aFound != myModifiedObjects.end())
+ aShape = aFound->second;
+ }
+
+ theDestination.push_back(aShape);
+ }
+
+ aThis->myProcessedObjects = aProcessed;
+}
+
void GeomAPI_ShapeHierarchy::compoundsOfUnusedObjects(
ListOfShape& theDestination) const
{
for (std::vector<ShapeAndSubshapes>::const_iterator anIt = mySubshapes.begin();
anIt != mySubshapes.end(); ++anIt) {
- MapShapeToParent::const_iterator aParent = myParent.find(anIt->first);
+ MapShapeToShape::const_iterator aParent = myParent.find(anIt->first);
if ((aParent == myParent.end() || !aParent->second) &&
anIt->first->shapeType() == GeomAPI_Shape::COMPOUND) {
// this is a top-level compound
- GeomShapePtr aCompound = collectUnusedSubs(anIt->first, aUsedObjects);
+ GeomShapePtr aCompound = collectSubs(anIt->first, aUsedObjects);
// add to destination non-empty compounds only
if (aCompound)
theDestination.push_back(aCompound);
}
}
-static void addSubShape(GeomShapePtr theTarget, GeomShapePtr theSub)
+static void addSubShape(GeomShapePtr theTarget, GeomShapePtr theSub,
+ const std::map<GeomShapePtr, GeomShapePtr, GeomAPI_Shape::Comparator>& theModified)
{
if (!theTarget.get() || !theSub.get())
return;
TopoDS_Shape* aShape = theTarget->implPtr<TopoDS_Shape>();
- const TopoDS_Shape& aShapeToAdd = theSub->impl<TopoDS_Shape>();
+
+ std::map<GeomShapePtr, GeomShapePtr, GeomAPI_Shape::Comparator>::const_iterator
+ aFound = theModified.find(theSub);
+ const TopoDS_Shape& aShapeToAdd =
+ (aFound == theModified.end() ? theSub : aFound->second)->impl<TopoDS_Shape>();
static BRep_Builder aBuilder;
aBuilder.Add(*aShape, aShapeToAdd);
}
-GeomShapePtr GeomAPI_ShapeHierarchy::collectUnusedSubs(
+GeomShapePtr GeomAPI_ShapeHierarchy::collectSubs(
GeomShapePtr theTopLevelCompound,
- const SetOfShape& theUsed) const
+ const SetOfShape& theExcluded,
+ const MapShapeToShape& theModified) const
{
GeomShapePtr aResult = theTopLevelCompound->emptyCopied();
bool isResultEmpty = true;
for (GeomAPI_ShapeIterator aSub(theTopLevelCompound); aSub.more(); aSub.next()) {
GeomShapePtr aCurrent = aSub.current();
- if (theUsed.find(aCurrent) != theUsed.end())
+ if (theExcluded.find(aCurrent) != theExcluded.end())
continue; // already used
MapShapeToIndex::const_iterator aFoundIndex = myParentIndices.find(aCurrent);
// check compsolid is fully unused in the Boolean operation
if (aCurrent->shapeType() == GeomAPI_Shape::COMPSOLID) {
for (GeomAPI_ShapeIterator anIt(aCurrent); isAddShape && anIt.more(); anIt.next())
- isAddShape = theUsed.find(anIt.current()) == theUsed.end();
+ isAddShape = theExcluded.find(anIt.current()) == theExcluded.end();
}
if (isAddShape) { // low-level shape, add it
- addSubShape(aResult, aCurrent);
+ addSubShape(aResult, aCurrent, theModified);
isResultEmpty = false;
}
} else {
- GeomShapePtr aCompound = collectUnusedSubs(aCurrent, theUsed);
+ GeomShapePtr aCompound = collectSubs(aCurrent, theExcluded, theModified);
if (aCompound) {
- addSubShape(aResult, aCompound);
+ addSubShape(aResult, aCompound, theModified);
isResultEmpty = false;
}
}
class GeomAPI_ShapeHierarchy
{
typedef std::pair<GeomShapePtr, ListOfShape> ShapeAndSubshapes;
- typedef std::map<GeomShapePtr, GeomShapePtr, GeomAPI_Shape::Comparator> MapShapeToParent;
+ typedef std::map<GeomShapePtr, GeomShapePtr, GeomAPI_Shape::Comparator> MapShapeToShape;
typedef std::map<GeomShapePtr, size_t, GeomAPI_Shape::Comparator> MapShapeToIndex;
typedef std::set<GeomShapePtr, GeomAPI_Shape::Comparator> SetOfShape;
ListOfShape myObjects; ///< list of objects of some operation
- MapShapeToParent myParent; ///< refer a shape to compound/compsolid containing it
+ MapShapeToShape myParent; ///< refer a shape to compound/compsolid containing it
/// indices of compounds/compsolids to keep the order of parent shapes
/// corresponding to the order of objects
MapShapeToIndex myParentIndices;
std::vector<ShapeAndSubshapes> mySubshapes;
SetOfShape myProcessedObjects;
+ MapShapeToShape myModifiedObjects;
public:
/// Add an object of the operation (low-level shape in the hierarchy)
/// Mark list ofshapes as already processed
GEOMAPI_EXPORT void markProcessed(const ListOfShape& theShapes);
+ /// Mark the shape as modified and store its image
+ GEOMAPI_EXPORT void markModified(const GeomShapePtr& theSource, const GeomShapePtr& theModified);
+
/// Split compound/compsolid shape for subshapes selected for operation and the others.
GEOMAPI_EXPORT void splitCompound(const GeomShapePtr& theCompShape,
ListOfShape& theUsed,
/// Generates the list of top-level compounds, which exclude the objects of operation.
GEOMAPI_EXPORT void compoundsOfUnusedObjects(ListOfShape& theDestination) const;
+ /// Generates the list of top-level compounds, with modified objects of operation.
+ GEOMAPI_EXPORT void topLevelObjects(ListOfShape& theDestination) const;
+
/// Return \c true if there is no object in hierarchy
GEOMAPI_EXPORT bool empty() const;
const GeomAPI_Shape::ShapeType theMaxType = GeomAPI_Shape::SHAPE) const;
private:
- GeomShapePtr collectUnusedSubs(const GeomShapePtr theTopLevelCompound,
- const SetOfShape& theUsed) const;
+ /// Collect subs of a top-level compound, excluding the set of given objects
+ /// and substitute the shapes which were modified
+ GeomShapePtr collectSubs(const GeomShapePtr theTopLevelCompound,
+ const SetOfShape& theExcluded = SetOfShape(),
+ const MapShapeToShape& theModified = MapShapeToShape()) const;
public:
class iterator : public std::iterator<std::forward_iterator_tag, GeomShapePtr>
aResultVolumeStr = "{:0.27f}".format(aResultVolume).lstrip("0").lstrip(".").lstrip("0")
anExpectedResultVolume = theExpectedResultsVolumes[anIndex]
anExpectedResultVolumeStr = "{:0.27f}".format(anExpectedResultVolume).lstrip("0").lstrip(".").lstrip("0")
- assert math.fabs(aResultVolume - anExpectedResultVolume) < aTolerance * math.fabs(anExpectedResultVolume), "Volume of result[{}]: {:0.27f}. Expected: {:0.27f}. The first {} significant digits not equal.".format(anIndex, aResultVolume, anExpectedResultVolume, theNbSignificantDigits)
+ assert math.fabs(aResultVolume - anExpectedResultVolume) <= aTolerance * math.fabs(anExpectedResultVolume), "Volume of result[{}]: {:0.27f}. Expected: {:0.27f}. The first {} significant digits not equal.".format(anIndex, aResultVolume, anExpectedResultVolume, theNbSignificantDigits)
def testHaveNamingFaces(theFeature, theModel, thePartDoc) :
""" Tests if all faces of result have a name