FIND_LIBRARY(TKTreeModel TKTreeModel "${TINSPECTOR_LIB_DIR}")
SET(TKTreeModel ${TKTreeModel})
+ FIND_LIBRARY(TKVInspector TKVInspector "${TINSPECTOR_LIB_DIR}")
+ SET(TKVInspector ${TKVInspector})
+
ENDIF(TKTInspector)
ENDIF(EXISTS ${TINSPECTOR_ROOT_DIR})
CMAKE_POLICY(SET CMP0020 OLD) # disable automatic linking to qtmain.lib
ENDIF(WIN32)
-SET (SHAPER_Version 2.7.1)
+SET (SHAPER_Version 2.7.2)
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMakeCommon" ${CMAKE_MODULE_PATH})
SET(SHAPER_INSTALL_TUI_DOC doc CACHE INTERNAL "" FORCE)
ENDIF(${HAVE_SALOME})
+# Sketcher: Change radius of circular edges while dragging a point on the edge
+SET(SKETCHER_CHANGE_RADIUS_WHEN_MOVE FALSE)
+
ADD_SUBDIRECTORY (src/Config)
ADD_SUBDIRECTORY (src/Events)
ADD_SUBDIRECTORY (src/Model)
export TOOLS_DIR=$(pwd)
export HOME_OLD=$HOME
-
source /dn46/SALOME/series8x/current-2017-07-11/start.sh
export HOME=$HOME_OLD
TestGroup.py
TestField.py
TestGroup1799.py
+ TestGroupMove.py
+ TestGroupMove2.py
)
Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_12"), 150, True)
Plane_5 = model.addPlane(Part_1_doc, model.selection("FACE", "Extrusion_1_1/Generated_Face_7"), 150, True)
Partition_1 = model.addPartition(Part_1_doc, [model.selection("FACE", "Plane_1"), model.selection("COMPSOLID", "Extrusion_1_1"), model.selection("FACE", "Plane_2")])
-Plane_6 = model.addPlane(Part_1_doc, model.selection("FACE", "Partition_1_1/Modified_Face_1_2_1"), 110, True)
-Plane_7 = model.addPlane(Part_1_doc, model.selection("FACE", "Partition_1_1/Modified_Face_1_9_1"), 380, True)
+Plane_6 = model.addPlane(Part_1_doc, model.selection("FACE", "Partition_1_1_7/Modified_Face_1_3"), 110, True)
+Plane_7 = model.addPlane(Part_1_doc, model.selection("FACE", "Partition_1_1_5/Modified_Face_1_3"), 380, True)
Partition_2 = model.addPartition(Part_1_doc, [model.selection("FACE", "Plane_3"), model.selection("COMPSOLID", "Partition_1_1"), model.selection("FACE", "Plane_4")])
model.do()
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test that box partitioned is splitted: group with edge becomes 2 edges group,
+# group with not-touched vertex keeps this vertex.
+
+from salome.shaper import model
+from ModelAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 20, 10, 10)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Box_1_1/Back"), 10, True)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Box_1_1/Left&Box_1_1/Top")])
+Group_2 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Box_1_1/Back&Box_1_1/Left&Box_1_1/Top")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Plane_1")])
+model.do()
+# move groups
+Part_1_doc.moveFeature(Group_1.feature(), Partition_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+model.end()
+
+# Check groups
+aFactory = ModelAPI_Session.get().validators()
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 2)
+assert(aFactory.validate(Group_1.feature()))
+
+selectionList = Group_2.feature().selectionList("group_list")
+assert(selectionList.size() == 1)
+assert(aFactory.validate(Group_2.feature()))
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# Test that removed vertex, selected in the group makes group with one invalid element (empty shape)
+
+from salome.shaper import model
+from ModelAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Box_1 = model.addBox(Part_1_doc, 10, 10, 20)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("VERTEX", "Box_1_1/Back&Box_1_1/Right&Box_1_1/Top"), model.selection("VERTEX", "Box_1_1/Front&Box_1_1/Left&Box_1_1/Top"), model.selection("VERTEX", "Box_1_1/Back&Box_1_1/Left&Box_1_1/Bottom"))
+Group_1 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Box_1_1/Back&Box_1_1/Left&Box_1_1/Top")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_1_1"), model.selection("FACE", "Plane_1")])
+Remove_SubShapes_1 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPSOLID", "Partition_1_1"))
+Remove_SubShapes_1.setSubShapesToKeep([model.selection("SOLID", "Partition_1_1_2")])
+model.do()
+# move group
+Part_1_doc.moveFeature(Group_1.feature(), Remove_SubShapes_1.feature())
+model.end()
+
+# Check group
+aFactory = ModelAPI_Session.get().validators()
+selectionList = Group_1.feature().selectionList("group_list")
+assert(selectionList.size() == 1)
+assert(aFactory.validate(Group_1.feature()) == False)
title="Export file"
path="">
<validator id="ExchangePlugin_ExportFormat"
- parameters="BREP|BRP:BREP,STEP|STP:STEP,IGES|IGS:IGES-5.1,IGES|IGS:IGES-5.3" />
+ parameters="brep|brp:BREP,step|stp:STEP,iges|igs:IGES-5.1,iges|igs:IGES-5.3" />
</export_file_selector>
<multi_selector id="selection_list"
tooltip="Select a set of objects"
title="Export file"
path="">
<validator id="ExchangePlugin_ExportFormat"
- parameters="XAO:XAO" />
+ parameters="xao:XAO" />
</export_file_selector>
<stringvalue id="xao_author"
label="Author"
Test2023.py
Test2046.py
Test2038.py
+ Test2172.py
+ Test2194.py
+ Test2197_1.py
+ Test2197_2.py
+ Test2197_3.py
+ Test2197_4.py
+ Test2215.py
+ Test2222.py
+ Test2233.py
+ Test2231.py
+ Test2240.py
+ Test2246.py
+ Test2248.py
+ Test2251.py
)
}
ResultPtr aContext = anObjectAttr->context();
ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aContext);
- if(aResCompSolidPtr.get()) {
+ if(aResCompSolidPtr.get()
+ && aResCompSolidPtr->shape()->shapeType() == GeomAPI_Shape::COMPSOLID) {
std::shared_ptr<GeomAPI_Shape> aContextShape = aResCompSolidPtr->shape();
std::map<std::shared_ptr<GeomAPI_Shape>, ListOfShape>::iterator
anIt = aCompSolidsObjects.begin();
{
//load result
if(theBaseShape->isEqual(theResultShape)) {
- theResultBody->store(theResultShape);
+ theResultBody->store(theResultShape, false);
} else {
const int aModifyTag = 1;
const int aDeletedTag = 2;
const std::string aModFName = "Modified_Face";
theResultBody->loadAndOrientModifiedShapes(&theMakeShape, theBaseShape, GeomAPI_Shape::FACE,
- aModifyTag, aModName, theMapOfShapes);
+ aModifyTag, aModName, theMapOfShapes, false, false, true);
theResultBody->loadDeletedShapes(&theMakeShape, theBaseShape,
GeomAPI_Shape::FACE, aDeletedTag);
}
theResultBody->loadAndOrientModifiedShapes(&theMakeShape, *anIter,
aName == aModEName ? GeomAPI_Shape::EDGE : GeomAPI_Shape::FACE,
- aTag, aName, theMapOfShapes);
+ aTag, aName, theMapOfShapes, false, false, true);
theResultBody->loadDeletedShapes(&theMakeShape, *anIter, GeomAPI_Shape::FACE, aDeletedTag);
}
}
}
theResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), *anIt,
(*anIt)->shapeType() == GeomAPI_Shape::EDGE ?
- GeomAPI_Shape::EDGE : GeomAPI_Shape::FACE, aTag, aName, *aMap.get());
+ GeomAPI_Shape::EDGE : GeomAPI_Shape::FACE, aTag, aName, *aMap.get(), false, false, true);
theResultBody->loadDeletedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::FACE, aDelTag);
}
}
theTag++, aGenName + "Face",
*aMapOfSubShapes.get());
}
+ // issue #2197: make naming of edges generated from vertices
+ if (aShapeTypeToExplode == GeomAPI_Shape::EDGE) {
+ GeomAPI_DataMapOfShapeShape aFacesFromFromEdges;
+ GeomAPI_ShapeExplorer anEdgeExp(theBaseShape, GeomAPI_Shape::EDGE);
+ for(; anEdgeExp.more(); anEdgeExp.next()) {
+ ListOfShape aGenerated;
+ theMakeShape->generated(anEdgeExp.current(), aGenerated);
+ ListOfShape::iterator aGenIter = aGenerated.begin();
+ for(; aGenIter != aGenerated.end(); aGenIter++) {
+ GeomShapePtr aGen = *aGenIter;
+ if (aGen.get() && !aGen->isNull()) {
+ if ((*aGenIter)->shapeType() == GeomAPI_Shape::FACE) { // normal case
+ aFacesFromFromEdges.bind(aGen, anEdgeExp.current());
+ }
+ }
+ }
+ }
+
+ // closed revolution of 1-3 faces can not distinguish lateral and base edges
+ if (aFacesFromFromEdges.size() <= 3) {
+ bool isClosed = false; // lateral edges are closed (in full revolution)
+ GeomAPI_DataMapOfShapeShape anEdgesFromVertices;
+ GeomAPI_ShapeExplorer aVertExp(theBaseShape, GeomAPI_Shape::VERTEX);
+ for(int anIndex = 1; aVertExp.more(); aVertExp.next()) {
+ ListOfShape aGenerated;
+ theMakeShape->generated(aVertExp.current(), aGenerated);
+ ListOfShape::iterator aGenIter = aGenerated.begin();
+ for(; aGenIter != aGenerated.end(); aGenIter++) {
+ std::shared_ptr<GeomAPI_Shape> aGenerated = *aGenIter;
+ if (anEdgesFromVertices.isBound(aGenerated)) // already here
+ continue;
+ std::ostringstream aStream;
+ aStream<<"Lateral_Edge_"<<anIndex++;
+ theResultBody->generated(aGenerated, aStream.str(), theTag++);
+
+ anEdgesFromVertices.bind(aGenerated, aVertExp.current());
+ std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aGenerated));
+ isClosed = isClosed || anEdge->isClosed();
+ }
+ }
+ if (isClosed) {
+ GeomAPI_ShapeExplorer anEdgesExp(theMakeShape->shape(), GeomAPI_Shape::EDGE);
+ for(int anIndex = 1; anEdgesExp.more(); anEdgesExp.next()) {
+ if (!anEdgesFromVertices.isBound(anEdgesExp.current())) {
+ // found a base edge
+ std::ostringstream aStream;
+ aStream<<"Base_Edge_"<<anIndex++;
+ theResultBody->generated(anEdgesExp.current(), aStream.str(), theTag++);
+ // only one orientation is needed
+ anEdgesFromVertices.bind(anEdgesExp.current(), anEdgesExp.current());
+ }
+ }
+ } else if (aFacesFromFromEdges.size() == 1) { // 2233: sphere created by the revolution:
+ // vertices at degenerated edges will have the same name
+ GeomAPI_DataMapOfShapeShape aVertices;
+ GeomAPI_ShapeExplorer aVertExp(theMakeShape->shape(), GeomAPI_Shape::VERTEX);
+ for(int anIndex = 1; aVertExp.more(); aVertExp.next()) {
+ if (!aVertices.isBound(aVertExp.current())) {
+ // found a base edge
+ std::ostringstream aStream;
+ aStream<<"Vertex_"<<anIndex++;
+ theResultBody->generated(aVertExp.current(), aStream.str(), theTag++);
+ // only one orientation is needed
+ aVertices.bind(aVertExp.current(), aVertExp.current());
+ }
+ }
+ }
+ } else { // issue #2197, test case 4 : edges that produce fully-revolved face,
+ // but contain only 2 edges (on apex of revolution)
+ GeomAPI_ShapeExplorer anEdgeExp(theBaseShape, GeomAPI_Shape::EDGE);
+ for(int anIndex = 1; anEdgeExp.more(); anEdgeExp.next()) {
+ ListOfShape aGenerated;
+ theMakeShape->generated(anEdgeExp.current(), aGenerated);
+ ListOfShape::iterator aGenIter = aGenerated.begin();
+ for(; aGenIter != aGenerated.end(); aGenIter++) {
+ GeomShapePtr aGen = (*aGenIter);
+ if (aGen.get() && !aGen->isNull()) {
+ GeomAPI_ShapeExplorer aFaceEdgeExp(aGen, GeomAPI_Shape::EDGE);
+ int aNumEdges = 0;
+ int aNumClosed = 0;
+ GeomShapePtr aNotClosedEdge;
+ GeomAPI_DataMapOfShapeShape alreadyIterated;
+ for(; aFaceEdgeExp.more(); aFaceEdgeExp.next()) {
+ std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aFaceEdgeExp.current()));
+ if (anEdge->isDegenerated() || alreadyIterated.isBound(anEdge))
+ continue;
+ alreadyIterated.bind(anEdge, anEdge);
+ aNumEdges++;
+ if (anEdge->isClosed()) {
+ aNumClosed++;
+ } else {
+ aNotClosedEdge = anEdge;
+ }
+ }
+ if (aNumEdges == 2 && aNumClosed == 1) {
+ std::ostringstream aStream;
+ aStream<<"Base_Edge_"<<anIndex++;
+ theResultBody->generated(aNotClosedEdge, aStream.str(), theTag++);
+ }
+ }
+ }
+ }
+ }
+ }
std::shared_ptr<GeomAlgoAPI_MakeSweep> aMakeSweep =
std::dynamic_pointer_cast<GeomAlgoAPI_MakeSweep>(theMakeShape);
// Store modified shape.
if(!aBaseShape.get() || aBaseShape->isEqual(theResultShape)) {
- aResultBody->store(theResultShape);
+ aResultBody->store(theResultShape, false);
setResult(aResultBody, theIndex);
return;
}
for(ListOfShape::const_iterator anIt = theObjects.cbegin(); anIt != theObjects.cend(); ++anIt) {
GeomShapePtr aShape = *anIt;
std::string aModEdgeName = aModName + "_Edge_" + std::to_string((long long)anIndex);
- std::string aModFaceName = aModName + "_Face_" + std::to_string((long long)anIndex++);
aResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), aShape, GeomAPI_Shape::EDGE,
- aModTag, aModEdgeName, *aMapOfSubShapes.get(), true);
- aModTag += 10000;
+ aModTag, aModEdgeName, *aMapOfSubShapes.get(), false, true, true);
+ std::string aModFaceName = aModName + "_Face_" + std::to_string((long long)anIndex++);
aResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), aShape, GeomAPI_Shape::FACE,
- aModTag, aModFaceName, *aMapOfSubShapes.get(), true);
- aModTag += 10000;
- aResultBody->loadDeletedShapes(theMakeShape.get(), aShape, GeomAPI_Shape::EDGE, aDelTag);
+ aModTag + 1, aModFaceName, *aMapOfSubShapes.get(), false, true, true);
aResultBody->loadDeletedShapes(theMakeShape.get(), aShape, GeomAPI_Shape::FACE, aDelTag);
}
aGenTag++, aGenName + "Face", *aMapOfSubShapes.get());
}
- aResultBody->loadAndOrientGeneratedShapes(&thePipeAlgo, theBaseShape, aShapeTypeToExplode,
- aGenTag++, aGenName, *aMapOfSubShapes.get());
-
// Store from shapes.
int aFromTag = aGenTag;
storeShapes(aResultBody, aBaseShapeType, aMapOfSubShapes,
#include <ModelAPI_Validator.h>
#include <GeomAPI_ShapeIterator.h>
+#include <GeomAPI_ShapeExplorer.h>
#include <GeomAlgoAPI_Copy.h>
#include <GeomAlgoAPI_ShapeBuilder.h>
#include <GeomAlgoAPI_ShapeTools.h>
+#include <GeomAlgoAPI_MakeShapeCustom.h>
+
//==================================================================================================
FeaturesPlugin_RemoveSubShapes::FeaturesPlugin_RemoveSubShapes()
aResultShape = anAttrSelectionInList->value();
}
+ // find all removed shapes
+ GeomAlgoAPI_MakeShapeCustom aDeletedSubs;
+ std::set<GeomAPI_Shape::ShapeType> aTypes; // types that where removed
+ aTypes.insert(GeomAPI_Shape::FACE);
+ for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
+ if (!anIt.current().get() || anIt.current()->isNull())
+ continue;
+ int anIndex;
+ for(anIndex = 0; anIndex < aSubsNb; ++anIndex) {
+ AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
+ GeomShapePtr aLeftShape = anAttrSelectionInList->value();
+ if (anIt.current()->isEqual(aLeftShape)) {
+ break; // found in a left-list
+ }
+ }
+ if (anIndex == aSubsNb) { // not found in left
+ aDeletedSubs.addDeleted(anIt.current());
+ aTypes.insert(anIt.current()->shapeType());
+ if (anIt.current()->shapeType() != GeomAPI_Shape::FACE) {
+ GeomAPI_ShapeExplorer aFaces(anIt.current(), GeomAPI_Shape::FACE);
+ for(; aFaces.more(); aFaces.next())
+ aDeletedSubs.addDeleted(aFaces.current());
+ }
+ }
+ }
+
+
GeomAlgoAPI_Copy aCopy(aResultShape);
aResultShape = aCopy.shape();
// Store result.
ResultBodyPtr aResultBody = document()->createBody(data());
aResultBody->storeModified(aBaseShape, aResultShape, 1);
+ std::set<GeomAPI_Shape::ShapeType>::iterator aTypeIter = aTypes.begin();
+ for(; aTypeIter != aTypes.end(); aTypeIter++)
+ aResultBody->loadDeletedShapes(&aDeletedSubs, aBaseShape, *aTypeIter, 1);
aResultBody->loadAndOrientModifiedShapes(&aCopy,
aBaseShape,
GeomAPI_Shape::FACE,
- 10000,
+ 2,
"Modified_Face",
*aCopy.mapOfSubShapes().get(),
- true);
+ true, false, true);
setResult(aResultBody);
}
theResultBody->loadAndOrientModifiedShapes(&theAlgo,
theBaseShape, GeomAPI_Shape::FACE,
theFaceTag, theName + "_Face", theSubShapes, false, true);
- if (theBaseShape->shapeType() == GeomAPI_Shape::COMPSOLID
- || theBaseShape->shapeType() == GeomAPI_Shape::SOLID) {
- break;
- }
}
case GeomAPI_Shape::FACE:
case GeomAPI_Shape::WIRE: {
Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Translation_1_1"), model.selection("SOLID", "Extrusion_2_1")])
Translation_2 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_1_1")], model.selection("EDGE", "PartSet/OZ"), 50)
Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Translation_2_1/Translated_Face_24"), model.selection("FACE", "Translation_2_1/Translated_Face_13"), model.selection("FACE", "Translation_2_1/Translated_Face_16"), model.selection("FACE", "Translation_2_1/Translated_Face_12"), model.selection("FACE", "Translation_2_1/Translated_Face_9"), model.selection("FACE", "Translation_2_1/Translated_Face_10"), model.selection("FACE", "Translation_2_1/Translated_Face_11"), model.selection("FACE", "Translation_2_1/Translated_Face_25"), model.selection("FACE", "Translation_2_1/Translated_Face_20"), model.selection("FACE", "Translation_2_1/Translated_Face_19"), model.selection("FACE", "Translation_2_1/Translated_Face_18"), model.selection("FACE", "Translation_2_1/Translated_Face_27"), model.selection("FACE", "Translation_2_1/Translated_Face_17"), model.selection("FACE", "Translation_2_1/Translated_Face_31"), model.selection("FACE", "Translation_2_1/Translated_Face_32"), model.selection("FACE", "Translation_2_1/Translated_Face_30"), model.selection("FACE", "Translation_2_1/Translated_Face_28"), model.selection("FACE", "Translation_2_1/Translated_Face_29"), model.selection("FACE", "Translation_2_1/Translated_Face_8"), model.selection("FACE", "Translation_2_1/Translated_Face_22"), model.selection("FACE", "Translation_2_1/Translated_Face_7"), model.selection("FACE", "Translation_2_1/Translated_Face_6"), model.selection("FACE", "Translation_2_1/Translated_Face_5"), model.selection("FACE", "Translation_2_1/Translated_Face_3"), model.selection("FACE", "Translation_2_1/Translated_Face_1"), model.selection("FACE", "Translation_2_1/Translated_Face_2"), model.selection("FACE", "Translation_2_1/Translated_Face_21"), model.selection("FACE", "Translation_2_1/Translated_Face_4"), model.selection("FACE", "Translation_2_1/Translated_Face_25"), model.selection("FACE", "Translation_2_1/Translated_Face_27"), model.selection("FACE", "Translation_2_1/Translated_Face_21"), model.selection("FACE", "Translation_2_1/Translated_Face_22"), model.selection("FACE", "Translation_2_1/Translated_Face_26"), model.selection("FACE", "Translation_2_1/Translated_Face_23"), model.selection("FACE", "Translation_2_1/Translated_Face_30"), model.selection("FACE", "Translation_2_1/Translated_Face_23"), model.selection("FACE", "Translation_2_1/Translated_Face_14"), model.selection("FACE", "Translation_2_1/Translated_Face_15")])
-model.do()
+#Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Translation_2_1_6/Translated_Face_1"), model.selection("FACE", "Translation_2_1_5/Translated_Face_1"), model.selection("FACE", "Translation_2_1_5/Translated_Face_4"), model.selection("FACE", "Translation_2_1_4/Translated_Face_4"), model.selection("FACE", "Translation_2_1_5/Translated_Face_3"), model.selection("FACE", "Translation_2_1_5/Translated_Face_2"), model.selection("FACE", "Translation_2_1_5/Translated_Face_5"), model.selection("FACE", "Translation_2_1_7/Translated_Face_5"), model.selection("FACE", "Translation_2_1_6/Translated_Face_5"), model.selection("FACE", "Translation_2_1_4/Translated_Face_1"), model.selection("FACE", "Translation_2_1_2/Translated_Face_2"), model.selection("FACE", "Translation_2_1_5/Translated_Face_5"), model.selection("FACE", "Translation_2_1_2/Translated_Face_1"), model.selection("FACE", "Translation_2_1_4/Translated_Face_5"), model.selection("FACE", "Translation_2_1_2/Translated_Face_3"), model.selection("FACE", "Translation_2_1_3/Translated_Face_5"), model.selection("FACE", "Translation_2_1_1/Translated_Face_3"), model.selection("FACE", "Translation_2_1_4/Translated_Face_2"), model.selection("FACE", "Translation_2_1_2/Translated_Face_3"), model.selection("FACE", "Translation_2_1_1/Translated_Face_4"), model.selection("FACE", "Translation_2_1_1/Translated_Face_1"), model.selection("FACE", "Translation_2_1_1/Translated_Face_2"), model.selection("FACE", "Translation_2_1_3/Translated_Face_4"), model.selection("FACE", "Translation_2_1_4/Translated_Face_3"), model.selection("FACE", "Translation_2_1_3/Translated_Face_5"), model.selection("FACE", "Translation_2_1_3/Translated_Face_2"), model.selection("FACE", "Translation_2_1_3/Translated_Face_3"), model.selection("FACE", "Translation_2_1_3/Translated_Face_1"), model.selection("FACE", "Translation_2_1_7/Translated_Face_3"), model.selection("FACE", "Translation_2_1_7/Translated_Face_5"), model.selection("FACE", "Translation_2_1_7/Translated_Face_4"), model.selection("FACE", "Translation_2_1_7/Translated_Face_1"), model.selection("FACE", "Translation_2_1_7/Translated_Face_2"), model.selection("FACE", "Translation_2_1_6/Translated_Face_4"), model.selection("FACE", "Translation_2_1_4/Translated_Face_5"), model.selection("FACE", "Translation_2_1_6/Translated_Face_5"), model.selection("FACE", "Translation_2_1_6/Translated_Face_2"), model.selection("FACE", "Translation_2_1_6/Translated_Face_3")])
+
model.end()
groupFeature = Group_1.feature()
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
+SketchLine_1 = Sketch_1.addLine(-85.62958302127123, 51.64856737222455, 159.4430553521271, 401.6485673722245)
+SketchLine_2 = Sketch_1.addLine(159.4430553521271, 401.6485673722245, 909.4430553521272, 401.6485673722245)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(909.4430553521272, 401.6485673722245, 909.4430553521272, -98.35143262777548)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(909.4430553521272, -98.35143262777548, 551.916977573864, -398.3514326277755)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(551.916977573864, -398.3514326277755, -18.08302242613596, -398.3514326277755)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(-18.08302242613596, -398.3514326277755, -18.08302242613596, -98.35143262777552)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchArc_1 = Sketch_1.addArc(0, -7.626897158721915e-023, -85.62958302127123, 51.64856737222455, -18.08302242613596, -98.35143262777552, False)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchArc_1.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_6.result())
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchArc_1.results()[1], 100)
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_2.result(), 750)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_3.result(), 500)
+SketchConstraintLength_3 = Sketch_1.setLength(SketchLine_5.result(), 570)
+SketchConstraintAngle_1 = Sketch_1.setAngleBackward(SketchLine_5.result(), SketchLine_4.result(), 139.9999999999999)
+SketchConstraintAngle_2 = Sketch_1.setAngle(SketchLine_1.result(), SketchLine_2.result(), 124.9999999999987)
+SketchConstraintLength_4 = Sketch_1.setLength(SketchLine_6.result(), 300)
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchArc_1.startPoint(), SketchLine_2.result(), 350)
+SketchConstraintDistance_2 = Sketch_1.setDistance(SketchLine_4.startPoint(), SketchLine_5.result(), 300)
+SketchPoint_1 = Sketch_1.addPoint(model.selection("VERTEX", "PartSet/Origin"))
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchArc_1.center(), SketchPoint_1.coordinates())
+SketchCircle_1 = Sketch_1.addCircle(623.3624504738834, 247.4315530304268, 75)
+SketchCircle_2 = Sketch_1.addCircle(267.9975824521076, 55.86558171402226, 100)
+SketchLine_7 = Sketch_1.addLine(-18.08302242613596, -98.35143262777552, 356.0223839531057, 103.3169707422677)
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchLine_8 = Sketch_1.addLine(557.3438493481349, 211.8430112592427, 909.4430553521272, 401.6485673722245)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_8.endPoint())
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchCircle_2.center(), SketchLine_7.result())
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchCircle_1.center(), SketchLine_7.result())
+SketchConstraintRadius_2 = Sketch_1.setRadius(SketchCircle_2.results()[1], 100)
+SketchConstraintRadius_3 = Sketch_1.setRadius(SketchCircle_1.results()[1], 75)
+SketchPoint_2 = Sketch_1.addPoint(557.3438493481349, 211.8430112592427)
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchPoint_2.coordinates(), SketchLine_8.startPoint())
+SketchConstraintCollinear_1 = Sketch_1.setCollinear(SketchLine_7.result(), SketchLine_8.result())
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchCircle_2.results()[1])
+SketchConstraintDistance_3 = Sketch_1.setDistance(SketchCircle_2.center(), SketchLine_6.endPoint(), 325)
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchPoint_2.coordinates(), SketchCircle_1.results()[1])
+SketchConstraintDistance_4 = Sketch_1.setDistance(SketchCircle_1.center(), SketchLine_2.endPoint(), 325)
+model.do()
+Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f-SketchLine_8f")], model.selection("EDGE", "PartSet/OZ"), 360, 0)
+Revolution_2 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_2_2f-SketchLine_7r")], model.selection("EDGE", "PartSet/OZ"), 360, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Revolution_1_1/Lateral_Edge_1"), model.selection("EDGE", "Revolution_1_1/Lateral_Edge_2"), model.selection("EDGE", "Revolution_1_1/Base_Edge_1"), model.selection("EDGE", "Revolution_1_1/Base_Edge_2"), model.selection("EDGE", "Revolution_2_1/Lateral_Edge_1"), model.selection("EDGE", "Revolution_2_1/Lateral_Edge_2"), model.selection("EDGE", "Revolution_2_1/Lateral_Edge_3"), model.selection("EDGE", "Revolution_2_1/Base_Edge_2"), model.selection("EDGE", "Revolution_2_1/Base_Edge_3"), model.selection("EDGE", "Revolution_2_1/Base_Edge_1")])
+model.end()
+
+# check that resulting group selection is valid
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+assert(aFactory.validate(Group_1.feature()))
+assert(Group_1.groupList().size() == 10)
+for a in range(10):
+ assert(Group_1.groupList().value(a).value().shapeTypeStr() == "EDGE")
+ assert(len(Group_1.groupList().value(a).namingName()) > 0)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+
+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("YOZ"))
+SketchCircle_1 = Sketch_1.addCircle(-79.57211859899775, 93.0358363165245, 69.46562387481423)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f")], model.selection(), 10, 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Extrusion_1_1/To_Face_1"))
+SketchCircle_2 = Sketch_2.addCircle(-111.8968837135755, 98.96901887198163, 6.57145775571253)
+SketchCircle_3 = Sketch_2.addCircle(-41.97827733564338, 89.35676702647821, 6.102067916018811)
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_2/Face-SketchCircle_2_2f"), model.selection("FACE", "Sketch_2/Face-SketchCircle_3_2f")], model.selection(), 10, 0)
+Boolean_1 = model.addSmash(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], [model.selection("SOLID", "Extrusion_2_1"), model.selection("SOLID", "Extrusion_2_2")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Extrusion_2_2/To_Face_1"), model.selection("FACE", "Extrusion_2_2/From_Face_1"), model.selection("FACE", "Extrusion_2_2/Generated_Face_1"), model.selection("FACE", "Extrusion_2_1/From_Face_1"), model.selection("FACE", "Boolean_1_1_1/Modified_1"), model.selection("FACE", "Extrusion_1_1/From_Face_1"), model.selection("FACE", "Extrusion_1_1/Generated_Face_1"), model.selection("FACE", "Extrusion_2_2/From_Face_1"), model.selection("FACE", "Extrusion_2_1/Generated_Face_1"), model.selection("FACE", "Extrusion_2_1/From_Face_1"), model.selection("FACE", "Extrusion_2_1/To_Face_1")])
+model.do()
+model.end()
+
+groupFeature = Group_1.feature()
+groupSelectionList = groupFeature.selectionList("group_list")
+assert(groupSelectionList.size() == 11)
+for index in range(0, groupSelectionList.size()):
+ attrSelection = groupSelectionList.value(index)
+ shape = attrSelection.value()
+ name = attrSelection.namingName()
+ assert(shape.isFace())
+ assert(name != ""), "Empty shape name"
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+
+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("YOZ"))
+SketchCircle_1 = Sketch_1.addCircle(-150, 79, -50, 79)
+SketchCircle_2 = Sketch_1.addCircle(-155, 278, -10, 278)
+model.do()
+Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2f-SketchCircle_2_2f")], model.selection("EDGE", "PartSet/OZ"), 360, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Revolution_1_1/Base_Edge_1"), model.selection("EDGE", "Revolution_1_1/Base_Edge_2"), model.selection("EDGE", "Revolution_1_1/Base_Edge_3")])
+Group_2 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Revolution_1_1/Lateral_Edge_1"), model.selection("EDGE", "Revolution_1_1/Lateral_Edge_2"), model.selection("EDGE", "Revolution_1_1/Lateral_Edge_3")])
+model.end()
+
+# check that resulting group selection is valid
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+for aGroupIter in [Group_1, Group_2]:
+ assert(aFactory.validate(aGroupIter.feature()))
+ assert(aGroupIter.groupList().size() == 3)
+ for a in range(3):
+ assert(aGroupIter.groupList().value(a).value().shapeTypeStr() == "EDGE")
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchCircle_1 = Sketch_1.addCircle(-150, 80, 100)
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchCircle_1_2")])
+Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Face_1_1")], model.selection("EDGE", "PartSet/OZ"), 360, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Revolution_1_1/Base_Edge_1")])
+Group_2 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Revolution_1_1/Lateral_Edge_1")])
+Group_3 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Revolution_1_1/Lateral_Edge_1&Revolution_1_1/Base_Edge_1")])
+model.end()
+
+# check that resulting group selection is valid
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+for aGroupIter in [Group_1, Group_2, Group_3]:
+ assert(aFactory.validate(aGroupIter.feature()))
+ assert(aGroupIter.groupList().size() == 1)
+ if aGroupIter == Group_3:
+ assert(aGroupIter.groupList().value(0).value().shapeTypeStr() == "VERTEX")
+ else:
+ assert(aGroupIter.groupList().value(0).value().shapeTypeStr() == "EDGE")
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# revolution of 3-edges contour (4th is used as axis of rotation) is checking for naming of edges
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
+SketchLine_1 = Sketch_1.addLine(138, 47, 265, 35)
+SketchLine_2 = Sketch_1.addLine(265, 35, 248, 186)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(248, 186, 138, 234)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(138, 234, 138, 47)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_4.endPoint())
+model.do()
+Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_2f-SketchLine_3f-SketchLine_4f")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_4"), 360, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Revolution_1_1/Lateral_Edge_4"), model.selection("EDGE", "Revolution_1_1/Base_Edge_2"), model.selection("EDGE", "Revolution_1_1/Lateral_Edge_2"), model.selection("EDGE", "Revolution_1_1/Base_Edge_1"), model.selection("EDGE", "Revolution_1_1/Base_Edge_3")])
+model.end()
+
+# check that resulting group selection is valid
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+assert(aFactory.validate(Group_1.feature()))
+assert(Group_1.groupList().size() == 5)
+for a in range(5):
+ assert(Group_1.groupList().value(a).value().shapeTypeStr() == "EDGE")
+ assert(len(Group_1.groupList().value(a).namingName()) > 0)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# revolution of 4-edges contour (5th is used as axis of rotation) is checking for naming of edges
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOZ"))
+SketchLine_1 = Sketch_1.addLine(138.1074168797953, 47.3145780051151, 265.9846547314579, 35.80562659846547)
+SketchLine_2 = Sketch_1.addLine(248.0818414322251, 186.7007672634271, 138.1074168797954, 234.0153452685422)
+SketchLine_2.setName("SketchLine_3")
+SketchLine_2.result().setName("SketchLine_3")
+SketchLine_3 = Sketch_1.addLine(138.1074168797954, 234.0153452685422, 138.1074168797953, 47.3145780051151)
+SketchLine_3.setName("SketchLine_4")
+SketchLine_3.result().setName("SketchLine_4")
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_1.setName("SketchConstraintCoincidence_3")
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_3.endPoint())
+SketchConstraintCoincidence_2.setName("SketchConstraintCoincidence_4")
+SketchLine_4 = Sketch_1.addLine(248.0818414322251, 186.7007672634271, 215.8394027534853, 111.2328618876045)
+SketchLine_4.setName("SketchLine_5")
+SketchLine_4.result().setName("SketchLine_5")
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.startPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_3.setName("SketchConstraintCoincidence_5")
+SketchLine_5 = Sketch_1.addLine(215.8394027534853, 111.2328618876045, 265.9846547314579, 35.80562659846547)
+SketchLine_5.setName("SketchLine_6")
+SketchLine_5.result().setName("SketchLine_6")
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_4.setName("SketchConstraintCoincidence_6")
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_5.endPoint())
+SketchConstraintCoincidence_5.setName("SketchConstraintCoincidence_7")
+model.do()
+Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1f-SketchLine_3f-SketchLine_4f-SketchLine_5r-SketchLine_6r")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_4"), 360, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Revolution_1_1/Generated_Face_5&Revolution_1_1/Generated_Face_1"), model.selection("EDGE", "Revolution_1_1/Generated_Face_2&Revolution_1_1/Generated_Face_1"), model.selection("EDGE", "Revolution_1_1/Generated_Face_3&Revolution_1_1/Generated_Face_2"), model.selection("EDGE", "Revolution_1_1/Base_Edge_2"), model.selection("EDGE", "Revolution_1_1/Base_Edge_1"), model.selection("EDGE", "Revolution_1_1/Generated_Face_1"), model.selection("EDGE", "Revolution_1_1/Generated_Face_2")])
+model.end()
+
+# check that resulting group selection is valid
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+assert(aFactory.validate(Group_1.feature()))
+assert(Group_1.groupList().size() == 7)
+for a in range(7):
+ assert(Group_1.groupList().value(a).value().shapeTypeStr() == "EDGE")
+ assert(len(Group_1.groupList().value(a).namingName()) > 0)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(0, 0, 0, 50)
+SketchLine_2 = Sketch_1.addLine(0, 50, 50, 50)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchLine_3 = Sketch_1.addLine(50, 50, 50, 0)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(50, 0, 0, 0)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintRigid_1 = Sketch_1.setFixed(SketchLine_1.startPoint())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_1.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_4.result(), 50)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_1.result(), 50)
+SketchConstraintParallel_1 = Sketch_1.setParallel(SketchLine_1.result(), SketchLine_3.result())
+SketchConstraintParallel_2 = Sketch_1.setParallel(SketchLine_2.result(), SketchLine_4.result())
+SketchConstraintPerpendicular_1 = Sketch_1.setPerpendicular(SketchLine_1.result(), SketchLine_4.result())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r")], model.selection(), 50, 0)
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "Extrusion_1_1/From_Face_1"), 25, True)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
+SketchLine_5 = Sketch_2.addLine(84.67753244325934, -72.65003691291119, -28.95543815719345, -72.65003691291119)
+SketchLine_6 = Sketch_2.addLine(-28.95543815719345, -72.65003691291119, -28.95543815719345, 10.01640181835304)
+SketchLine_7 = Sketch_2.addLine(-28.95543815719345, 10.01640181835304, 84.67753244325934, 10.01640181835304)
+SketchLine_8 = Sketch_2.addLine(84.67753244325934, 10.01640181835304, 84.67753244325934, -72.65003691291119)
+SketchConstraintCoincidence_5 = Sketch_2.setCoincident(SketchLine_8.endPoint(), SketchLine_5.startPoint())
+SketchConstraintCoincidence_6 = Sketch_2.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchConstraintCoincidence_7 = Sketch_2.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_8 = Sketch_2.setCoincident(SketchLine_7.endPoint(), SketchLine_8.startPoint())
+SketchConstraintHorizontal_1 = Sketch_2.setHorizontal(SketchLine_5.result())
+SketchConstraintVertical_2 = Sketch_2.setVertical(SketchLine_6.result())
+SketchConstraintHorizontal_2 = Sketch_2.setHorizontal(SketchLine_7.result())
+SketchConstraintVertical_3 = Sketch_2.setVertical(SketchLine_8.result())
+model.do()
+Wire_1 = model.addWire(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_6"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_8"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_5"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_7")])
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Wire_1_1")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1"), model.selection("FACE", "Face_1_1")])
+Sketch_3 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_9 = Sketch_3.addLine(0, 0, 0, 10)
+SketchLine_10 = Sketch_3.addLine(0, 10, 10, 10)
+SketchConstraintCoincidence_9 = Sketch_3.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchLine_11 = Sketch_3.addLine(10, 10, 10, 0)
+SketchConstraintCoincidence_10 = Sketch_3.setCoincident(SketchLine_10.endPoint(), SketchLine_11.startPoint())
+SketchLine_12 = Sketch_3.addLine(10, 0, 0, 0)
+SketchConstraintCoincidence_11 = Sketch_3.setCoincident(SketchLine_11.endPoint(), SketchLine_12.startPoint())
+SketchConstraintCoincidence_12 = Sketch_3.setCoincident(SketchLine_12.endPoint(), SketchLine_9.startPoint())
+SketchConstraintRigid_2 = Sketch_3.setFixed(SketchLine_9.startPoint())
+SketchConstraintVertical_4 = Sketch_3.setVertical(SketchLine_9.result())
+SketchConstraintLength_3 = Sketch_3.setLength(SketchLine_12.result(), 10)
+SketchConstraintLength_4 = Sketch_3.setLength(SketchLine_9.result(), 10)
+SketchConstraintParallel_3 = Sketch_3.setParallel(SketchLine_9.result(), SketchLine_11.result())
+SketchConstraintParallel_4 = Sketch_3.setParallel(SketchLine_10.result(), SketchLine_12.result())
+SketchConstraintPerpendicular_2 = Sketch_3.setPerpendicular(SketchLine_9.result(), SketchLine_12.result())
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchLine_9r-SketchLine_10r-SketchLine_11r-SketchLine_12r")], model.selection(), 50, 0)
+Boolean_1 = model.addCut(Part_1_doc, [model.selection("COMPSOLID", "Partition_1_1_1")], [model.selection("SOLID", "Extrusion_2_1")])
+model.do()
+model.end()
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# check that fac partitioned by plane has correctly named modified edges
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(173, 265, -254, 265)
+SketchLine_2 = Sketch_1.addLine(-254, 265, -254, 118)
+SketchLine_3 = Sketch_1.addLine(-254, 118, 173, 118)
+SketchLine_4 = Sketch_1.addLine(173, 118, 173, 265)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_3"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), model.selection("EDGE", "Sketch_1/Edge-SketchLine_4")])
+Plane_4 = model.addPlane(Part_1_doc, model.selection("FACE", "PartSet/YOZ"), 1, False)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("FACE", "Plane_1")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Partition_1_1_2/Modified_Edge_1_1")])
+model.end()
+
+# check that resulting group selection is valid
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+assert(aFactory.validate(Group_1.feature()))
+assert(Group_1.groupList().size() == 1)
+assert(Group_1.groupList().value(0).value().shapeTypeStr() == "EDGE")
+assert(len(Group_1.groupList().value(0).namingName()) > 0)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(306.7092651757188, 0, 0, 0)
+SketchPoint_1 = Sketch_1.addPoint(model.selection("VERTEX", "PartSet/Origin"))
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchPoint_1.result())
+SketchLine_2 = Sketch_1.addLine(0, 0, 0, 127.7955271565495)
+SketchLine_3 = Sketch_1.addLine(0, 127.7955271565495, 306.7092651757188, 127.7955271565495)
+SketchLine_4 = Sketch_1.addLine(306.7092651757188, 127.7955271565495, 306.7092651757188, 0)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+SketchLine_5 = Sketch_1.addLine(0, 127.7955271565495, -349.8402555910542, 127.7955271565495)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(-349.8402555910542, 127.7955271565495, -349.8402555910542, 0)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchLine_7 = Sketch_1.addLine(-349.8402555910542, 0, 0, 0)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_7.endPoint())
+SketchLine_8 = Sketch_1.addLine(0, 0, 0, -164.5367412140575)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_8.startPoint())
+SketchLine_9 = Sketch_1.addLine(0, -164.5367412140575, -349.8402555910542, -164.5367412140575)
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_8.endPoint(), SketchLine_9.startPoint())
+SketchLine_10 = Sketch_1.addLine(-349.8402555910542, -164.5367412140575, -349.8402555910542, 0)
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_10.startPoint())
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_10.endPoint())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_7.result())
+SketchConstraintHorizontal_4 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintHorizontal_5 = Sketch_1.setHorizontal(SketchLine_9.result())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_6.result())
+SketchConstraintVertical_4 = Sketch_1.setVertical(SketchLine_10.result())
+SketchConstraintVertical_5 = Sketch_1.setVertical(SketchLine_8.result())
+SketchLine_11 = Sketch_1.addLine(527.1565495207667, -78.27476038338659, 81.46964856230041, -78.27476038338659)
+SketchLine_12 = Sketch_1.addLine(81.46964856230041, -78.27476038338659, 81.46964856230041, -285.9424920127795)
+SketchLine_13 = Sketch_1.addLine(81.46964856230041, -285.9424920127795, 527.1565495207667, -285.9424920127795)
+SketchLine_14 = Sketch_1.addLine(527.1565495207667, -285.9424920127795, 527.1565495207667, -78.27476038338659)
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchLine_14.endPoint(), SketchLine_11.startPoint())
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchLine_11.endPoint(), SketchLine_12.startPoint())
+SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchLine_12.endPoint(), SketchLine_13.startPoint())
+SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchLine_13.endPoint(), SketchLine_14.startPoint())
+SketchConstraintHorizontal_6 = Sketch_1.setHorizontal(SketchLine_11.result())
+SketchConstraintVertical_6 = Sketch_1.setVertical(SketchLine_12.result())
+SketchConstraintHorizontal_7 = Sketch_1.setHorizontal(SketchLine_13.result())
+SketchConstraintVertical_7 = Sketch_1.setVertical(SketchLine_14.result())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_2f-SketchLine_5f-SketchLine_6f-SketchLine_7f"), model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r"), model.selection("FACE", "Sketch_1/Face-SketchLine_7r-SketchLine_8r-SketchLine_9r-SketchLine_10r"), model.selection("FACE", "Sketch_1/Face-SketchLine_11f-SketchLine_12f-SketchLine_13f-SketchLine_14f")], model.selection(), 10, 0)
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1"), model.selection("COMPSOLID", "Extrusion_1_2")])
+model.do()
+model.end()
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# check that revolution that produces a sphere has correctly named 2 vertices with different names
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchPoint_1 = Sketch_1.addPoint(model.selection("VERTEX", "PartSet/Origin"))
+SketchLine_1 = Sketch_1.addLine(model.selection("EDGE", "PartSet/OZ"))
+SketchArc_1 = Sketch_1.addArc(0, 0, 0, 50, 0, -50, True)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchArc_1.center())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.result(), SketchArc_1.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.result())
+SketchLine_2 = Sketch_1.addLine(0, 50, 0, -50)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchArc_1.endPoint())
+model.do()
+Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchArc_1_2f-SketchLine_2f")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), 360, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Revolution_1_1/Vertex_1"), model.selection("VERTEX", "Revolution_1_1/Vertex_2")])
+model.end()
+
+# check that resulting group selection is valid and names are different
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+assert(aFactory.validate(Group_1.feature()))
+assert(Group_1.groupList().size() == 2)
+assert(Group_1.groupList().value(0).value().shapeTypeStr() == "VERTEX")
+assert(len(Group_1.groupList().value(0).namingName()) > 0)
+assert(Group_1.groupList().value(1).value().shapeTypeStr() == "VERTEX")
+assert(Group_1.groupList().value(0).namingName() != Group_1.groupList().value(1).namingName())
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "length_assemblage", "10")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(0, 60, 10, 60)
+SketchLine_2 = Sketch_1.addLine(model.selection("EDGE", "PartSet/OY"))
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_2.result())
+SketchLine_3 = Sketch_1.addLine(10, 60, 10, 40)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(10, 40, 20, 40)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(20, 40, 20, 20)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(20, 20, 30, 20)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchLine_7 = Sketch_1.addLine(30, 20, 30, 0)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchLine_8 = Sketch_1.addLine(model.selection("EDGE", "PartSet/OX"))
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.result())
+SketchLine_9 = Sketch_1.addLine(30, 0, 81.26217508737108, 0)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_8.result())
+SketchLine_10 = Sketch_1.addLine(0, 60, 0, 81.26217508737108)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_10.startPoint())
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_2.result())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_4.result())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_6.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_5.result())
+SketchArc_1 = Sketch_1.addArc(4.151438510550382e-034, -3.089278765476956e-034, 81.26217508737108, 0, 0, 81.26217508737108, False)
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_2.startPoint(), SketchArc_1.center())
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchArc_1.startPoint())
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchLine_2.result(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchArc_1.endPoint())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_7.result())
+SketchArc_2 = Sketch_1.addArc(4.151438510550382e-034, -3.089278765476956e-034, 76.26217508737108, 0, 0, 76.26217508737108, False)
+SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchLine_2.startPoint(), SketchArc_2.center())
+SketchConstraintCoincidence_16.setName("SketchConstraintCoincidence_23")
+SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchLine_9.result(), SketchArc_2.startPoint())
+SketchConstraintCoincidence_17.setName("SketchConstraintCoincidence_24")
+SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchLine_10.result(), SketchArc_2.endPoint())
+SketchConstraintCoincidence_18.setName("SketchConstraintCoincidence_25")
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchArc_1.endPoint(), SketchArc_2.endPoint(), 5)
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_7.result(), "2*length_assemblage")
+SketchConstraintLength_1.setName("SketchConstraintLength_2")
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_6.result(), "length_assemblage")
+SketchConstraintLength_2.setName("SketchConstraintLength_3")
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_5.result(), SketchLine_7.result())
+SketchConstraintEqual_1.setName("SketchConstraintEqual_2")
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_6.result(), SketchLine_4.result())
+SketchConstraintEqual_2.setName("SketchConstraintEqual_3")
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_5.result(), SketchLine_3.result())
+SketchConstraintEqual_3.setName("SketchConstraintEqual_4")
+SketchConstraintEqual_4 = Sketch_1.setEqual(SketchLine_4.result(), SketchLine_1.result())
+SketchConstraintEqual_4.setName("SketchConstraintEqual_5")
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_2.addCircle(9.082839147404137, 71.32948234489588, 2.005056553640547)
+SketchCircle_2 = Sketch_2.addCircle(20.11065019242717, 63.7102674410618, 2.268462537186828)
+SketchCircle_3 = Sketch_2.addCircle(26.52683116407693, 51.67992811921848, 2.727171758268866)
+SketchCircle_4 = Sketch_2.addCircle(38.35666483055617, 58.29661474623231, 3.007584830460834)
+SketchCircle_5 = Sketch_2.addCircle(33.94554041254697, 44.0607132153844, 3.054011155390377)
+SketchCircle_6 = Sketch_2.addCircle(48.58245325412298, 42.45666797247195, 2.346858526438435)
+SketchCircle_7 = Sketch_2.addCircle(38.95818179664835, 31.42885692744893, 3.547307159201095)
+SketchCircle_8 = Sketch_2.addCircle(63.82088306179116, 27.41874382016783, 4.536925074373651)
+SketchCircle_9 = Sketch_2.addCircle(50.18649849703544, 28.4212720969881, 4.820482891521984)
+SketchCircle_10 = Sketch_2.addCircle(49.58498153094326, 15.18789884296047, 2.552020354335177)
+SketchCircle_11 = Sketch_2.addCircle(66.22695092615982, 10.77677442495125, 4.536925074373645)
+SketchCircle_12 = Sketch_2.addCircle(50.98852111849166, 6.165144351577979, 3.547307159201085)
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6f-SketchLine_7f-SketchLine_9f-SketchLine_10r-SketchArc_2_2f")])
+Face_2 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_9f-SketchLine_10r-SketchArc_1_2f-SketchArc_2_2r")])
+Face_3 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchCircle_1_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_2_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_3_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_4_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_5_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_6_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_7_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_9_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_8_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_10_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_12_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_11_2")])
+Face_4 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchCircle_1_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_2_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_3_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_4_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_5_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_7_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_6_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_9_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_8_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_10_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_12_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_11_2"), model.selection("WIRE", "Sketch_1/Wire-SketchLine_1f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6f-SketchLine_7f-SketchLine_9f-SketchLine_10r-SketchArc_2_2f")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_2_1"), model.selection("FACE", "Face_3_1"), model.selection("FACE", "Face_3_2"), model.selection("FACE", "Face_3_3"), model.selection("FACE", "Face_3_4"), model.selection("FACE", "Face_3_5"), model.selection("FACE", "Face_3_6"), model.selection("FACE", "Face_3_7"), model.selection("FACE", "Face_3_8"), model.selection("FACE", "Face_3_9"), model.selection("FACE", "Face_3_10"), model.selection("FACE", "Face_3_11"), model.selection("FACE", "Face_3_12"), model.selection("FACE", "Face_4_1")])
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Face_2_1"), model.selection("FACE", "Face_3_7"), model.selection("FACE", "Face_3_5"), model.selection("FACE", "Face_3_3"), model.selection("FACE", "Face_3_4"), model.selection("FACE", "Face_3_1"), model.selection("FACE", "Face_3_2"), model.selection("FACE", "Face_3_6"), model.selection("FACE", "Face_3_11"), model.selection("FACE", "Face_3_10"), model.selection("FACE", "Face_3_8"), model.selection("FACE", "Face_3_9"), model.selection("FACE", "Face_3_12")])
+Group_1.result().setName("eau")
+Group_1.result().setColor(0, 170, 255)
+Group_2 = model.addGroup(Part_1_doc, [model.selection("FACE", "Face_4_1")])
+Group_2.result().setName("acier")
+Group_2.result().setColor(170, 85, 0)
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/XOY"))
+SketchLine_11 = Sketch_3.addLine(40, 0, 30, 0)
+SketchPoint_1 = Sketch_3.addPoint(model.selection("VERTEX", "Partition_1_1_1/Modified_Edge_15_6&Partition_1_1_1/Modified_Edge_15_5"))
+SketchConstraintCoincidence_19 = Sketch_3.setCoincident(SketchLine_11.endPoint(), SketchPoint_1.result())
+SketchLine_12 = Sketch_3.addLine(30, 0, 30, 10)
+SketchLine_13 = Sketch_3.addLine(30, 10, 40, 10)
+SketchLine_14 = Sketch_3.addLine(40, 10, 40, 0)
+SketchConstraintCoincidence_20 = Sketch_3.setCoincident(SketchLine_14.endPoint(), SketchLine_11.startPoint())
+SketchConstraintCoincidence_21 = Sketch_3.setCoincident(SketchLine_11.endPoint(), SketchLine_12.startPoint())
+SketchConstraintCoincidence_22 = Sketch_3.setCoincident(SketchLine_12.endPoint(), SketchLine_13.startPoint())
+SketchConstraintCoincidence_23 = Sketch_3.setCoincident(SketchLine_13.endPoint(), SketchLine_14.startPoint())
+SketchConstraintCoincidence_23.setName("SketchConstraintCoincidence_26")
+SketchConstraintHorizontal_4 = Sketch_3.setHorizontal(SketchLine_11.result())
+SketchConstraintVertical_4 = Sketch_3.setVertical(SketchLine_12.result())
+SketchConstraintHorizontal_5 = Sketch_3.setHorizontal(SketchLine_13.result())
+SketchConstraintVertical_5 = Sketch_3.setVertical(SketchLine_14.result())
+SketchConstraintLength_3 = Sketch_3.setLength(SketchLine_13.result(), "length_assemblage")
+SketchConstraintLength_3.setName("SketchConstraintLength_1")
+SketchConstraintEqual_5 = Sketch_3.setEqual(SketchLine_13.result(), SketchLine_14.result())
+SketchConstraintEqual_5.setName("SketchConstraintEqual_1")
+model.do()
+Face_5 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_3/Wire-SketchLine_11r-SketchLine_12r-SketchLine_13r-SketchLine_14r")])
+MultiTranslation_1 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Face_5_1")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_9"), "length_assemblage", 4, model.selection("EDGE", "PartSet/OY"), "length_assemblage", 2)
+Recover_1 = model.addRecover(Part_1_doc, MultiTranslation_1, [Face_5.result()])
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_1_1")], model.selection("VERTEX", "Sketch_3/Vertex-SketchPoint_1-SketchLine_12s-SketchLine_11e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_6s-SketchLine_5e"))
+MultiTranslation_2 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_1_1")], model.selection("EDGE", "PartSet/OX"), "length_assemblage", 4, model.selection("EDGE", "PartSet/OY"), "length_assemblage", 2)
+Recover_2 = model.addRecover(Part_1_doc, MultiTranslation_1, [Face_5.result()])
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_2_1")], model.selection("VERTEX", "Sketch_3/Vertex-SketchPoint_1-SketchLine_12s-SketchLine_11e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_4s-SketchLine_3e"))
+MultiTranslation_3 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_2_1")], model.selection("EDGE", "PartSet/OX"), "length_assemblage", 4)
+Recover_3 = model.addRecover(Part_1_doc, MultiTranslation_1, [Face_5.result()])
+Translation_3 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_3_1")], model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_9s-SketchLine_7e"), model.selection("VERTEX", "MultiTranslation_3_1/Translated_Edge_1_4&MultiTranslation_3_1/Translated_Edge_1_1"))
+MultiTranslation_4 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_3_1")], model.selection("EDGE", "PartSet/OX"), "length_assemblage", 3)
+Recover_4 = model.addRecover(Part_1_doc, MultiTranslation_1, [Face_5.result()])
+Translation_4 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_4_1")], model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_9s-SketchLine_7e"), model.selection("VERTEX", "Sketch_1/Vertex-SketchLine_1s-SketchLine_10s"))
+MultiTranslation_5 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_4_1")], model.selection("EDGE", "PartSet/OX"), "length_assemblage", 2)
+Partition_2 = model.addPartition(Part_1_doc, [model.selection("COMPOUND", "Partition_1_1"), model.selection("COMPOUND", "MultiTranslation_1_1"), model.selection("COMPOUND", "MultiTranslation_2_1"), model.selection("COMPOUND", "MultiTranslation_3_1"), model.selection("COMPOUND", "MultiTranslation_4_1"), model.selection("COMPOUND", "MultiTranslation_5_1")])
+model.end()
+
+# check that partition constructed correctly
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+assert(aFactory.validate(Partition_2.feature()))
+assert(Partition_2.feature().results().size() == 1)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# check that revolution that produces a sphere has correctly named 2 vertices with different names
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("YOZ"))
+SketchPoint_1 = Sketch_1.addPoint(model.selection("VERTEX", "PartSet/Origin"))
+SketchLine_1 = Sketch_1.addLine(model.selection("EDGE", "PartSet/OZ"))
+SketchArc_1 = Sketch_1.addArc(0, 0, 0, 62, 0, -62, False)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchArc_1.center())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.result(), SketchArc_1.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_1.result())
+SketchLine_2 = Sketch_1.addLine(0, -62, 0, 62)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchArc_1.startPoint(), SketchLine_2.endPoint())
+model.do()
+Revolution_1 = model.addRevolution(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchArc_1_2f-SketchLine_2f")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), 360, 0)
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Revolution_1_1")], model.selection("EDGE", "PartSet/OY"), 150)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("VERTEX", "Translation_1_1/Translated_Vertex_1"), model.selection("VERTEX", "Translation_1_1/Translated_Vertex_2")])
+model.end()
+
+# check that resulting group selection is valid, names exist and different
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+assert(aFactory.validate(Group_1.feature()))
+assert(Group_1.groupList().size() == 2)
+assert(Group_1.groupList().value(0).value().shapeTypeStr() == "VERTEX")
+assert(len(Group_1.groupList().value(0).namingName()) > 0)
+assert(Group_1.groupList().value(1).value().shapeTypeStr() == "VERTEX")
+assert(Group_1.groupList().value(0).namingName() != Group_1.groupList().value(1).namingName())
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# check that extrusion of sketch with intersected edges produces well-named edges
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(394.1014919414247, 282.461820162796, -355.0948596332293, 282.461820162796)
+SketchLine_2 = Sketch_1.addLine(-355.0948596332293, 282.461820162796, -355.0948596332293, -224.6243998437472)
+SketchLine_3 = Sketch_1.addLine(-355.0948596332293, -224.6243998437472, 394.1014919414247, -224.6243998437472)
+SketchLine_4 = Sketch_1.addLine(394.1014919414247, -224.6243998437472, 394.1014919414247, 282.461820162796)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+SketchArc_1 = Sketch_1.addArc(-7.174842024158346, 282.461820162796, -355.0948596332293, 282.461820162796, 143.9210226543769, -30.9362945892586, False)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_2.startPoint(), SketchArc_1.startPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchLine_2.result(), SketchArc_1.results()[1])
+SketchArc_2 = Sketch_1.addArc(394.1014919414247, 441.436567364073, 394.1014919414247, -224.6243998437472, -125.0902346435239, 24.21101315681109, True)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchArc_2.startPoint())
+SketchConstraintTangent_2 = Sketch_1.setTangent(SketchLine_3.result(), SketchArc_2.results()[1])
+SketchCircle_1 = Sketch_1.addCircle(-13.45056286489504, 169.4770920976776, 150.6703210346195)
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 10, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/From_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_4&Extrusion_1_1/To_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_2"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_10&Extrusion_1_1/To_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_10&Extrusion_1_1/From_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/To_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/From_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_10"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/Generated_Face_10"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/To_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/From_Face_3"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_3&Extrusion_1_1/Generated_Face_9"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/To_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/From_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/From_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/To_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_2&Extrusion_1_1/Generated_Face_5"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/Generated_Face_6"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/From_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/To_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/To_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_1&Extrusion_1_1/From_Face_4"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_5&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_11&Extrusion_1_1/Generated_Face_5"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_11&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_11&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_11&Extrusion_1_1/Generated_Face_10"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/Generated_Face_5"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_10&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_10&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_6&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/Generated_Face_6"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_7&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_10&Extrusion_1_1/Generated_Face_9"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_9&Extrusion_1_1/Generated_Face_8"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_8&Extrusion_1_1/To_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_8&Extrusion_1_1/From_Face_1"), model.selection("EDGE", "Extrusion_1_1/Generated_Face_8&Extrusion_1_1/Generated_Face_7")])
+model.end()
+
+# check that resulting group selection is valid
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+assert(aFactory.validate(Group_1.feature()))
+assert(Group_1.groupList().size() == 46)
+for a in range(46):
+ assert(Group_1.groupList().value(a).value().shapeTypeStr() == "EDGE")
+ assert(len(Group_1.groupList().value(a).namingName()) > 0)
+
+assert(model.checkPythonDump())
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+# check that extrusion of sketch with intersected edges produces well-named faces
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(500.0000311770457, 317.8294573643411, -308.1395348837211, 317.8294573643411)
+SketchLine_2 = Sketch_1.addLine(-308.1395348837211, 317.8294573643411, -308.1395348837211, -263.9724263224183)
+SketchLine_3 = Sketch_1.addLine(-308.1395348837211, -263.9724263224183, 500.0000311770457, -263.9724263224183)
+SketchLine_4 = Sketch_1.addLine(500.0000311770457, -263.9724263224183, 500.0000311770457, 317.8294573643411)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+SketchCircle_1 = Sketch_1.addCircle(-118.2170542635659, 222.8682170542636, 141.685090902591)
+SketchCircle_2 = Sketch_1.addCircle(294.5736434108529, -40.69767441860468, 113.2187726277406)
+SketchArc_1 = Sketch_1.addArc(500.0000311770867, -335287.7996679137, 500.0000311770457, -263.9724263224183, -639.534183538502, -265.9104108427558, True)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchArc_1.startPoint())
+SketchConstraintTangent_1 = Sketch_1.setTangent(SketchLine_3.result(), SketchArc_1.results()[1])
+SketchArc_2 = Sketch_1.addArc(-638.1195022375863, -681.8252609710054, -639.534183538502, -265.9104108427558, -316.014851248167, -418.6983758160058, True)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchArc_1.endPoint(), SketchArc_2.startPoint())
+SketchConstraintTangent_2 = Sketch_1.setTangent(SketchArc_1.results()[1], SketchArc_2.results()[1])
+SketchArc_3 = Sketch_1.addArc(-167.5780303038277, -297.4405230733651, -316.014851248167, -418.6983758160058, -17.4411870157839, -178.2940378070349, False)
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchArc_2.endPoint(), SketchArc_3.startPoint())
+SketchConstraintTangent_3 = Sketch_1.setTangent(SketchArc_2.results()[1], SketchArc_3.results()[1])
+SketchArc_4 = Sketch_1.addArc(-301.8048538198685, -403.9610406236078, -17.4411870157839, -178.2940378070349, -637.5573748460384, -265.908384788777, False)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchArc_3.endPoint(), SketchArc_4.startPoint())
+SketchConstraintTangent_4 = Sketch_1.setTangent(SketchArc_3.results()[1], SketchArc_4.results()[1])
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchArc_2.results()[1], SketchArc_4.endPoint())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("COMPOUND", "Sketch_1")], model.selection(), 100, 0)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "Extrusion_1_1/Generated_Face_19"), model.selection("FACE", "Extrusion_1_1/Generated_Face_18"), model.selection("FACE", "Extrusion_1_1/Generated_Face_16"), model.selection("FACE", "Extrusion_1_1/Generated_Face_15"), model.selection("FACE", "Extrusion_1_1/Generated_Face_15"), model.selection("FACE", "Extrusion_1_1/Generated_Face_5"), model.selection("FACE", "Extrusion_1_1/Generated_Face_4"), model.selection("FACE", "Extrusion_1_1/From_Face_3"), model.selection("FACE", "Extrusion_1_1/Generated_Face_3"), model.selection("FACE", "Extrusion_1_1/To_Face_3"), model.selection("FACE", "Extrusion_1_1/Generated_Face_19"), model.selection("FACE", "Extrusion_1_1/Generated_Face_4"), model.selection("FACE", "Extrusion_1_1/From_Face_4"), model.selection("FACE", "Extrusion_1_1/To_Face_4"), model.selection("FACE", "Extrusion_1_1/Generated_Face_8"), model.selection("FACE", "Extrusion_1_1/Generated_Face_3"), model.selection("FACE", "Extrusion_1_1/Generated_Face_9"), model.selection("FACE", "Extrusion_1_1/From_Face_6"), model.selection("FACE", "Extrusion_1_1/Generated_Face_13"), model.selection("FACE", "Extrusion_1_1/To_Face_6"), model.selection("FACE", "Extrusion_1_1/Generated_Face_1"), model.selection("FACE", "Extrusion_1_1/Generated_Face_12"), model.selection("FACE", "Extrusion_1_1/To_Face_5"), model.selection("FACE", "Extrusion_1_1/Generated_Face_2"), model.selection("FACE", "Extrusion_1_1/From_Face_5"), model.selection("FACE", "Extrusion_1_1/Generated_Face_1"), model.selection("FACE", "Extrusion_1_1/Generated_Face_8"), model.selection("FACE", "Extrusion_1_1/Generated_Face_9"), model.selection("FACE", "Extrusion_1_1/Generated_Face_13"), model.selection("FACE", "Extrusion_1_1/Generated_Face_7"), model.selection("FACE", "Extrusion_1_1/Generated_Face_14"), model.selection("FACE", "Extrusion_1_1/Generated_Face_12"), model.selection("FACE", "Extrusion_1_1/Generated_Face_18"), model.selection("FACE", "Extrusion_1_1/From_Face_2"), model.selection("FACE", "Extrusion_1_1/Generated_Face_11"), model.selection("FACE", "Extrusion_1_1/Generated_Face_6"), model.selection("FACE", "Extrusion_1_1/To_Face_2"), model.selection("FACE", "Extrusion_1_1/Generated_Face_10"), model.selection("FACE", "Extrusion_1_1/Generated_Face_6"), model.selection("FACE", "Extrusion_1_1/To_Face_7"), model.selection("FACE", "Extrusion_1_1/From_Face_7"), model.selection("FACE", "Extrusion_1_1/Generated_Face_17"), model.selection("FACE", "Extrusion_1_1/From_Face_1"), model.selection("FACE", "Extrusion_1_1/To_Face_1")])
+model.end()
+
+# check that resulting group selection is valid
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+assert(aFactory.validate(Group_1.feature()))
+assert(Group_1.groupList().size() == 44)
+for a in range(44):
+ assert(Group_1.groupList().value(a).value().shapeTypeStr() == "FACE")
+ assert(len(Group_1.groupList().value(a).namingName()) > 0)
+
+assert(model.checkPythonDump())
clear_in_neutral_point="false">
<validator id="FeaturesPlugin_ValidatorPartitionSelection" parameters="Plane"/>
</multi_selector>
- <validator id="GeomValidators_MinObjectsSelected" parameters="base_objects,2"/>
+ <validator id="GeomValidators_MinObjectsSelected" parameters="base_objects,1"/>
</source>
Adaptor3d_Curve* anAdaptor3d = &aBRepAdaptor;
return GCPnts_AbscissaPoint::Length(*anAdaptor3d);
}
+
+bool GeomAPI_Edge::isClosed() const
+{
+ const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
+ if (aShape.IsNull())
+ return false;
+ double aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve((const TopoDS_Edge&)aShape, aFirst, aLast);
+ if (aCurve.IsNull() || !aCurve->IsPeriodic())
+ return false;
+ aLast += aLast > aFirst ? -aCurve->Period() : aCurve->Period();;
+
+ return fabs(aFirst - aLast) < 1.e-9;
+}
+
+bool GeomAPI_Edge::isDegenerated() const
+{
+ const TopoDS_Shape& aShape = const_cast<GeomAPI_Edge*>(this)->impl<TopoDS_Shape>();
+ if (aShape.IsNull() || aShape.ShapeType() != TopAbs_EDGE)
+ return false;
+ return BRep_Tool::Degenerated(TopoDS::Edge(aShape));
+}
/// Returns edge length.
GEOMAPI_EXPORT
double length() const;
+
+ /// Returns true if the edge is closed (like full circle)
+ GEOMAPI_EXPORT
+ bool isClosed() const;
+
+ /// Returns true if the edge is degenerated (has no 3D curve)
+ GEOMAPI_EXPORT
+ bool isDegenerated() const;
};
//! Pointer on attribute object
//
#include <GeomAlgoAPI_EdgeBuilder.h>
-
-#include <Bnd_Box.hxx>
-#include <BRep_Tool.hxx>
-#include <BRepBndLib.hxx>
+#include <gp_Pln.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS.hxx>
+#include <BRep_Tool.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom_CylindricalSurface.hxx>
+#include <Geom_RectangularTrimmedSurface.hxx>
+
#include <gp_Ax2.hxx>
#include <gp_Circ.hxx>
#include <gp_Elips.hxx>
-#include <gp_Pln.hxx>
-#include <Geom_CylindricalSurface.hxx>
-#include <Geom_Plane.hxx>
-#include <Geom_RectangularTrimmedSurface.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
+#include <Bnd_Box.hxx>
+#include <BRepBndLib.hxx>
std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_EdgeBuilder::line(
std::shared_ptr<GeomAPI_Pnt> theStart, std::shared_ptr<GeomAPI_Pnt> theEnd)
/// OCCT creates an edge on a circle with empty radius, but visualization
/// is not able to process it
- if (theCenter->isEqual(theStartPoint))
+ if (theCenter->isEqual(theStartPoint) || theCenter->isEqual(theEndPoint))
return aRes;
double aRadius = theCenter->distance(theStartPoint);
aBuilderIt != myListOfMakeShape.end(); aBuilderIt++) {
std::shared_ptr<GeomAlgoAPI_MakeShape> aMakeShape = *aBuilderIt;
NCollection_Map<TopoDS_Shape> aTempShapes;
- bool hasResults = false;
for(NCollection_Map<TopoDS_Shape>::Iterator
aShapeIt(anAlgoShapes); aShapeIt.More(); aShapeIt.Next()) {
+ bool hasResults = false;
std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape);
aShape->setImpl(new TopoDS_Shape(aShapeIt.Value()));
ListOfShape aGeneratedShapes;
#include <TopExp_Explorer.hxx>
#include <TopoDS_Builder.hxx>
+#include <TopTools_MapOfShape.hxx>
//=================================================================================================
std::shared_ptr<GeomAPI_Shape> GeomAlgoAPI_Partition::make(const ListOfShape& theObjects,
build(theObjects, theTools);
}
+static void prepareShapes(const TopoDS_Shape& theShape,
+ TopTools_ListOfShape& theSimpleList)
+{
+ if (theShape.ShapeType() != TopAbs_COMPOUND) {
+ theSimpleList.Append(theShape);
+ return;
+ }
+
+ // explode compound on simple shapes to allow their intersections
+ TopoDS_Iterator It (theShape, Standard_True, Standard_True);
+ for (; It.More(); It.Next()) {
+ TopoDS_Shape curSh = It.Value();
+ prepareShapes(curSh, theSimpleList);
+ }
+}
//=================================================================================================
void GeomAlgoAPI_Partition::build(const ListOfShape& theObjects,
this->setImpl(anOperation);
this->setBuilderType(OCCT_BOPAlgo_Builder);
+ TopTools_MapOfShape ShapesMap;
// Getting objects.
- for (ListOfShape::const_iterator
+ for(ListOfShape::const_iterator
anObjectsIt = theObjects.begin(); anObjectsIt != theObjects.end(); anObjectsIt++) {
const TopoDS_Shape& aShape = (*anObjectsIt)->impl<TopoDS_Shape>();
- anOperation->AddArgument(aShape);
+ // #2240: decompose compounds to get the valid result
+ TopTools_ListOfShape aSimpleShapes;
+ prepareShapes(aShape, aSimpleShapes);
+ TopTools_ListIteratorOfListOfShape aSimpleIter(aSimpleShapes);
+ for (; aSimpleIter.More(); aSimpleIter.Next()) {
+ const TopoDS_Shape& aSimpleSh = aSimpleIter.Value();
+ if (ShapesMap.Add(aSimpleSh)) {
+ anOperation->AddArgument(aSimpleSh);
+ }
+ }
}
// Getting tools.
}
// Making pipe.
- BRepOffsetAPI_MakePipeShell* aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire);
- if(!aPipeBuilder) {
- return;
- }
+ Standard_Boolean isDone = Standard_False;
bool anIsSolidNeeded = false;
- ListOfShape::const_iterator aBaseIt = theBaseShapes.cbegin();
- ListOfShape::const_iterator aLocIt = theLocations.cbegin();
- while(aBaseIt != theBaseShapes.cend()) {
- GeomShapePtr aBase = *aBaseIt;
- TopoDS_Shape aBaseShape;
- TopAbs_ShapeEnum aBaseShapeType;
- if(!getBase(aBaseShape, aBaseShapeType, aBase)) {
- delete aPipeBuilder;
+ BRepOffsetAPI_MakePipeShell* aPipeBuilder;
+ for(int i = 0; i < 2; ++i) {
+ aPipeBuilder = new BRepOffsetAPI_MakePipeShell(aPathWire);
+ if(!aPipeBuilder) {
return;
}
- ++aBaseIt;
- if(aBaseShapeType == TopAbs_FACE) {
- anIsSolidNeeded = true;
- }
-
- if(aHasLocations) {
- GeomShapePtr aLocation = *aLocIt;
- if(!aLocation.get() || aLocation->shapeType() != GeomAPI_Shape::VERTEX) {
+ ListOfShape::const_iterator aBaseIt = theBaseShapes.cbegin();
+ ListOfShape::const_iterator aLocIt = theLocations.cbegin();
+ while(aBaseIt != theBaseShapes.cend()) {
+ GeomShapePtr aBase = *aBaseIt;
+ TopoDS_Shape aBaseShape;
+ TopAbs_ShapeEnum aBaseShapeType;
+ if(!getBase(aBaseShape, aBaseShapeType, aBase)) {
delete aPipeBuilder;
return;
}
- TopoDS_Vertex aLocationVertex = aLocation->impl<TopoDS_Vertex>();
- ++aLocIt;
- aPipeBuilder->Add(aBaseShape, aLocationVertex);
- } else {
- aPipeBuilder->Add(aBaseShape);
+ ++aBaseIt;
+ if(aBaseShapeType == TopAbs_FACE) {
+ anIsSolidNeeded = true;
+ }
+
+ if(aHasLocations) {
+ GeomShapePtr aLocation = *aLocIt;
+ if(!aLocation.get() || aLocation->shapeType() != GeomAPI_Shape::VERTEX) {
+ delete aPipeBuilder;
+ return;
+ }
+ TopoDS_Vertex aLocationVertex = aLocation->impl<TopoDS_Vertex>();
+ ++aLocIt;
+ aPipeBuilder->Add(aBaseShape, aLocationVertex);
+ } else {
+ aPipeBuilder->Add(aBaseShape);
+ }
+ }
+
+ if(aPipeBuilder->IsReady() == Standard_False) {
+ delete aPipeBuilder;
+ return;
+ }
+
+ if (i == 1) {
+ // Try to use Descrete Trihedron mode.
+ aPipeBuilder->SetDiscreteMode();
+ }
+ aPipeBuilder->Build();
+ isDone = aPipeBuilder->IsDone();
+
+ if (isDone) {
+ break;
}
- }
- if(aPipeBuilder->IsReady() == Standard_False) {
delete aPipeBuilder;
- return;
}
- if(!buildPipe(aPipeBuilder)) {
- delete aPipeBuilder;
+ if (!isDone) {
return;
}
+
this->initialize(aPipeBuilder);
// Checking result.
NCollection_List<TopoDS_Shape> anUngroupedShapes, aStillUngroupedShapes;
addSimpleShapeToList(anInShape, anUngroupedShapes);
- NCollection_Vector<NCollection_List<TopoDS_Shape>> aGroups;
- while(!anUngroupedShapes.IsEmpty()) {
- NCollection_List<TopoDS_Shape> aGroupedShapes;
- aGroupedShapes.Append(anUngroupedShapes.First());
- anUngroupedShapes.RemoveFirst();
- for(NCollection_List<TopoDS_Shape>::Iterator aGroupIt(aGroupedShapes);
+ // Iterate over all shapes and find shapes with shared vertices.
+ TopTools_ListOfShape aMapOrder;
+ BOPCol_DataMapOfShapeListOfShape aVertexShapesMap;
+ for(NCollection_List<TopoDS_Shape>::Iterator aShapesIt(anUngroupedShapes);
+ aShapesIt.More();
+ aShapesIt.Next()) {
+ const TopoDS_Shape& aShape = aShapesIt.Value();
+ for(TopExp_Explorer aShapeExp(aShape, TopAbs_VERTEX);
+ aShapeExp.More();
+ aShapeExp.Next()) {
+ const TopoDS_Shape& aVertex = aShapeExp.Current();
+ if (!aVertexShapesMap.IsBound(aVertex)) {
+ NCollection_List<TopoDS_Shape> aList;
+ aList.Append(aShape);
+ aMapOrder.Append(aVertex);
+ aVertexShapesMap.Bind(aVertex, aList);
+ } else {
+ if(!aVertexShapesMap.ChangeFind(aVertex).Contains(aShape)) {
+ aVertexShapesMap.ChangeFind(aVertex).Append(aShape);
+ }
+ }
+ }
+ }
+
+ // Iterate over the map and group shapes.
+ NCollection_Vector<TopTools_ListOfShape> aGroups;
+ while (!aMapOrder.IsEmpty()) {
+ // Get first group of shapes in map, and then unbind it.
+ const TopoDS_Shape& aKey = aMapOrder.First();
+ TopTools_ListOfShape aGroupedShapes = aVertexShapesMap.Find(aKey);
+ aVertexShapesMap.UnBind(aKey);
+ aMapOrder.Remove(aKey);
+ // Iterate over shapes in this group and add to it shapes from groups in map.
+ for(TopTools_ListOfShape::Iterator aGroupIt(aGroupedShapes);
aGroupIt.More(); aGroupIt.Next()) {
const TopoDS_Shape& aGroupedShape = aGroupIt.Value();
- for(TopExp_Explorer aGroupShapeExp(aGroupedShape, TopAbs_VERTEX);
- aGroupShapeExp.More();
- aGroupShapeExp.Next()) {
- // Find all shapes which have same vertex.
- aStillUngroupedShapes.Clear();
- const TopoDS_Shape& aVertex1 = aGroupShapeExp.Current();
- for(NCollection_List<TopoDS_Shape>::Iterator anUngroupedIt(anUngroupedShapes);
- anUngroupedIt.More();
- anUngroupedIt.Next()) {
- const TopoDS_Shape& anUngroupedShape = anUngroupedIt.Value();
- bool isAdded = false;
- for(TopExp_Explorer anUgroupedShapeExp(anUngroupedShape, TopAbs_VERTEX);
- anUgroupedShapeExp.More();
- anUgroupedShapeExp.Next()) {
- const TopoDS_Shape& aVertex2 = anUgroupedShapeExp.Current();
- if(aVertex1.IsSame(aVertex2)) {
- aGroupedShapes.Append(anUngroupedShape);
- isAdded = true;
- break;
- }
- }
- if(!isAdded) {
- aStillUngroupedShapes.Append(anUngroupedShape);
- }
+ TopTools_ListOfShape aKeysToUnbind;
+ for(TopTools_ListOfShape::Iterator aKeysIt(aMapOrder);
+ aKeysIt.More();
+ aKeysIt.Next()) {
+ const TopTools_ListOfShape& aGroupInMap = aVertexShapesMap(aKeysIt.Value());
+ if(!aGroupInMap.Contains(aGroupedShape)) {
+ // Group in map does not containt shape from our group, so go to the next group in map.
+ continue;
}
- anUngroupedShapes = aStillUngroupedShapes;
- if(anUngroupedShapes.IsEmpty()) {
- break;
+ // Iterate over shape in group in map, and add new shapes into our group.
+ for(TopTools_ListOfShape::Iterator aGroupInMapIt(aGroupInMap);
+ aGroupInMapIt.More();
+ aGroupInMapIt.Next()) {
+ const TopoDS_Shape& aShape = aGroupInMapIt.Value();
+ if (!aGroupedShapes.Contains(aShape)) {
+ aGroupedShapes.Append(aShape);
+ }
}
+ // Save key to unbind from this map.
+ aKeysToUnbind.Append(aKeysIt.Value());
}
- if(anUngroupedShapes.IsEmpty()) {
- break;
+ // Unbind groups from map that we added to our group.
+ for(TopTools_ListOfShape::Iterator aKeysIt(aKeysToUnbind);
+ aKeysIt.More();
+ aKeysIt.Next()) {
+ aVertexShapesMap.UnBind(aKeysIt.Value());
+ aMapOrder.Remove(aKeysIt.Value());
+ }
+ }
+ // Sort shapes.
+ TopTools_ListOfShape aSortedGroup;
+ for(int aST = TopAbs_COMPOUND; aST <= TopAbs_SHAPE; ++aST) {
+ TopTools_ListOfShape::Iterator anIt(aGroupedShapes);
+ while (anIt.More()) {
+ if(anIt.Value().ShapeType() == aST) {
+ aSortedGroup.Append(anIt.Value());
+ aGroupedShapes.Remove(anIt);
+ } else {
+ anIt.Next();
+ }
}
}
- aGroups.Append(aGroupedShapes);
+ aGroups.Append(aSortedGroup);
}
TopoDS_Compound aCompound;
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <GProp_GProps.hxx>
+#include <BRepGProp.hxx>
#include <list>
#include <cmath>
-
+#include <algorithm>
static TopoDS_Vertex findStartVertex(const TopoDS_Shape& theShape)
{
return findStartVertex(theShape);
}
+// returns true if the first shape must be located earlier than the second
+bool isFirst(const TopoDS_Shape& theFirst, const TopoDS_Shape& theSecond,
+ NCollection_DataMap<TopoDS_Shape, NCollection_Array1<int> >& theAreaToIndex,
+ const NCollection_DataMap<Handle(Geom_Curve), int>& theCurveToIndex)
+{
+ // fill theAreaToIndex for both shapes if needed
+ for(int aShapeNum = 1; aShapeNum <= 2; aShapeNum++) {
+ TopoDS_Shape aShape = aShapeNum == 1 ? theFirst : theSecond;
+ if (!theAreaToIndex.IsBound(aShape)) { // fill the list of curve indices
+ NCollection_List<int> aNewList;
+ TopExp_Explorer anEdgesExp(aShape, TopAbs_EDGE);
+ for(; anEdgesExp.More(); anEdgesExp.Next()) {
+ double aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(
+ TopoDS::Edge(anEdgesExp.Current()), aFirst, aLast);
+ if (aCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
+ aCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
+ if (theCurveToIndex.IsBound(aCurve)) {
+ aNewList.Append(theCurveToIndex.Find(aCurve));
+ }
+ }
+ NCollection_Array1<int> aNewArray(1, aNewList.Extent());
+ NCollection_List<int>::Iterator aListIter(aNewList);
+ for(int anIndex = 1; aListIter.More(); aListIter.Next(), anIndex++) {
+ aNewArray.SetValue(anIndex, aListIter.Value());
+ }
+ std::sort(aNewArray.begin(), aNewArray.end());
+ theAreaToIndex.Bind(aShape, aNewArray);
+ }
+ }
+ // compare lists of indices one by one to find chich list indices are lower
+ NCollection_Array1<int>::Iterator aFirstList(theAreaToIndex.ChangeFind(theFirst));
+ NCollection_Array1<int>::Iterator aSecondList(theAreaToIndex.ChangeFind(theSecond));
+ for(; aFirstList.More() && aSecondList.More(); aFirstList.Next(), aSecondList.Next()) {
+ if (aFirstList.Value() < aSecondList.Value()) return true;
+ if (aFirstList.Value() > aSecondList.Value()) return false;
+ }
+ // if faces are identical by curves names (circle splitted by line in seam-point), use parameters
+ if (!aFirstList.More() && !aSecondList.More()) {
+ GProp_GProps aGProps;
+ BRepGProp::SurfaceProperties(theFirst, aGProps);
+ gp_Pnt aCentre1 = aGProps.CentreOfMass();
+ BRepGProp::SurfaceProperties(theSecond, aGProps);
+ gp_Pnt aCentre2 = aGProps.CentreOfMass();
+ return aCentre1.X() + aCentre1.Y() + aCentre1.Z() < aCentre2.X() + aCentre2.Y() + aCentre2.Z();
+ }
+ // if in first list there is no elements left, it is the first
+ return !aFirstList.More();
+}
+
+// sorts faces (in theAreas list) to make persistent order: by initial shapes edges
+static void sortFaces(TopTools_ListOfShape& theAreas,
+ const std::list<std::shared_ptr<GeomAPI_Shape> >& theInitialShapes)
+{
+ // collect indices of all edges to operate them quickly
+ NCollection_DataMap<Handle(Geom_Curve), int> aCurveToIndex; // curve -> index in initial shapes
+ std::list<std::shared_ptr<GeomAPI_Shape> >::const_iterator aFeatIt = theInitialShapes.begin();
+ for (int anIndex = 0; aFeatIt != theInitialShapes.end(); aFeatIt++) {
+ std::shared_ptr<GeomAPI_Shape> aShape(*aFeatIt);
+ const TopoDS_Edge& anEdge = aShape->impl<TopoDS_Edge>();
+ if (anEdge.ShapeType() != TopAbs_EDGE)
+ continue;
+
+ double aFirst, aLast;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
+ if (aCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
+ aCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve)->BasisCurve();
+ if (!aCurveToIndex.IsBound(aCurve))
+ aCurveToIndex.Bind(aCurve, anIndex++);
+ }
+ // map from area to the most first indices of curves (to compare) in it
+ NCollection_DataMap<TopoDS_Shape, NCollection_Array1<int> > anAreaToIndex;
+ // sort areas
+ TopTools_ListOfShape::Iterator anArea1(theAreas);
+ for(; anArea1.More(); anArea1.Next()) {
+ TopTools_ListOfShape::Iterator anArea2 = anArea1;
+ for(anArea2.Next(); anArea2.More(); anArea2.Next()) {
+ if (!isFirst(anArea1.Value(), anArea2.Value(), anAreaToIndex, aCurveToIndex)) { // exchange
+ TopoDS_Shape aTmp = anArea1.Value();
+ anArea1.ChangeValue() = anArea2.Value();
+ anArea2.ChangeValue() = aTmp;
+ }
+ }
+ }
+}
+
void GeomAlgoAPI_SketchBuilder::createFaces(
const std::shared_ptr<GeomAPI_Pnt>& theOrigin,
const std::shared_ptr<GeomAPI_Dir>& theDirX,
return;
// Collect faces
- const TopTools_ListOfShape& anAreas = aBB.Modified(aPlnFace);
+ TopTools_ListOfShape anAreas = aBB.Modified(aPlnFace);
+ sortFaces(anAreas, theFeatures); // sort faces by the edges in them
TopTools_ListIteratorOfListOfShape anIt(anAreas);
for (; anIt.More(); anIt.Next()) {
TopoDS_Face aFace = TopoDS::Face(anIt.Value());
double aMinValue = 1.e-5;
if(theArguments.size() == 1) {
std::list<std::string>::const_iterator anIt = theArguments.begin();
- char *aErr;
double aValue = Config_PropManager::stringToDouble((*anIt).c_str());
if(aValue != 0) {
// very probably ok
}
//=======================================================================
-bool Model_Application::isLoadByDemand(std::string theID)
+bool Model_Application::isLoadByDemand(std::string theID, const int theDocIndex)
{
- return myLoadedByDemand.find(theID) != myLoadedByDemand.end();
+ return myLoadedByDemand.find(theID) != myLoadedByDemand.end() &&
+ myLoadedByDemand[theID] == theDocIndex;
}
//=======================================================================
//! Defines that specified document must be loaded by demand
void setLoadByDemand(std::string theID, const int theDocID);
//! Returns true if specified document must be loaded by demand
- bool isLoadByDemand(std::string theID);
+ bool isLoadByDemand(std::string theID, const int theDocIndex);
//! Closes and removes the documents that are not loaded by demand and
//! not in the given list
void removeUselessDocuments(std::list<std::shared_ptr<ModelAPI_Document> > theUsedDocs);
#include <TDataStd_UAttribute.hxx>
#include <TDataStd_Name.hxx>
#include <TopTools_ListOfShape.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
+#include <TopTools_MapOfShape.hxx>
#include <TopExp_Explorer.hxx>
#include <BRep_Tool.hxx>
#include <TopoDS.hxx>
#include <TDF_ChildIterator.hxx>
#include <TDF_ChildIDIterator.hxx>
#include <TopoDS_Iterator.hxx>
+#include <TDF_ChildIDIterator.hxx>
#include <Geom_Circle.hxx>
#include <Geom_Ellipse.hxx>
#include <BRep_Builder.hxx>
if (aSelLab.IsAttribute(kPART_REF_ID)) {
ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(context());
if (!aPart.get() || !aPart->isActivated())
- return aResult; // postponed naming needed
+ return std::shared_ptr<GeomAPI_Shape>(); // postponed naming needed
Handle(TDataStd_Integer) anIndex;
if (aSelLab.FindAttribute(TDataStd_Integer::GetID(), anIndex)) {
if (anIndex->Get()) { // special selection attribute was created, use it
if (aPartEnd != std::string::npos && aPartEnd != aSubShapeName.rfind('/')) {
std::string aNameInPart = aSubShapeName.substr(aPartEnd + 1);
int anIndex;
- std::string aTypeStr; // to reuse already existing selection the type is not needed
- return aPart->shapeInPart(aNameInPart, aTypeStr, anIndex);
+ std::string aType; // to reuse already existing selection the type is not needed
+ return aPart->shapeInPart(aNameInPart, aType, anIndex);
}
}
}
TopoDS_Shape aSelShape = aSelection->Get();
aResult = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape);
aResult->setImpl(new TopoDS_Shape(aSelShape));
- return aResult;
} else { // for simple construction element: just shape of this construction element
std::shared_ptr<Model_ResultConstruction> aConstr =
std::dynamic_pointer_cast<Model_ResultConstruction>(context());
}
}
}
- return aResult; // empty case
+ return aResult;
}
bool Model_AttributeSelection::isInvalid()
Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(aConShape, selectionLabel());
if (!aNS.IsNull()) {
aNS = TNaming_Tool::CurrentNamedShape(aNS);
- if (!aNS.IsNull()) {
+ if (!aNS.IsNull() && scope().Contains(aNS->Label())) { // scope check is for 2228
TDF_Label aLab = aNS->Label();
while(aLab.Depth() != 7 && aLab.Depth() > 5)
aLab = aLab.Father();
return aResult;
}
+void Model_AttributeSelection::computeValues(
+ ResultPtr theOldContext, ResultPtr theNewContext, TopoDS_Shape theValShape,
+ TopTools_ListOfShape& theShapes)
+{
+ bool aWasWholeContext = theValShape.IsNull();
+ if (aWasWholeContext) {
+ //theShapes.Append(theValShape);
+ //return;
+ theValShape = theOldContext->shape()->impl<TopoDS_Shape>();
+ }
+ //TopoDS_Shape anOldContShape = theOldContext->shape()->impl<TopoDS_Shape>();
+ TopoDS_Shape aNewContShape = theNewContext->shape()->impl<TopoDS_Shape>();
+ //if (anOldContShape.IsSame(theValShape)) { // full context shape substituted by new full context
+ //theShapes.Append(aNewContShape);
+ //return;
+ //}
+ // if a new value is unchanged in the new context, do nothing: value is correct
+ TopExp_Explorer aSubExp(aNewContShape, theValShape.ShapeType());
+ for(; aSubExp.More(); aSubExp.Next()) {
+ if (aSubExp.Current().IsSame(theValShape)) {
+ theShapes.Append(theValShape);
+ return;
+ }
+ }
+ // if new context becomes compsolid, the resulting sub may be in sub-solids
+ std::list<ResultPtr> aNewToIterate;
+ aNewToIterate.push_back(theNewContext);
+ ResultCompSolidPtr aComp = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(theNewContext);
+ if (aComp.get()) {
+ for(int a = 0; a < aComp->numberOfSubs(); a++)
+ aNewToIterate.push_back(aComp->subResult(a, false));
+ }
+
+ // first iteration: searching for the whole shape appearance (like face of the box)
+ // second iteration: searching for sub-shapes that contain the sub (like vertex on faces)
+ int aToFindPart = 0;
+ TopTools_DataMapOfShapeShape aNewToOld; // map from new containers to old containers (with val)
+ TopTools_MapOfShape anOlds; // to know how many olds produced new containers
+ for(; aToFindPart != 2 && theShapes.IsEmpty(); aToFindPart++) {
+ std::list<ResultPtr>::iterator aNewContIter = aNewToIterate.begin();
+ for(; aNewContIter != aNewToIterate.end(); aNewContIter++) {
+ std::shared_ptr<Model_Data> aNewData =
+ std::dynamic_pointer_cast<Model_Data>((*aNewContIter)->data());
+ TDF_Label aNewLab = aNewData->label();
+ // searching for produced sub-shape fully on some label
+ TDF_ChildIDIterator aNSIter(aNewLab, TNaming_NamedShape::GetID(), Standard_True);
+ for(; aNSIter.More(); aNSIter.Next()) {
+ Handle(TNaming_NamedShape) aNS = Handle(TNaming_NamedShape)::DownCast(aNSIter.Value());
+ for(TNaming_Iterator aPairIter(aNS); aPairIter.More(); aPairIter.Next()) {
+ if (aToFindPart == 0) { // search shape is fully inside
+ if (aPairIter.OldShape().IsSame(theValShape)) {
+ if (aPairIter.NewShape().IsNull()) {// value was removed
+ theShapes.Clear();
+ return;
+ }
+ theShapes.Append(aPairIter.NewShape());
+ }
+ } else if (!aPairIter.OldShape().IsNull()) { // search shape that contains this sub
+ TopExp_Explorer anExp(aPairIter.OldShape(), theValShape.ShapeType());
+ for(; anExp.More(); anExp.Next()) {
+ if (anExp.Current().IsSame(theValShape)) { // found a new container
+ if (aPairIter.NewShape().IsNull()) {// value was removed
+ theShapes.Clear();
+ return;
+ }
+ aNewToOld.Bind(aPairIter.NewShape(), aPairIter.OldShape());
+ anOlds.Add(aPairIter.OldShape());
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (aToFindPart == 2 && !aNewToOld.IsEmpty()) {
+ // map of sub-shapes -> number of occurences of these shapes in containers
+ NCollection_DataMap<TopoDS_Shape, TopTools_MapOfShape, TopTools_ShapeMapHasher> aSubs;
+ TopTools_DataMapOfShapeShape::Iterator aContIter(aNewToOld);
+ for(; aContIter.More(); aContIter.Next()) {
+ TopExp_Explorer aSubExp(aContIter.Key(), theValShape.ShapeType());
+ for(; aSubExp.More(); aSubExp.Next()) {
+ if (!aSubs.IsBound(aSubExp.Current())) {
+ aSubs.Bind(aSubExp.Current(), TopTools_MapOfShape());
+ }
+ // store old to know how many olds produced this shape
+ aSubs.ChangeFind(aSubExp.Current()).Add(aContIter.Value());
+ }
+ }
+ // if sub is appeared same times in containers as the number of old shapes that contain it
+ int aCountInOld = anOlds.Size();
+ NCollection_DataMap<TopoDS_Shape, TopTools_MapOfShape, TopTools_ShapeMapHasher>::Iterator
+ aSubsIter(aSubs);
+ for(; aSubsIter.More(); aSubsIter.Next()) {
+ if (aSubsIter.Value().Size() == aCountInOld) {
+ theShapes.Append(aSubsIter.Key());
+ }
+ }
+ }
+ if (theShapes.IsEmpty()) { // nothing was changed
+ theShapes.Append(aWasWholeContext ? TopoDS_Shape() : theValShape);
+ }
+}
+
+bool Model_AttributeSelection::searchNewContext(std::shared_ptr<Model_Document> theDoc,
+ const TopoDS_Shape theContShape, ResultPtr theContext, TopoDS_Shape theValShape,
+ TDF_Label theAccessLabel,
+ std::list<ResultPtr>& theResults, TopTools_ListOfShape& theValShapes)
+{
+ std::set<ResultPtr> aResults; // to avoid duplicates, new context, null if deleted
+ TopTools_ListOfShape aResContShapes;
+ TNaming_SameShapeIterator aModifIter(theContShape, theAccessLabel);
+ for(; aModifIter.More(); aModifIter.Next()) {
+ TDF_Label anObjLab = aModifIter.Label().Father();
+ ResultPtr aModifierObj = std::dynamic_pointer_cast<ModelAPI_Result>
+ (theDoc->objects()->object(anObjLab));
+ if (!aModifierObj.get()) {
+ // #2241: shape may be sub-element of new object, not main (shell created from faces)
+ if (!anObjLab.IsRoot())
+ aModifierObj = std::dynamic_pointer_cast<ModelAPI_Result>
+ (theDoc->objects()->object(anObjLab.Father()));
+ if (!aModifierObj.get())
+ continue;
+ }
+ FeaturePtr aModifierFeat = theDoc->feature(aModifierObj);
+ if (!aModifierFeat.get())
+ continue;
+ FeaturePtr aThisFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
+ if (aModifierFeat == aThisFeature || theDoc->objects()->isLater(aModifierFeat, aThisFeature))
+ continue; // the modifier feature is later than this, so, should not be used
+ FeaturePtr aCurrentModifierFeat = theDoc->feature(theContext);
+ if (aCurrentModifierFeat == aModifierFeat ||
+ theDoc->objects()->isLater(aCurrentModifierFeat, aModifierFeat))
+ continue; // the current modifier is later than the found, so, useless
+ Handle(TNaming_NamedShape) aNewNS;
+ aModifIter.Label().FindAttribute(TNaming_NamedShape::GetID(), aNewNS);
+ if (aNewNS->Evolution() == TNaming_MODIFY || aNewNS->Evolution() == TNaming_GENERATED) {
+ aResults.insert(aModifierObj);
+ //TNaming_Iterator aPairIter(aNewNS);
+ //aResContShapes.Append(aPairIter.NewShape());
+ aResContShapes.Append(aModifierObj->shape()->impl<TopoDS_Shape>());
+ } else if (aNewNS->Evolution() == TNaming_DELETE) { // a shape was deleted => result is empty
+ aResults.insert(ResultPtr());
+ } else { // not-precessed modification => don't support it
+ continue;
+ }
+ }
+ if (aResults.empty())
+ return false; // no modifications found, must stay the same
+ // iterate all results to find futher modifications
+ std::set<ResultPtr>::iterator aResIter = aResults.begin();
+ for(; aResIter != aResults.end(); aResIter++) {
+ if (aResIter->get() != NULL) {
+ // compute new values by two contextes: the old and the new
+ TopTools_ListOfShape aValShapes;
+ computeValues(theContext, *aResIter, theValShape, aValShapes);
+
+ TopTools_ListIteratorOfListOfShape aNewVal(aValShapes);
+ for(; aNewVal.More(); aNewVal.Next()) {
+ std::list<ResultPtr> aNewRes;
+ TopTools_ListOfShape aNewUpdatedVal;
+ TopoDS_Shape aNewValSh = aNewVal.Value();
+ TopoDS_Shape aNewContShape = (*aResIter)->shape()->impl<TopoDS_Shape>();
+ if (theValShape.IsNull() && aNewContShape.IsSame(aNewValSh))
+ aNewValSh.Nullify();
+ if (searchNewContext(theDoc, aNewContShape, *aResIter, aNewValSh,
+ theAccessLabel, aNewRes, aNewUpdatedVal))
+ {
+ // appeand new results instead of the current ones
+ std::list<ResultPtr>::iterator aNewIter = aNewRes.begin();
+ TopTools_ListIteratorOfListOfShape aNewUpdVal(aNewUpdatedVal);
+ for(; aNewIter != aNewRes.end(); aNewIter++, aNewUpdVal.Next()) {
+ theResults.push_back(*aNewIter);
+ theValShapes.Append(aNewUpdVal.Value());
+ }
+ } else { // the current result is good
+ theResults.push_back(*aResIter);
+ theValShapes.Append(aNewValSh);
+ }
+ }
+ }
+ }
+ return true; // theResults must be empty: everything is deleted
+}
+
void Model_AttributeSelection::updateInHistory()
{
ResultPtr aContext = std::dynamic_pointer_cast<ModelAPI_Result>(myRef.value());
- // only bodies may be modified later in the history, don't do anything otherwise
- if (!aContext.get() || aContext->groupName() != ModelAPI_ResultBody::group())
+ // only bodies and parts may be modified later in the history, don't do anything otherwise
+ if (!aContext.get() || (aContext->groupName() != ModelAPI_ResultBody::group() &&
+ aContext->groupName() != ModelAPI_ResultPart::group()))
return;
+ std::shared_ptr<Model_Document> aDoc =
+ std::dynamic_pointer_cast<Model_Document>(aContext->document());
std::shared_ptr<Model_Data> aContData = std::dynamic_pointer_cast<Model_Data>(aContext->data());
if (!aContData.get() || !aContData->isValid())
return;
TDF_Label aContLab = aContData->label(); // named shape where the selected context is located
Handle(TNaming_NamedShape) aContNS;
- if (!aContLab.FindAttribute(TNaming_NamedShape::GetID(), aContNS))
+ if (!aContLab.FindAttribute(TNaming_NamedShape::GetID(), aContNS)) {
+ bool aFoundNewContext = true;
+ ResultPtr aNewContext = aContext;
+ while(aFoundNewContext) {
+ aFoundNewContext = false;
+ // parts have no shape in result, so, trace references using the Part info
+ if (aNewContext->groupName() == ModelAPI_ResultPart::group()) {
+ ResultPartPtr aPartContext = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aNewContext);
+ if (aPartContext.get()) { // searching for the up to date references to the referenced cont
+ const std::set<AttributePtr>& aRefs = aPartContext->data()->refsToMe();
+ std::set<AttributePtr>::const_iterator aRef = aRefs.begin();
+ for(; aRef != aRefs.end(); aRef++) {
+ // to avoid detection of part changes by local selection only
+ AttributeSelectionPtr aSel =
+ std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*aRef);
+ if (aSel.get() && !aSel->value()->isSame(aSel->context()->shape()))
+ continue;
+
+ FeaturePtr aRefFeat = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRef)->owner());
+ if (aRefFeat.get() && aRefFeat != owner()) {
+ FeaturePtr aThisFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
+ if (aDoc->objects()->isLater(aThisFeature, aRefFeat)) { // found better feature
+ aFoundNewContext = true;
+ aNewContext = aRefFeat->firstResult();
+ }
+ }
+ }
+ }
+ }
+ }
+ if (aNewContext != aContext) {
+ setValue(aNewContext, value());
+ }
return;
- std::shared_ptr<Model_Document> aDoc =
- std::dynamic_pointer_cast<Model_Document>(aContext->document());
+ }
FeaturePtr aThisFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(owner());
FeaturePtr aCurrentModifierFeat = aDoc->feature(aContext);
// iterate the context shape modifications in order to find a feature that is upper in history
TNaming_Iterator aPairIter(aContNS);
if (!aPairIter.More())
return;
- TopoDS_Shape aNewShape = aPairIter.NewShape();
+ TopoDS_Shape aNewCShape = aPairIter.NewShape();
bool anIterate = true;
// trying to update also the sub-shape selected
GeomShapePtr aSubShape = value();
if (aSubShape.get() && aSubShape->isEqual(aContext->shape()))
aSubShape.reset();
-
- while(anIterate) {
- anIterate = false;
- TNaming_SameShapeIterator aModifIter(aNewShape, aContLab);
- for(; aModifIter.More(); aModifIter.Next()) {
- ResultPtr aModifierObj = std::dynamic_pointer_cast<ModelAPI_Result>
- (aDoc->objects()->object(aModifIter.Label().Father()));
- if (!aModifierObj.get())
- break;
- FeaturePtr aModifierFeat = aDoc->feature(aModifierObj);
- if (!aModifierFeat.get())
- break;
- if (aModifierFeat == aThisFeature || aDoc->objects()->isLater(aModifierFeat, aThisFeature))
- continue; // the modifier feature is later than this, so, should not be used
- if (aCurrentModifierFeat == aModifierFeat ||
- aDoc->objects()->isLater(aCurrentModifierFeat, aModifierFeat))
- continue; // the current modifier is later than the found, so, useless
- Handle(TNaming_NamedShape) aNewNS;
- aModifIter.Label().FindAttribute(TNaming_NamedShape::GetID(), aNewNS);
- if (aNewNS->Evolution() == TNaming_MODIFY || aNewNS->Evolution() == TNaming_GENERATED) {
- aModifierResFound = aModifierObj;
- aCurrentModifierFeat = aModifierFeat;
- TNaming_Iterator aPairIter(aNewNS);
- aNewShape = aPairIter.NewShape();
- anIterate = true;
- break;
- } else if (aNewNS->Evolution() == TNaming_DELETE) { // a shape was deleted => result is null
- ResultPtr anEmptyContext;
- std::shared_ptr<GeomAPI_Shape> anEmptyShape;
- setValue(anEmptyContext, anEmptyShape); // nullify the selection
- return;
- } else { // not-precessed modification => don't support it
- continue;
- }
- }
+ TopoDS_Shape aValShape;
+ if (aSubShape.get()) {
+ aValShape = aSubShape->impl<TopoDS_Shape>();
}
- if (aModifierResFound.get()) {
+
+ std::list<ResultPtr> aNewContexts;
+ TopTools_ListOfShape aValShapes;
+ if (searchNewContext(aDoc, aNewCShape, aContext, aValShape, aContLab, aNewContexts, aValShapes))
+ {
// update scope to reset to a new one
myScope.Clear();
- myRef.setValue(aModifierResFound);
- // if context shape type is changed to more complicated and this context is selected, split
- if (myParent &&!aSubShape.get() && aModifierResFound->shape().get() && aContext->shape().get())
- {
- TopoDS_Shape anOldShape = aContext->shape()->impl<TopoDS_Shape>();
- TopoDS_Shape aNewShape = aModifierResFound->shape()->impl<TopoDS_Shape>();
- if (!anOldShape.IsNull() && !aNewShape.IsNull() &&
- anOldShape.ShapeType() != aNewShape.ShapeType() &&
- (aNewShape.ShapeType() == TopAbs_COMPOUND || aNewShape.ShapeType() == TopAbs_COMPSOLID)) {
- // prepare for split in "update"
- TDF_Label aSelLab = selectionLabel();
- split(aContext, aNewShape, anOldShape.ShapeType());
+
+ std::list<ResultPtr>::iterator aNewCont = aNewContexts.begin();
+ TopTools_ListIteratorOfListOfShape aNewValues(aValShapes);
+ if (aNewCont == aNewContexts.end()) { // all results were deleted
+ ResultPtr anEmptyContext;
+ std::shared_ptr<GeomAPI_Shape> anEmptyShape;
+ setValue(anEmptyContext, anEmptyShape); // nullify the selection
+ return;
+ }
+
+ GeomShapePtr aValueShape;
+ if (!aNewValues.Value().IsNull()) {
+ aValueShape = std::make_shared<GeomAPI_Shape>();
+ aValueShape->setImpl<TopoDS_Shape>(new TopoDS_Shape(aNewValues.Value()));
+ }
+ setValue(*aNewCont, aValueShape);
+ // if there are more than one result, put them by "append" into "parent" list
+ if (myParent) {
+ for(aNewCont++, aNewValues.Next(); aNewCont != aNewContexts.end();
+ aNewCont++, aNewValues.Next()) {
+ GeomShapePtr aValueShape;
+ if (!aNewValues.Value().IsNull()) {
+ aValueShape = std::make_shared<GeomAPI_Shape>();
+ aValueShape->setImpl<TopoDS_Shape>(new TopoDS_Shape(aNewValues.Value()));
+ }
+ myParent->append(*aNewCont, aValueShape);
}
}
- update(); // it must recompute a new sub-shape automatically
}
}
#include <ModelAPI_AttributeSelection.h>
#include <TDF_LabelMap.hxx>
#include <TopoDS_Shape.hxx>
+#include <TopTools_ListOfShape.hxx>
class Model_AttributeSelectionList;
+class Model_Document;
/**\class Model_AttributeSelection
* \ingroup DataModel
/// Splits theNewShape into sub-shapes of theType type (for the list parent of this attribute)
void split(ResultPtr theContext, TopoDS_Shape theNewShape, TopAbs_ShapeEnum theType);
+ /// When group position is updated, searches the new context and new values
+ bool searchNewContext(std::shared_ptr<Model_Document> theDoc, const TopoDS_Shape theContShape,
+ ResultPtr theContext, TopoDS_Shape theValShape, TDF_Label theAccessLabel,
+ std::list<ResultPtr>& theResults, TopTools_ListOfShape& theValShapes);
+
+ /// computes theShapes list - shapes that were generated/modified/deleted the theValShape
+ /// during creation from new to old context
+ void computeValues(ResultPtr theOldContext, ResultPtr theNewContext, TopoDS_Shape theValShape,
+ TopTools_ListOfShape& theShapes);
+
friend class Model_Data;
friend class Model_AttributeSelectionList;
};
std::list<std::shared_ptr<GeomAPI_Shape> >::iterator aShapes = aContext->second.begin();
for(; aShapes != aContext->second.end(); aShapes++) {
if (!theSubShape.get()) {
- if (!aShapes->get())
+ if (!aShapes->get() || (*aShapes)->isSame(aContext->first->shape()))
return true;
} else {
// we need to call here isSame instead of isEqual to do not check shapes orientation
if (anAttr.get()) {
if (anAttr->context() == theContext) { // contexts are equal, so, check that values are also
std::shared_ptr<GeomAPI_Shape> aValue = anAttr->value();
- if (!aValue.get()) {
- if (!theSubShape.get()) { // both are null
+ if (!theSubShape.get()) {
+ if (!aValue.get() || aValue->isSame(theContext->shape())) { // both are null
return true;
}
} else {
// we need to call here isSame instead of isEqual to do not check shapes orientation
- if (aValue->isSame(theSubShape)) // shapes are equal
+ if (theSubShape->isSame(aValue)) // shapes are equal
return true;
}
}
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
#include <TDF_ChildIterator.hxx>
+#include <TDF_ChildIDIterator.hxx>
#include <TDF_Reference.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopExp_Explorer.hxx>
void Model_BodyBuilder::clean()
{
- std::vector<TNaming_Builder*>::iterator aBuilder = myBuilders.begin();
- for(; aBuilder != myBuilders.end(); aBuilder++)
- delete *aBuilder;
+ TDF_Label aLab = std::dynamic_pointer_cast<Model_Data>(data())->shapeLab();
+ if (aLab.IsNull())
+ return;
+ std::map<int, TNaming_Builder*>::iterator aBuilder = myBuilders.begin();
+ for(; aBuilder != myBuilders.end(); aBuilder++) {
+ delete aBuilder->second;
+ // clear also shapes on cleaned sub-labels (#2241)
+ Handle(TNaming_NamedShape) aNS;
+ if (aLab.FindChild(aBuilder->first).FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
+ aNS->Clear();
+ }
+ }
myBuilders.clear();
}
TNaming_Builder* Model_BodyBuilder::builder(const int theTag)
{
- if (myBuilders.size() <= (unsigned int)theTag) {
- myBuilders.insert(myBuilders.end(), theTag - myBuilders.size() + 1, NULL);
- }
- if (!myBuilders[theTag]) {
+ std::map<int, TNaming_Builder*>::iterator aFind = myBuilders.find(theTag);
+ if (aFind == myBuilders.end()) {
std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
myBuilders[theTag] = new TNaming_Builder(aData->shapeLab().FindChild(theTag));
- //TCollection_AsciiString entry;//
- //TDF_Tool::Entry(aData->shapeLab().FindChild(theTag), entry);
- //cout << "Label = " <<entry.ToCString() <<endl;
+ aFind = myBuilders.find(theTag);
}
- return myBuilders[theTag];
+ return aFind->second;
}
void Model_BodyBuilder::buildName(const int theTag, const std::string& theName)
for (; aShapeExplorer.More(); aShapeExplorer.Next ()) {
const TopoDS_Shape& aRoot = aShapeExplorer.Current ();
if (!aView.Add(aRoot)) continue;
+ if (TNaming_Tool::NamedShape(aRoot, builder(theTag)->NamedShape()->Label()).IsNull())
+ continue; // there is no sence to write history is old shape does not persented in document
ListOfShape aList;
std::shared_ptr<GeomAPI_Shape> aRShape(new GeomAPI_Shape());
aRShape->setImpl((new TopoDS_Shape(aRoot)));
for (; aShapeExplorer.More(); aShapeExplorer.Next ()) {
const TopoDS_Shape& aRoot = aShapeExplorer.Current ();
if (!aView.Add(aRoot)) continue;
+ if (TNaming_Tool::NamedShape(aRoot, builder(theTag)->NamedShape()->Label()).IsNull())
+ continue; // there is no sence to write history is old shape does not persented in document
ListOfShape aList;
std::shared_ptr<GeomAPI_Shape> aRShape(new GeomAPI_Shape());
aRShape->setImpl((new TopoDS_Shape(aRoot)));
*/
class Model_BodyBuilder : public ModelAPI_BodyBuilder
{
- /// builders that tores the naming history: one per label to allow store several shapes to one
+ /// builders that store the naming history: one per label to allow store several shapes to one
/// label; index in vector corresponds to the label tag
- std::vector<TNaming_Builder*> myBuilders;
+ std::map<int, TNaming_Builder*> myBuilders;
public:
/// Stores the shape (called by the execution method).
MODEL_EXPORT virtual void store(const std::shared_ptr<GeomAPI_Shape>& theShape,
if (theAttr->isArgument()) {
if (mySendAttributeUpdated) {
if (myObject) {
- myObject->attributeChanged(theAttr->id());
+ try {
+ myObject->attributeChanged(theAttr->id());
+ } catch(...) {
+ if (owner().get() && owner()->data().get() && owner()->data()->isValid()) {
+ Events_InfoMessage("Model_Data",
+ "%1 has failed during the update").arg(owner()->data()->name()).send();
+ }
+ }
static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
ModelAPI_EventCreator::get()->sendUpdated(myObject, anEvent);
}
myWasChangedButBlocked.clear();
std::list<ModelAPI_Attribute*>::iterator aChangedIter = aWasChangedButBlocked.begin();
for(; aChangedIter != aWasChangedButBlocked.end(); aChangedIter++) {
- myObject->attributeChanged((*aChangedIter)->id());
+ try {
+ myObject->attributeChanged((*aChangedIter)->id());
+ } catch(...) {
+ if (owner().get() && owner()->data().get() && owner()->data()->isValid()) {
+ Events_InfoMessage("Model_Data",
+ "%1 has failed during the update").arg(owner()->data()->name()).send();
+ }
+ }
}
static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
ModelAPI_EventCreator::get()->sendUpdated(myObject, anEvent);
// If not found child label with the exact sub-name, then try to find compound with
// such sub-name without suffix.
Standard_Integer aSuffixPos = aSubName.SearchFromEnd('_');
- if (aSuffixPos != -1) {
+ if (aSuffixPos != -1 && aSuffixPos != aSubName.Length()) {
TCollection_ExtendedString anIndexStr = aSubName.Split(aSuffixPos);
aSubName.Remove(aSuffixPos);
aNamesIter.Initialize(aFind->second, TDataStd_Name::GetID(), Standard_True);
//! Sets the current feature: all features below will be disabled, new features
//! will be appended after this one.
- //! \param theCurrent the selected feature as current: blow it everythin become disabled
+ //! \param theCurrent the selected feature as current: below it everything becomes disabled
//! \param theVisible use visible features only: flag is true for Object Browser functionality
MODEL_EXPORT virtual void setCurrentFeature(std::shared_ptr<ModelAPI_Feature> theCurrent,
const bool theVisible);
updateSubs(theNewShape);
}
+void Model_ResultCompSolid::loadAndOrientModifiedShapes(GeomAlgoAPI_MakeShape* theMS,
+ std::shared_ptr<GeomAPI_Shape> theShapeIn, const int theKindOfShape, const int theTag,
+ const std::string& theName, GeomAPI_DataMapOfShapeShape& theSubShapes,
+ const bool theIsStoreSeparate,
+ const bool theIsStoreAsGenerated,
+ const bool theSplitInSubs)
+{
+ if (theSplitInSubs && mySubs.size()) { // consists of subs
+ std::vector<std::shared_ptr<ModelAPI_ResultBody> >::const_iterator aSubIter = mySubs.cbegin();
+ for(; aSubIter != mySubs.cend(); aSubIter++) {
+ (*aSubIter)->loadAndOrientModifiedShapes(
+ theMS, theShapeIn, theKindOfShape, theTag, theName, theSubShapes, theIsStoreSeparate,
+ theIsStoreAsGenerated);
+ }
+ } else { // do for this directly
+ ModelAPI_ResultCompSolid::loadAndOrientModifiedShapes(
+ theMS, theShapeIn, theKindOfShape, theTag, theName, theSubShapes, theIsStoreSeparate,
+ theIsStoreAsGenerated);
+ }
+}
+
+
int Model_ResultCompSolid::numberOfSubs(bool forTree) const
{
return int(mySubs.size());
} else if (!mySubs.empty()) { // erase all subs
while(!mySubs.empty()) {
ResultBodyPtr anErased = *(mySubs.rbegin());
- anErased->setDisabled(anErased, true);
+ if (anErased->data()->isValid())
+ anErased->setDisabled(anErased, true);
mySubs.pop_back();
}
// redisplay this because result with and without subs are displayed differently
MODEL_EXPORT virtual void storeModified(const std::shared_ptr<GeomAPI_Shape>& theOldShape,
const std::shared_ptr<GeomAPI_Shape>& theNewShape, const int theDecomposeSolidsTag = 0);
+ /// load and orient modified shapes for sub-objects
+ MODEL_EXPORT virtual void loadAndOrientModifiedShapes (GeomAlgoAPI_MakeShape* theMS,
+ std::shared_ptr<GeomAPI_Shape> theShapeIn, const int theKindOfShape, const int theTag,
+ const std::string& theName, GeomAPI_DataMapOfShapeShape& theSubShapes,
+ const bool theIsStoreSeparate = false,
+ const bool theIsStoreAsGenerated = false,
+ const bool theSplitInSubs = false);
+
+
/// Returns the number of sub-elements
MODEL_EXPORT virtual int numberOfSubs(bool forTree = false) const;
// iterate and store the result ids of sub-elements and sub-elements to sub-labels
Handle(TDataStd_IntPackedMap) aRefs = TDataStd_IntPackedMap::Set(aLab);
const int aSubNum = aComposite->numberOfSubs();
+ // subs are placed one by one because of #2248): sketch curve may produce several edges
+ int aSubLabId = 1;
+
for(int a = 0; a < aSubNum; a++) {
FeaturePtr aSub = aComposite->subFeature(a);
const std::list<std::shared_ptr<ModelAPI_Result> >& aResults = aSub->results();
Handle(Geom_Curve) aFaceCurve = BRep_Tool::Curve(anEdge, aFirst, aLast);
if (aFaceCurve == aCurve) {
TDF_Label aSubLab = aLab.FindChild(anID);
+ TDF_Label aShapeSubLab = aLab.FindChild(aSubLabId++);
std::string aFullNameSub = fullName(aComposite, anEdge);
- saveSubName(aSubLab, isSelectionMode, anEdge, aMyDoc, aFullNameSub);
+ saveSubName(aShapeSubLab, isSelectionMode, anEdge, aMyDoc, aFullNameSub);
int anOrient = Model_SelectionNaming::edgeOrientation(aSubShape, anEdge);
if (anOrient != 0) {
}
} else { // put vertices of the selected edge to sub-labels
// add edges to sub-label to support naming for edges selection
- int aTagIndex = anID + kSTART_VERTEX_DELTA;
for(TopExp_Explorer anEdgeExp(aSubShape, TopAbs_VERTEX);
- anEdgeExp.More();
- anEdgeExp.Next(), aTagIndex += kSTART_VERTEX_DELTA) {
+ anEdgeExp.More(); anEdgeExp.Next()) {
TopoDS_Vertex aV = TopoDS::Vertex(anEdgeExp.Current());
- TDF_Label aSubLab = aLab.FindChild(aTagIndex);
+ TDF_Label aShapeSubLab = aLab.FindChild(aSubLabId++);
std::string aFullNameSub = fullName(aComposite, aV);
- saveSubName(aSubLab, isSelectionMode, aV, aMyDoc, aFullNameSub);
+ saveSubName(aShapeSubLab, isSelectionMode, aV, aMyDoc, aFullNameSub);
}
}
}
std::shared_ptr<ModelAPI_Document> Model_ResultPart::partDoc()
{
- if (myTrsf.get() && baseRef().get()) { // the second condition is to to #2035
+ if (myTrsf.get() && baseRef().get()) { // the second condition is due to #2035
return baseRef()->partDoc();
}
DocumentPtr aRes = data()->document(DOC_REF())->value();
}
if (!aDocRef->value().get()) { // create (or open) a document if it is not yet created
Handle(Model_Application) anApp = Model_Application::getApplication();
- if (anApp->isLoadByDemand(data()->name())) {
- anApp->loadDocument(data()->name(), aDocRef->docId()); // if it is just ne part, load may fail
+ if (anApp->isLoadByDemand(data()->name(), aDocRef->docId())) {
+ anApp->loadDocument(data()->name(), aDocRef->docId()); // if it is just new part, load fails
} else {
anApp->createDocument(aDocRef->docId());
}
std::shared_ptr<ModelAPI_ResultPart> Model_ResultPart::original()
{
- if (myTrsf.get() && baseRef().get()) { // the second condition is to to #2035
+ if (myTrsf.get() && baseRef().get()) { // the second condition is due to #2035
return baseRef()->original();
}
return std::dynamic_pointer_cast<ModelAPI_ResultPart>(data()->owner());
/// Returns the part-document of this result
MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Document> partDoc();
- /// Returns the original part result: for transfomration features results this is
+ /// Returns the original part result: for transformation features results this is
/// the original Part feature result
MODEL_EXPORT virtual std::shared_ptr<ModelAPI_ResultPart> original();
BB.MakeCompound(aCmp);
TopTools_ListIteratorOfListOfShape it(theAncestors);
for(;it.More();it.Next()) {
+ if (theSMap.Contains(it.Value()))
+ continue;
BB.Add(aCmp, it.Value());
theSMap.Add(it.Value());
}
return true;
}
+const TopoDS_Shape findCommonShape(
+ const TopAbs_ShapeEnum theType, const TopTools_ListOfShape& theList)
+{
+ if(theList.Extent() < 1) {
+ return TopoDS_Shape();
+ } else if (theList.Extent() == 1) { // check that sub-shape is bounded by this alone shape
+ TopTools_MapOfShape aSubsInShape;
+ TopExp_Explorer anExp(theList.First(), theType);
+ for(; anExp.More(); anExp.Next()) {
+ if (aSubsInShape.Contains(anExp.Current())) { // found duplicate
+ return anExp.Current();
+ }
+ aSubsInShape.Add(anExp.Current());
+ }
+ }
+
+ // Store in maps sub-shapes from each face.
+ std::vector<TopTools_MapOfShape> aVec;
+ for(TopTools_ListIteratorOfListOfShape anIt(theList); anIt.More(); anIt.Next()) {
+ const TopoDS_Shape aFace = anIt.Value();
+ TopTools_MapOfShape aMap;
+ for(TopExp_Explorer anExp(aFace, theType); anExp.More(); anExp.Next()) {
+ const TopoDS_Shape& aSubShape = anExp.Current();
+ aMap.Add(anExp.Current());
+ }
+ aVec.push_back(aMap);
+ }
+
+ // Find sub-shape shared between all faces.
+ TopoDS_Shape aSharedShape;
+ for(TopTools_MapIteratorOfMapOfShape anIt(aVec[0]); anIt.More(); anIt.Next()) {
+ const TopoDS_Shape& aSubShape = anIt.Value();
+ int aSharedNb = 1;
+ for(int anIndex = 1; anIndex < aVec.size(); ++anIndex) {
+ if(aVec[anIndex].Contains(aSubShape)) {
+ ++aSharedNb;
+ }
+ }
+ if(aSharedNb == theList.Extent()) {
+ if(aSharedShape.IsNull()) {
+ aSharedShape = aSubShape;
+ } else {
+ // More than one shape shared between all faces, return null shape in this case.
+ return TopoDS_Shape();
+ }
+ }
+ }
+
+ return aSharedShape;
+}
+
std::string Model_SelectionNaming::namingName(ResultPtr& theContext,
std::shared_ptr<GeomAPI_Shape> theSubSh, const std::string& theDefaultName,
const bool theAnotherDoc)
const TopTools_ListOfShape& anAncestors = aMap.FindFromKey(aSubShape);
// check that it is not a trivial case (F1 & F2: aNumber = 1)
isTrivialCase = isTrivial(anAncestors, aSMap);
+ if (!isTrivialCase) { // another try: check that common shape can be processed anyway
+ isTrivialCase = !findCommonShape(TopAbs_EDGE, anAncestors).IsNull();
+ }
} else
break;
TopTools_ListOfShape aListOfNbs;
size_t ParseName(const std::string& theSubShapeName, std::list<std::string>& theList)
{
std::string aName = theSubShapeName;
- std::string aLastName;
+ std::string aLastName = aName;
size_t n1(0), n2(0); // n1 - start position, n2 - position of the delimiter
while ((n2 = aName.find('&', n1)) != std::string::npos) {
const std::string aName1 = aName.substr(n1, n2 - n1); //name of face
return theList.size();
}
-const TopoDS_Shape findCommonShape(
- const TopAbs_ShapeEnum theType, const TopTools_ListOfShape& theList)
-{
- if(theList.Extent() < 2) {
- return TopoDS_Shape();
- }
-
- // Store in maps sub-shapes from each face.
- std::vector<TopTools_MapOfShape> aVec;
- for(TopTools_ListIteratorOfListOfShape anIt(theList); anIt.More(); anIt.Next()) {
- const TopoDS_Shape aFace = anIt.Value();
- TopTools_MapOfShape aMap;
- for(TopExp_Explorer anExp(aFace, theType); anExp.More(); anExp.Next()) {
- const TopoDS_Shape& aSubShape = anExp.Current();
- aMap.Add(anExp.Current());
- }
- aVec.push_back(aMap);
- }
-
- // Find sub-shape shared between all faces.
- TopoDS_Shape aSharedShape;
- for(TopTools_MapIteratorOfMapOfShape anIt(aVec[0]); anIt.More(); anIt.Next()) {
- const TopoDS_Shape& aSubShape = anIt.Value();
- int aSharedNb = 1;
- for(int anIndex = 1; anIndex < aVec.size(); ++anIndex) {
- if(aVec[anIndex].Contains(aSubShape)) {
- ++aSharedNb;
- }
- }
- if(aSharedNb == theList.Extent()) {
- if(aSharedShape.IsNull()) {
- aSharedShape = aSubShape;
- } else {
- // More than one shape shared between all faces, return null shape in this case.
- return TopoDS_Shape();
- }
- }
- }
-
- return aSharedShape;
-}
-
std::string getContextName(const std::string& theSubShapeName)
{
std::string aName;
return false;
}
}
+ if (!aSelection.IsNull() &&
+ aSelection.ShapeType() != aType && aSelection.ShapeType() != TopAbs_COMPOUND)
+ aSelection.Nullify(); // to avoid selection of face instead of edge that is described by face
// another try to find edge or vertex by faces
std::list<std::string> aListofNames;
size_t aN = aSelection.IsNull() ? ParseName(aSubShapeName, aListofNames) : 0;
- if (aSelection.IsNull() && (aType == TopAbs_EDGE || aType == TopAbs_VERTEX)) {
- if(aN > 1) {
+ if ((aSelection.IsNull() && (aType == TopAbs_EDGE || aType == TopAbs_VERTEX)) ||
+ (!aSelection.IsNull() && aSelection.ShapeType() != aType)) { // edge by one face as example
+ if(aN >= 1) {
TopTools_ListOfShape aList;
std::list<std::string>::iterator it = aListofNames.begin();
for(; it != aListofNames.end(); it++){
}
// in case of construction, there is no registered names for all sub-elements,
// even for the main element; so, trying to find them by name (without "&" intersections)
- if (aN == 0) {
+ if (aN < 2) {
size_t aConstrNamePos = aSubShapeName.find("/");
bool isFullName = aConstrNamePos == std::string::npos;
std::string aContrName = aContName;
return aResult;
}
-bool Model_Session::isLoadByDemand(const std::string theDocID)
+bool Model_Session::isLoadByDemand(const std::string theDocID, const int theDocIndex)
{
- return Model_Application::getApplication()->isLoadByDemand(theDocID);
+ return Model_Application::getApplication()->isLoadByDemand(theDocID, theDocIndex);
}
std::shared_ptr<ModelAPI_Document> Model_Session::copy(
MODEL_EXPORT virtual std::list<std::shared_ptr<ModelAPI_Document> > allOpenedDocuments();
/// Returns true if document is not loaded yet
- MODEL_EXPORT virtual bool isLoadByDemand(const std::string theDocID);
+ MODEL_EXPORT virtual bool isLoadByDemand(const std::string theDocID, const int theDocIndex);
/// Registers the plugin that creates features.
/// It is obligatory for each plugin to call this function on loading to be found by
Test1995.py
Test2170.py
TestExternalConstruction.py
+ Test2228.py
+ Test2241.py
+ Test2252.py
)
std::shared_ptr<GeomAPI_Shape> theShapeIn, const int theKindOfShape, const int theTag,
const std::string& theName, GeomAPI_DataMapOfShapeShape& theSubShapes,
const bool theIsStoreSeparate,
- const bool theIsStoreAsGenerated)
+ const bool theIsStoreAsGenerated,
+ const bool /*theSplitInSubs*/)
{
myBuilder->loadAndOrientModifiedShapes(
theMS, theShapeIn, theKindOfShape, theTag, theName, theSubShapes, theIsStoreSeparate,
std::shared_ptr<GeomAPI_Shape> theShapeIn, const int theKindOfShape, const int theTag,
const std::string& theName, GeomAPI_DataMapOfShapeShape& theSubShapes,
const bool theIsStoreSeparate = false,
- const bool theIsStoreAsGenerated = false);
+ const bool theIsStoreAsGenerated = false,
+ const bool theSplitInSubs = false);
/// load and orient generated shapes
MODELAPI_EXPORT virtual void loadAndOrientGeneratedShapes (GeomAlgoAPI_MakeShape* theMS,
std::shared_ptr<GeomAPI_Shape> theShapeIn, const int theKindOfShape,
virtual std::list<std::shared_ptr<ModelAPI_Document> > allOpenedDocuments() = 0;
/// Returns true if document is not loaded yet
- virtual bool isLoadByDemand(const std::string theDocID) = 0;
+ virtual bool isLoadByDemand(const std::string theDocID, const int theDocIndex) = 0;
/// Copies the document to the new one with the given id
virtual std::shared_ptr<ModelAPI_Document> copy(
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(model.selection("VERTEX", "Origin"))
+SketchCircle_1 = Sketch_1.addCircle(0, 0, 0.3529019640553777)
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.result(), SketchCircle_1.center())
+SketchCircle_2 = Sketch_1.addCircle(0, 0, 0.4492388920251514)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchCircle_2.center())
+model.do()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "PartSet/Sketch_1/Face-SketchCircle_1_2r-SketchCircle_2_2f")], model.selection(), 5, 0)
+Sketch_2 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/YOZ"))
+SketchCircle_3 = Sketch_2.addCircle(-0.01730125245914903, 1.175069067120482, 0.2787321880802174)
+SketchCircle_4 = Sketch_2.addCircle(-0.01730125245914903, 1.175069067120482, 0.3197841740766353)
+SketchConstraintCoincidence_3 = Sketch_2.setCoincident(SketchCircle_3.center(), SketchCircle_4.center())
+model.do()
+Extrusion_2 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchCircle_1_2r-SketchCircle_2_2f")], model.selection(), 0, 3)
+Extrusion_3 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "PartSet/Sketch_1/Face-SketchCircle_1_2f")], model.selection(), model.selection("FACE", "Extrusion_1_1/To_Face_1"), 0, model.selection(), 0)
+Boolean_1 = model.addCut(Part_1_doc, [model.selection("SOLID", "Extrusion_2_1")], [model.selection("SOLID", "Extrusion_3_1")])
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/XOZ"))
+SketchLine_1 = Sketch_3.addLine(-3.362323990279312, -0.5188129046480872, 0.8318943090987101, -0.5188129046480872)
+SketchLine_2 = Sketch_3.addLine(0.8318943090987101, -0.5188129046480872, 0.8318943090987101, 7.155729512171993)
+SketchLine_3 = Sketch_3.addLine(0.8318943090987101, 7.155729512171993, -3.362323990279312, 7.155729512171993)
+SketchLine_4 = Sketch_3.addLine(-3.362323990279312, 7.155729512171993, -3.362323990279312, -0.5188129046480872)
+SketchConstraintCoincidence_4 = Sketch_3.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_5 = Sketch_3.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_6 = Sketch_3.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_7 = Sketch_3.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_3.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_3.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_3.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_3.setVertical(SketchLine_4.result())
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchLine_2"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_3"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_4"), model.selection("EDGE", "Sketch_2/Edge-SketchLine_1")])
+Extrusion_4 = model.addExtrusion(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchCircle_2_2f")], model.selection(), model.selection("FACE", "Extrusion_2_1/From_Face_1"), 0, model.selection(), 0)
+Boolean_2 = model.addCut(Part_1_doc, [model.selection("SOLID", "Extrusion_1_1")], [model.selection("SOLID", "Extrusion_4_1")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Boolean_1_1"), model.selection("SOLID", "Boolean_2_1"), model.selection("FACE", "Face_1_1")])
+Remove_SubShapes_1 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPOUND", "Partition_1_1"))
+Remove_SubShapes_1.setSubShapesToKeep([model.selection("COMPSOLID", "Partition_1_1_1"), model.selection("FACE", "Partition_1_1_3"), model.selection("FACE", "Partition_1_1_4"), model.selection("FACE", "Partition_1_1_5"), model.selection("FACE", "Partition_1_1_6"), model.selection("FACE", "Partition_1_1_7")])
+model.end()
+
+
+# check that remove sub-shapes contains correct selection
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+assert(aFactory.validate(Remove_SubShapes_1.feature()))
+assert(Remove_SubShapes_1.subshapes().size() == 6)
+assert(Remove_SubShapes_1.subshapes().value(0).namingName() == "Partition_1_1_1")
+assert(Remove_SubShapes_1.subshapes().value(1).namingName() == "Partition_1_1_3")
+assert(Remove_SubShapes_1.subshapes().value(2).namingName() == "Partition_1_1_4")
+assert(Remove_SubShapes_1.subshapes().value(3).namingName() == "Partition_1_1_5")
+assert(Remove_SubShapes_1.subshapes().value(4).namingName() == "Partition_1_1_6")
+assert(Remove_SubShapes_1.subshapes().value(5).namingName() == "Partition_1_1_7")
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "l", "10")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(0, 60, 10, 60)
+SketchLine_2 = Sketch_1.addLine(model.selection("EDGE", "PartSet/OY"))
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_2.result())
+SketchLine_3 = Sketch_1.addLine(10, 60, 10, 40)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_3.startPoint())
+SketchLine_4 = Sketch_1.addLine(10, 40, 20, 40)
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchLine_5 = Sketch_1.addLine(20, 40, 20, 20)
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_5.startPoint())
+SketchLine_6 = Sketch_1.addLine(20, 20, 30, 20)
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_5.endPoint(), SketchLine_6.startPoint())
+SketchLine_7 = Sketch_1.addLine(30, 20, 30, 0)
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_6.endPoint(), SketchLine_7.startPoint())
+SketchLine_8 = Sketch_1.addLine(model.selection("EDGE", "PartSet/OX"))
+SketchConstraintCoincidence_7 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_8.result())
+SketchLine_9 = Sketch_1.addLine(30, 0, 81.26217508737108, 0)
+SketchConstraintCoincidence_8 = Sketch_1.setCoincident(SketchLine_7.endPoint(), SketchLine_9.startPoint())
+SketchConstraintCoincidence_9 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchLine_8.result())
+SketchLine_10 = Sketch_1.addLine(0, 60, 0, 81.26217508737108)
+SketchConstraintCoincidence_10 = Sketch_1.setCoincident(SketchLine_1.startPoint(), SketchLine_10.startPoint())
+SketchConstraintCoincidence_11 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchLine_2.result())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_4.result())
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_6.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_5.result())
+SketchArc_1 = Sketch_1.addArc(4.151438510550382e-034, -3.089278765476956e-034, 81.26217508737108, 0, 0, 81.26217508737108, False)
+SketchConstraintCoincidence_12 = Sketch_1.setCoincident(SketchLine_2.startPoint(), SketchArc_1.center())
+SketchConstraintCoincidence_13 = Sketch_1.setCoincident(SketchLine_9.endPoint(), SketchArc_1.startPoint())
+SketchConstraintCoincidence_14 = Sketch_1.setCoincident(SketchLine_2.result(), SketchArc_1.endPoint())
+SketchConstraintCoincidence_15 = Sketch_1.setCoincident(SketchLine_10.endPoint(), SketchArc_1.endPoint())
+SketchConstraintVertical_3 = Sketch_1.setVertical(SketchLine_7.result())
+SketchArc_2 = Sketch_1.addArc(4.151438510550382e-034, -3.089278765476956e-034, 76.26217508737108, 0, 0, 76.26217508737108, False)
+SketchConstraintCoincidence_16 = Sketch_1.setCoincident(SketchLine_2.startPoint(), SketchArc_2.center())
+SketchConstraintCoincidence_16.setName("SketchConstraintCoincidence_23")
+SketchConstraintCoincidence_17 = Sketch_1.setCoincident(SketchLine_9.result(), SketchArc_2.startPoint())
+SketchConstraintCoincidence_17.setName("SketchConstraintCoincidence_24")
+SketchConstraintCoincidence_18 = Sketch_1.setCoincident(SketchLine_10.result(), SketchArc_2.endPoint())
+SketchConstraintCoincidence_18.setName("SketchConstraintCoincidence_25")
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchArc_1.endPoint(), SketchArc_2.endPoint(), 5)
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_7.result(), "2*l")
+SketchConstraintLength_1.setName("SketchConstraintLength_2")
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_6.result(), "l")
+SketchConstraintLength_2.setName("SketchConstraintLength_3")
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_5.result(), SketchLine_7.result())
+SketchConstraintEqual_1.setName("SketchConstraintEqual_2")
+SketchConstraintEqual_2 = Sketch_1.setEqual(SketchLine_6.result(), SketchLine_4.result())
+SketchConstraintEqual_2.setName("SketchConstraintEqual_3")
+SketchConstraintEqual_3 = Sketch_1.setEqual(SketchLine_5.result(), SketchLine_3.result())
+SketchConstraintEqual_3.setName("SketchConstraintEqual_4")
+SketchConstraintEqual_4 = Sketch_1.setEqual(SketchLine_4.result(), SketchLine_1.result())
+SketchConstraintEqual_4.setName("SketchConstraintEqual_5")
+model.do()
+Sketch_2 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchCircle_1 = Sketch_2.addCircle(9.082839147404137, 71.32948234489588, 2.005056553640547)
+SketchCircle_2 = Sketch_2.addCircle(20.11065019242717, 63.7102674410618, 2.268462537186828)
+SketchCircle_3 = Sketch_2.addCircle(26.52683116407693, 51.67992811921848, 2.727171758268866)
+SketchCircle_4 = Sketch_2.addCircle(38.35666483055617, 58.29661474623231, 3.007584830460834)
+SketchCircle_5 = Sketch_2.addCircle(33.94554041254697, 44.0607132153844, 3.054011155390377)
+SketchCircle_6 = Sketch_2.addCircle(48.58245325412298, 42.45666797247195, 2.346858526438435)
+SketchCircle_7 = Sketch_2.addCircle(38.95818179664835, 31.42885692744893, 3.547307159201095)
+SketchCircle_8 = Sketch_2.addCircle(63.82088306179116, 27.41874382016783, 4.536925074373651)
+SketchCircle_9 = Sketch_2.addCircle(50.18649849703544, 28.4212720969881, 4.820482891521984)
+SketchCircle_10 = Sketch_2.addCircle(49.58498153094326, 15.18789884296047, 2.552020354335177)
+SketchCircle_11 = Sketch_2.addCircle(66.22695092615982, 10.77677442495125, 4.536925074373645)
+SketchCircle_12 = Sketch_2.addCircle(50.98852111849166, 6.165144351577979, 3.547307159201085)
+model.do()
+Face_1 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_1f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6f-SketchLine_7f-SketchLine_9f-SketchLine_10r-SketchArc_2_2f")])
+Face_2 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_1/Wire-SketchLine_9f-SketchLine_10r-SketchArc_1_2f-SketchArc_2_2r")])
+Face_3 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchCircle_1_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_2_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_3_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_4_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_5_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_6_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_7_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_9_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_8_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_10_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_12_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_11_2")])
+Face_4 = model.addFace(Part_1_doc, [model.selection("EDGE", "Sketch_2/Edge-SketchCircle_1_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_2_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_3_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_4_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_5_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_7_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_6_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_9_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_8_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_10_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_12_2"), model.selection("EDGE", "Sketch_2/Edge-SketchCircle_11_2"), model.selection("WIRE", "Sketch_1/Wire-SketchLine_1f-SketchLine_3f-SketchLine_4f-SketchLine_5f-SketchLine_6f-SketchLine_7f-SketchLine_9f-SketchLine_10r-SketchArc_2_2f")])
+Sketch_3 = model.addSketch(Part_1_doc, model.selection("FACE", "PartSet/XOY"))
+SketchLine_11 = Sketch_3.addLine(40, 0, 30, 0)
+SketchPoint_1 = Sketch_3.addPoint(model.selection("VERTEX", "Face_1_1/Edge_4&Face_1_1/Edge_5"))
+SketchConstraintCoincidence_19 = Sketch_3.setCoincident(SketchLine_11.endPoint(), SketchPoint_1.result())
+SketchLine_12 = Sketch_3.addLine(30, 0, 30, 10)
+SketchLine_13 = Sketch_3.addLine(30, 10, 40, 10)
+SketchLine_14 = Sketch_3.addLine(40, 10, 40, 0)
+SketchConstraintCoincidence_20 = Sketch_3.setCoincident(SketchLine_14.endPoint(), SketchLine_11.startPoint())
+SketchConstraintCoincidence_21 = Sketch_3.setCoincident(SketchLine_11.endPoint(), SketchLine_12.startPoint())
+SketchConstraintCoincidence_22 = Sketch_3.setCoincident(SketchLine_12.endPoint(), SketchLine_13.startPoint())
+SketchConstraintCoincidence_23 = Sketch_3.setCoincident(SketchLine_13.endPoint(), SketchLine_14.startPoint())
+SketchConstraintCoincidence_23.setName("SketchConstraintCoincidence_26")
+SketchConstraintHorizontal_4 = Sketch_3.setHorizontal(SketchLine_11.result())
+SketchConstraintVertical_4 = Sketch_3.setVertical(SketchLine_12.result())
+SketchConstraintHorizontal_5 = Sketch_3.setHorizontal(SketchLine_13.result())
+SketchConstraintVertical_5 = Sketch_3.setVertical(SketchLine_14.result())
+SketchConstraintEqual_5 = Sketch_3.setEqual(SketchLine_14.result(), SketchLine_13.result())
+SketchConstraintEqual_5.setName("SketchConstraintEqual_6")
+SketchConstraintLength_3 = Sketch_3.setLength(SketchLine_13.result(), "l")
+SketchConstraintLength_3.setName("SketchConstraintLength_4")
+model.do()
+Face_5 = model.addFace(Part_1_doc, [model.selection("WIRE", "Sketch_3/Wire-SketchLine_11r-SketchLine_12r-SketchLine_13r-SketchLine_14r")])
+MultiTranslation_1 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Face_5_1")], model.selection("EDGE", "PartSet/OX"), "l", 4, model.selection("EDGE", "PartSet/OY"), "l", 2)
+Recover_1 = model.addRecover(Part_1_doc, MultiTranslation_1, [Face_5.result()])
+Translation_1 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_1_1")], model.selection("VERTEX", "Face_4_1/Edge_4&Face_4_1/Edge_5"), model.selection("VERTEX", "Face_4_1/Edge_6&Face_4_1/Edge_7"))
+MultiTranslation_2 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_1_1")], model.selection("EDGE", "PartSet/OX"), "l", 4, model.selection("EDGE", "PartSet/OY"), "l", 2)
+Recover_2 = model.addRecover(Part_1_doc, MultiTranslation_1, [Face_5.result()])
+Translation_2 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_2_1")], model.selection("VERTEX", "Face_4_1/Edge_4&Face_4_1/Edge_5"), model.selection("VERTEX", "Face_4_1/Edge_8&Face_4_1/Edge_9"))
+MultiTranslation_3 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_2_1")], model.selection("EDGE", "PartSet/OX"), "l", 4)
+Recover_3 = model.addRecover(Part_1_doc, MultiTranslation_1, [Face_5.result()])
+Translation_3 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_3_1")], model.selection("VERTEX", "Face_4_1/Edge_4&Face_4_1/Edge_5"), model.selection("VERTEX", "MultiTranslation_3_1/Translated_Edge_1_4&MultiTranslation_3_1/Translated_Edge_1_1"))
+MultiTranslation_4 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_3_1")], model.selection("EDGE", "PartSet/OX"), "l", 3)
+Recover_4 = model.addRecover(Part_1_doc, MultiTranslation_1, [Face_5.result()])
+Translation_4 = model.addTranslation(Part_1_doc, [model.selection("FACE", "Recover_4_1")], model.selection("VERTEX", "Face_4_1/Edge_4&Face_4_1/Edge_5"), model.selection("VERTEX", "Face_4_1/Edge_1&Face_4_1/Edge_2"))
+MultiTranslation_5 = model.addMultiTranslation(Part_1_doc, [model.selection("FACE", "Translation_4_1")], model.selection("EDGE", "PartSet/OX"), "l", 2)
+Group_1 = model.addGroup(Part_1_doc, [model.selection("FACE", "MultiTranslation_4_1_2"), model.selection("FACE", "MultiTranslation_1_1_8"), model.selection("FACE", "MultiTranslation_1_1_4"), model.selection("FACE", "MultiTranslation_1_1_3"), model.selection("FACE", "MultiTranslation_1_1_6"), model.selection("FACE", "MultiTranslation_1_1_2"), model.selection("FACE", "MultiTranslation_1_1_7"), model.selection("FACE", "MultiTranslation_2_1_3"), model.selection("FACE", "MultiTranslation_3_1_4"), model.selection("FACE", "MultiTranslation_2_1_8"), model.selection("FACE", "MultiTranslation_2_1_4"), model.selection("FACE", "MultiTranslation_2_1_7"), model.selection("FACE", "MultiTranslation_4_1_3"), model.selection("FACE", "MultiTranslation_1_1_1"), model.selection("FACE", "MultiTranslation_5_1_2"), model.selection("FACE", "MultiTranslation_4_1_1"), model.selection("FACE", "MultiTranslation_5_1_1"), model.selection("FACE", "MultiTranslation_3_1_3"), model.selection("FACE", "MultiTranslation_3_1_2"), model.selection("FACE", "MultiTranslation_3_1_1"), model.selection("FACE", "MultiTranslation_2_1_6"), model.selection("FACE", "MultiTranslation_2_1_2"), model.selection("FACE", "MultiTranslation_2_1_5"), model.selection("FACE", "MultiTranslation_2_1_1"), model.selection("FACE", "MultiTranslation_1_1_5")])
+Group_1.setName("Group_3")
+Group_1.result().setName("assemblages")
+Group_2 = model.addGroup(Part_1_doc, [model.selection("FACE", "Face_2_1"), model.selection("FACE", "Face_3_7"), model.selection("FACE", "Face_3_5"), model.selection("FACE", "Face_3_3"), model.selection("FACE", "Face_3_4"), model.selection("FACE", "Face_3_1"), model.selection("FACE", "Face_3_2"), model.selection("FACE", "Face_3_6"), model.selection("FACE", "Face_3_11"), model.selection("FACE", "Face_3_10"), model.selection("FACE", "Face_3_8"), model.selection("FACE", "Face_3_9"), model.selection("FACE", "Face_3_12")])
+Group_2.setName("Group_1")
+Group_2.result().setName("eau")
+Group_2.result().setColor(0, 170, 255)
+Group_3 = model.addGroup(Part_1_doc, [model.selection("FACE", "Face_4_1")])
+Group_3.setName("Group_2")
+Group_3.result().setName("acier")
+Group_3.result().setColor(170, 85, 0)
+Shell_1 = model.addShell(Part_1_doc, [model.selection("FACE", "MultiTranslation_1_1_1"), model.selection("FACE", "MultiTranslation_1_1_2"), model.selection("FACE", "MultiTranslation_1_1_3"), model.selection("FACE", "MultiTranslation_1_1_4"), model.selection("FACE", "MultiTranslation_1_1_5"), model.selection("FACE", "MultiTranslation_1_1_6"), model.selection("FACE", "MultiTranslation_1_1_7"), model.selection("FACE", "MultiTranslation_2_1_4"), model.selection("FACE", "MultiTranslation_2_1_5"), model.selection("FACE", "MultiTranslation_2_1_6"), model.selection("FACE", "MultiTranslation_2_1_7"), model.selection("FACE", "MultiTranslation_2_1_8"), model.selection("FACE", "MultiTranslation_2_1_1"), model.selection("FACE", "MultiTranslation_2_1_2"), model.selection("FACE", "MultiTranslation_2_1_3"), model.selection("FACE", "MultiTranslation_3_1_4"), model.selection("FACE", "MultiTranslation_3_1_3"), model.selection("FACE", "MultiTranslation_3_1_2"), model.selection("FACE", "MultiTranslation_3_1_1"), model.selection("FACE", "MultiTranslation_4_1_1"), model.selection("FACE", "MultiTranslation_4_1_2"), model.selection("FACE", "MultiTranslation_4_1_3"), model.selection("FACE", "MultiTranslation_5_1_1"), model.selection("FACE", "MultiTranslation_5_1_2"), model.selection("FACE", "MultiTranslation_1_1_8")])
+Partition_1 = model.addPartition(Part_1_doc, [model.selection("FACE", "Face_3_1"), model.selection("FACE", "Face_3_2"), model.selection("FACE", "Face_4_1"), model.selection("FACE", "Face_2_1"), model.selection("FACE", "Face_1_1"), model.selection("FACE", "Face_3_5"), model.selection("FACE", "Face_3_3"), model.selection("FACE", "Face_3_4"), model.selection("FACE", "Face_3_7"), model.selection("FACE", "Face_3_6"), model.selection("FACE", "Face_3_8"), model.selection("FACE", "Face_3_9"), model.selection("FACE", "Face_3_10"), model.selection("FACE", "Face_3_11"), model.selection("FACE", "Face_3_12"), model.selection("SHELL", "Shell_1_1")])
+Remove_SubShapes_1 = model.addRemoveSubShapes(Part_1_doc, model.selection("COMPOUND", "Partition_1_1"))
+Remove_SubShapes_1.setSubShapesToKeep([model.selection("FACE", "Partition_1_1_2"), model.selection("FACE", "Partition_1_1_3"), model.selection("FACE", "Partition_1_1_4"), model.selection("FACE", "Partition_1_1_5"), model.selection("FACE", "Partition_1_1_6"), model.selection("FACE", "Partition_1_1_7"), model.selection("FACE", "Partition_1_1_8"), model.selection("FACE", "Partition_1_1_9"), model.selection("FACE", "Partition_1_1_10"), model.selection("FACE", "Partition_1_1_11"), model.selection("FACE", "Partition_1_1_12"), model.selection("FACE", "Partition_1_1_13"), model.selection("FACE", "Partition_1_1_14"), model.selection("FACE", "Partition_1_1_15"), model.selection("FACE", "Partition_1_1_16"), model.selection("FACE", "Partition_1_1_17"), model.selection("FACE", "Partition_1_1_18"), model.selection("FACE", "Partition_1_1_19"), model.selection("FACE", "Partition_1_1_20"), model.selection("FACE", "Partition_1_1_21"), model.selection("FACE", "Partition_1_1_22"), model.selection("FACE", "Partition_1_1_23"), model.selection("FACE", "Partition_1_1_24"), model.selection("FACE", "Partition_1_1_25"), model.selection("FACE", "Partition_1_1_26"), model.selection("FACE", "Partition_1_1_27"), model.selection("FACE", "Partition_1_1_28"), model.selection("FACE", "Partition_1_1_29"), model.selection("FACE", "Partition_1_1_30"), model.selection("FACE", "Partition_1_1_31"), model.selection("FACE", "Partition_1_1_32"), model.selection("FACE", "Partition_1_1_33"), model.selection("FACE", "Partition_1_1_34"), model.selection("FACE", "Partition_1_1_35"), model.selection("FACE", "Partition_1_1_36"), model.selection("FACE", "Partition_1_1_37"), model.selection("FACE", "Partition_1_1_38"), model.selection("FACE", "Partition_1_1_39"), model.selection("FACE", "Partition_1_1_40"), model.selection("FACE", "Partition_1_1_41"), model.selection("FACE", "Partition_1_1_42"), model.selection("FACE", "Partition_1_1_43"), model.selection("FACE", "Partition_1_1_44"), model.selection("FACE", "Partition_1_1_45"), model.selection("FACE", "Partition_1_1_46"), model.selection("FACE", "Partition_1_1_47"), model.selection("FACE", "Partition_1_1_48"), model.selection("FACE", "Partition_1_1_49"), model.selection("FACE", "Partition_1_1_50"), model.selection("FACE", "Partition_1_1_51"), model.selection("FACE", "Partition_1_1_52"), model.selection("FACE", "Partition_1_1_53"), model.selection("FACE", "Partition_1_1_54"), model.selection("FACE", "Partition_1_1_55"), model.selection("FACE", "Partition_1_1_56"), model.selection("FACE", "Partition_1_1_57")])
+model.end()
+
+# move groups
+model.begin()
+Part_1_doc.moveFeature(Group_1.feature(), Remove_SubShapes_1.feature())
+Part_1_doc.moveFeature(Group_2.feature(), Group_1.feature())
+Part_1_doc.moveFeature(Group_3.feature(), Group_2.feature())
+model.end()
+
+# check that groups 2 and 3 are correct, but Group_1 elements are removed (because shell is removed)
+from ModelAPI import *
+aFactory = ModelAPI_Session.get().validators()
+for Group in [Group_1, Group_2, Group_3]:
+ if Group != Group_1:
+ assert(aFactory.validate(Group.feature()))
+ assert(Group.groupList().size() != 0)
+ for a in range(Group.groupList().size()):
+ if Group == Group_1:
+ assert(len(Group.groupList().value(a).namingName()) == 0)
+ else:
+ assert(Group.groupList().value(a).value().shapeTypeStr() == "FACE")
+ assert(len(Group.groupList().value(a).namingName()) > 0)
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from salome.shaper import model
+from ModelAPI import *
+from GeomAlgoAPI import *
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(60, 0, 0, 0)
+SketchPoint_1 = Sketch_1.addPoint(model.selection("VERTEX", "PartSet/Origin"))
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchPoint_1.result())
+SketchLine_2 = Sketch_1.addLine(0, 0, 0, 60)
+SketchLine_3 = Sketch_1.addLine(0, 60, 60, 60)
+SketchLine_4 = Sketch_1.addLine(60, 60, 60, 0)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_3.result(), 60)
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_4.result())
+model.do()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "Sketch_1/Face-SketchLine_1r-SketchLine_2r-SketchLine_3r-SketchLine_4r")], model.selection(), 90, 0)
+model.do()
+aSession = ModelAPI_Session.get()
+aSession.setActiveDocument(partSet, False)
+Translation_1 = model.addTranslation(partSet, [model.selection("COMPOUND", "Part_1/")], model.selection("EDGE", "OX"), 100)
+model.do()
+# move timeline before Translation
+partSet.setCurrentFeature(Part_1.feature(), True)
+Rotation_1 = model.addRotation(partSet, [model.selection("COMPOUND", "Part_1/")], model.selection("EDGE", "OY"), 90)
+model.do()
+# move timeline to the end of history
+partSet.setCurrentFeature(Translation_1.feature(), True)
+model.end()
+
+# check that rotation then translation were applied consequently
+assert(partSet.size("Parts") == 1)
+resShape = modelAPI_Result(partSet.object("Parts", 0)).shape()
+# height of extrusion 90 / 2 + translation 100
+assert(GeomAlgoAPI_ShapeTools_centreOfMass(resShape).x() == 145)
+# rotated
+assert(floor(GeomAlgoAPI_ShapeTools_centreOfMass(resShape).z()) == -30)
+
+assert(model.checkPythonDump())
/// Returns main window of the application
virtual QMainWindow* desktop() const = 0;
+ /// Returns true if SHIFT is pressed
+ /// \return boolean value
+ virtual bool hasSHIFTPressed() const = 0;
signals:
/// Signal selection changed.
qDebug("ModuleBase_ModelWidget::moveObject");
#endif
- static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
+ static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED);
ModelAPI_EventCreator::get()->sendUpdated(theObj, anEvent);
Events_Loop::loop()->flush(anEvent);
}
void ModuleBase_ResultPrs::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
- const Standard_Integer theMode)
+ const Standard_Integer aMode)
{
- if (appendVertexSelection(aSelection, theMode))
- return;
-
- if (theMode > TopAbs_SHAPE) {
+ if (aMode > TopAbs_SHAPE) {
// In order to avoid using custom selection modes
- if (theMode == ModuleBase_ResultPrs::Sel_Result) {
+ if (aMode == ModuleBase_ResultPrs::Sel_Result) {
AIS_Shape::ComputeSelection(aSelection, TopAbs_COMPOUND);
}
return;
// TODO: OCCT issue should be created for the COMPOUND processing
// before it is fixed, the next workaround in necessary
- if (theMode == AIS_Shape::SelectionMode(TopAbs_COMPOUND)) {
+ if (aMode == AIS_Shape::SelectionMode(TopAbs_COMPOUND)) {
const TopoDS_Shape& aShape = Shape();
TopExp_Explorer aCompExp(aShape, TopAbs_COMPOUND);
// do not activate in compound mode shapes which do not contain compounds
return;
}
- if (theMode == AIS_Shape::SelectionMode(TopAbs_COMPSOLID)) {
+ if (aMode == AIS_Shape::SelectionMode(TopAbs_COMPSOLID)) {
// Limit selection area only by actual object (Shape)
ResultCompSolidPtr aCompSolid = ModelAPI_Tools::compSolidOwner(myResult);
if (aCompSolid.get()) {
}
//AIS_Shape::ComputeSelection(aSelection, 0);
}
- AIS_Shape::ComputeSelection(aSelection, theMode);
+ AIS_Shape::ComputeSelection(aSelection, aMode);
if (myAdditionalSelectionPriority > 0) {
for (aSelection->Init(); aSelection->More(); aSelection->Next()) {
}
}
-bool ModuleBase_ResultPrs::appendVertexSelection(const Handle(SelectMgr_Selection)& aSelection,
- const Standard_Integer theMode)
-{
- if (Shape().ShapeType() == TopAbs_VERTEX) {
- const TopoDS_Shape& aShape = Shape();
-
- int aPriority = StdSelect_BRepSelectionTool::GetStandardPriority(aShape, TopAbs_VERTEX);
- double aDeflection = Prs3d::GetDeflection(aShape, myDrawer);
-
- /// The cause of this method is the last parameter of BRep owner setting into True.
- /// That means that owner should behave like it comes from decomposition. (In this case, OCCT
- /// visualizes it in Ring style) OCCT version is 7.0.0 with path for SHAPER module.
- Handle(StdSelect_BRepOwner) aOwner = new StdSelect_BRepOwner(aShape, aPriority, Standard_True);
- StdSelect_BRepSelectionTool::ComputeSensitive(aShape, aOwner, aSelection,
- aDeflection, myDrawer->HLRAngle(), 9, 500);
-
- for (aSelection->Init(); aSelection->More(); aSelection->Next()) {
- Handle(SelectMgr_EntityOwner) anOwner =
- Handle(SelectMgr_EntityOwner)
- ::DownCast(aSelection->Sensitive()->BaseSensitive()->OwnerId());
- anOwner->Set(this);
- }
- return true;
- }
- return false;
-}
-
-/* OBSOLETE
void ModuleBase_ResultPrs::appendWiresSelection(const Handle(SelectMgr_Selection)& theSelection,
const TopoDS_Shape& theShape)
{
myDrawer->IsAutoTriangulation());
} catch ( Standard_Failure ) {
}
-}*/
+}
void ModuleBase_ResultPrs::HilightSelected(const Handle(PrsMgr_PresentationManager3d)& thePM,
const SelectMgr_SequenceOfOwner& theOwners)
/// Highlight the presentation with the given color
/// \param aPM a presentations manager
/// \param theStyle a style of presentation
- /// \param theMode a drawing mode
+ /// \param aMode a drawing mode
virtual void HilightWithColor (const Handle(PrsMgr_PresentationManager3d)& aPM,
- const Handle(Graphic3d_HighlightStyle)& theStyle, const Standard_Integer theMode = 0)
+ const Handle(Graphic3d_HighlightStyle)& theStyle, const Standard_Integer aMode = 0)
{
Selectable()->HilightOwnerWithColor(aPM, theStyle, this);
}
/// Redefinition of virtual function
Standard_EXPORT virtual void ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
- const Standard_Integer theMode) ;
+ const Standard_Integer aMode) ;
private:
- /// If the shape of this presentation is Vertex, it appends custom sensitive and owners for it.
- /// Owner is a usual Brep owner with "isDecomposite" in true. It is necessary to have "Ring"
- /// highlight/selected marker.
- /// \param theSelection a current filled selection
- /// \param theMode a selection mode
- /// \return true if the owner is created
- bool appendVertexSelection(const Handle(SelectMgr_Selection)& aSelection,
- const Standard_Integer theMode);
/// Appens sensitive and owners for wires of the given shape into selection
/// \param theSelection a current filled selection
/// \param theShape a shape
- //void appendWiresSelection(const Handle(SelectMgr_Selection)& theSelection,
- // const TopoDS_Shape& theShape);
+ void appendWiresSelection(const Handle(SelectMgr_Selection)& theSelection,
+ const TopoDS_Shape& theShape);
/// Reference to result object
ResultPtr myResult;
bool ModuleBase_WidgetEditor::focusTo()
{
showPopupEditor();
- return true;
+ return false;
}
bool ModuleBase_WidgetEditor::showPopupEditor(const bool theSendSignals)
bool isValueAccepted = false;
// we need to emit the focus in event manually in order to save the widget as an active
// in the property panel before the mouse leave event happens in the viewer. The module
- // ask an active widget and change the feature visualization if the widget is not the current one.
- if (theSendSignals)
- emitFocusInWidget();
+ // ask an active widget and change the feature visualization if the widget is not the current
+ // one. Also we need this widget as active to provide call of processEnter() applyed
+ // by operation manager to the current widget. If not, the myEditorDialog will stay opened
+ emitFocusInWidget();
// nds: it seems, that the envents processing is not necessary anymore
// White while all events will be processed
{
// Set focus to List control in order to make possible
// to use Tab key for transfer the focus to next widgets
- myListControl->setCurrentRow(myListControl->model()->rowCount() - 1);
ModuleBase_Tools::setFocus(myListControl,
"ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()");
}
AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(attributeID());
for (int i = 0; i < aSelectionListAttr->size(); i++) {
AttributeSelectionPtr anAttr = aSelectionListAttr->value(i);
- bool aFound = findInSelection(anAttr->context(), anAttr->value(), aGeomSelection);
+ bool aFound = findInSelection(anAttr->context(), anAttr->value(), aGeomSelection,
+ myWorkshop);
if (!aFound)
anIndicesToBeRemoved.insert(i);
}
for (int i = 0; i < aRefListAttr->size(); i++) {
ObjectPtr anObject = aRefListAttr->object(i);
if (anObject.get()) {
- bool aFound = findInSelection(anObject, GeomShapePtr(), aGeomSelection);
+ bool aFound = findInSelection(anObject, GeomShapePtr(), aGeomSelection,
+ myWorkshop);
if (!aFound)
anIndicesToBeRemoved.insert(i);
}
aFound = anAttributes.find(anAttribute) != anAttributes.end();
}
else {
- aFound = findInSelection(aRefAttrListAttr->object(i), GeomShapePtr(), aGeomSelection);
+ aFound = findInSelection(aRefAttrListAttr->object(i), GeomShapePtr(), aGeomSelection,
+ myWorkshop);
}
if (!aFound)
anIndicesToBeRemoved.insert(i);
}
bool ModuleBase_WidgetMultiSelector::findInSelection(const ObjectPtr& theObject,
- const GeomShapePtr& theShape,
- const std::map<ObjectPtr, std::set<GeomShapePtr> >& theGeomSelection)
+ GeomShapePtr theShape,
+ const std::map<ObjectPtr, std::set<GeomShapePtr> >& theGeomSelection,
+ ModuleBase_IWorkshop* theWorkshop)
{
+ // issue #2154: we should not remove from list objects hidden in the viewer if selection
+ // was done with SHIFT button
+ if (theWorkshop->hasSHIFTPressed() && !theObject->isDisplayed())
+ return true;
+
bool aFound = false;
GeomShapePtr anEmptyShape(new GeomAPI_Shape());
+ if (theShape.get()) { // treat shape equal to context as null: 2219, keep order of shapes in list
+ const ResultPtr aContext = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
+ if (aContext.get() && aContext->shape()->isEqual(theShape))
+ theShape.reset();
+ }
GeomShapePtr aShape = theShape.get() ? theShape : anEmptyShape;
if (theGeomSelection.find(theObject) != theGeomSelection.end()) {// found
const std::set<GeomShapePtr>& aShapes = theGeomSelection.at(theObject);
/// \param theObject a model object, a set of shapes is searched by it
/// \param theShape a shape to be in the set of the object shapes
/// \param theGeomSelection a map built on selection
+ /// \param theWorkshop a current workshop
/// \return boolean result
static bool findInSelection(const ObjectPtr& theObject,
- const GeomShapePtr& theShape,
- const std::map<ObjectPtr, std::set<GeomShapePtr> >& theGeomSelection);
+ GeomShapePtr theShape,
+ const std::map<ObjectPtr, std::set<GeomShapePtr> >& theGeomSelection,
+ ModuleBase_IWorkshop* theWorkshop);
protected:
/// List control
aFactory->registerValidator("PartSet_CollinearSelection", new PartSet_CollinearSelection);
aFactory->registerValidator("PartSet_MiddlePointSelection", new PartSet_MiddlePointSelection);
aFactory->registerValidator("PartSet_DifferentObjects", new PartSet_DifferentObjectsValidator);
+ aFactory->registerValidator("PartSet_DifferentPoints", new PartSet_DifferentPointsValidator);
aFactory->registerValidator("PartSet_CoincidentAttr", new PartSet_CoincidentAttr);
aFactory->registerValidator("PartSet_MultyTranslationSelection",
new PartSet_MultyTranslationSelection);
#include <ModuleBase_OperationFeature.h>
#include <ModuleBase_ViewerPrs.h>
+#include <GeomDataAPI_Point2D.h>
+#include <GeomAPI_Pnt2d.h>
+
#include <Events_InfoMessage.h>
#include <ModelAPI_AttributeRefAttr.h>
#include <SketchPlugin_Sketch.h>
#include <SketchPlugin_ConstraintCoincidence.h>
#include <SketchPlugin_Arc.h>
+#include <SketchPlugin_Point.h>
#include <GeomAPI_Edge.h>
#include <list>
return true;
}
+bool PartSet_DifferentPointsValidator::isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const
+{
+ FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
+
+ // the type of validated attributes should be equal, attributes with
+ // different types are not validated
+ // Check RefAttr attributes
+ std::string anAttrType = theAttribute->attributeType();
+ std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs;
+ if (anAttrType != ModelAPI_AttributeRefAttr::typeId())
+ return true;
+
+ // obtain point of the given attribute
+ AttributePoint2DPtr anAttributePoint = getRefPointAttribute(theAttribute);
+ if (!anAttributePoint.get() || !anAttributePoint->isInitialized())
+ return true;
+
+ // obtain point of the parameter attribute
+ AttributePoint2DPtr anArgumentPoint = getRefPointAttribute
+ (aFeature->attribute(theArguments.front()));
+
+ if (!anArgumentPoint.get() || !anArgumentPoint->isInitialized())
+ return true;
+
+ return !anAttributePoint->pnt()->isEqual(anArgumentPoint->pnt());
+}
+
+AttributePoint2DPtr PartSet_DifferentPointsValidator::getRefPointAttribute
+ (const AttributePtr& theAttribute) const
+{
+ AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
+
+ AttributePoint2DPtr aPointAttribute;
+ if (anAttr->isObject()) {
+ ObjectPtr anObject = anAttr->object();
+ if (anObject.get()) {
+ FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
+ if (aFeature->getKind() == SketchPlugin_Point::ID())
+ aPointAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>
+ (aFeature->attribute(SketchPlugin_Point::COORD_ID()));
+ }
+ }
+ else {
+ aPointAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr->attr());
+ }
+ return aPointAttribute;
+}
+
bool PartSet_CoincidentAttr::isValid(const AttributePtr& theAttribute,
const std::list<std::string>& theArguments,
Events_InfoMessage& theError) const
#include <ModuleBase_ISelection.h>
#include <ModelAPI_AttributeValidator.h>
+class GeomDataAPI_Point2D;
+
/*
* Selector validators
*/
};
+/**
+* \ingroup Validators
+* A validator which checks that Point2D selected for feature attributes are different (not the same)
+* It iterates by the feature ModelAPI_AttributeRefAttr attributes, finds GeomDataAPI_Point2D attribute in
+* value or attribute of the attributes and if the point of the given attribute is geometrical equal to
+* a point of another attribute, returns false
+*/
+class PartSet_DifferentPointsValidator : public ModelAPI_AttributeValidator
+{
+ public:
+ //! Returns true if the attribute is good for the feature attribute
+ //! \param theAttribute an attribute
+ //! \param theArguments a list of arguments (names of attributes to check)
+ //! \param theError an output error string
+ virtual bool isValid(const AttributePtr& theAttribute,
+ const std::list<std::string>& theArguments,
+ Events_InfoMessage& theError) const;
+private:
+ //! Finds Point2D attribute by reference attribute. It might be:
+ //! - COORD_ID attribute of SketchPlugin_Point if object
+ //! - Attribute casted to point if attribute
+ //! \param theAttribute an attribute
+ //! \return point 2d attribute or NULL
+ std::shared_ptr<GeomDataAPI_Point2D> getRefPointAttribute
+ (const AttributePtr& theAttribute) const;
+};
+
+
/**\class PartSet_CoincidentAttr
* \ingroup Validators
* \brief Validator to check whether there is a coincident constraint between
if (!aFirstValue.get() && myPreSelected.get()) {
aFirstValue = myPreSelected;
}
-
// if we have selection and use it
if (aFirstValue.get() && isValidSelectionCustom(aFirstValue) &&
aFirstValue->shape().get()) { /// Trihedron Axis may be selected, but shape is empty
QIntList aModes;
std::shared_ptr<GeomAPI_Pln> aPlane = plane();
if (aPlane.get()) {
- //QList<std::shared_ptr<ModuleBase_ViewerPrs>> aEdges = findCircularEdgesInPlane();
- //foreach(std::shared_ptr<ModuleBase_ViewerPrs> aPrs, aEdges) {
- //}
myWorkshop->module()->activeSelectionModes(aModes);
}
else {
setResult(aResult);
// do not activate part by simple execution if it is not loaded yet: it must be explicitly
// activated for this
- if (!ModelAPI_Session::get()->isLoadByDemand(aResult->data()->name())) {
+ std::shared_ptr<ModelAPI_AttributeDocRef> aDocRef =
+ aResult->data()->document(ModelAPI_ResultPart::DOC_REF());
+ if (!ModelAPI_Session::get()->isLoadByDemand(aResult->data()->name(), aDocRef->docId())) {
// On undo/redo creation of the part result the Object Browser must get creation event
// earlier that activation of this part event (otherwise the crash is produced)
// So, send a creation event earlier, without any grouping
from GeomDataAPI import *
from ModelAPI import ModelAPI_Feature
import math
+from salome.shaper.model import sketcher
+
+TOLERANCE = 1.e-7
aShapeTypes = {
GeomAPI_Shape.SOLID: "GeomAPI_Shape.SOLID",
""" Tests if all faces of result have a name
:param theFeature: feature to test.
"""
+ # open transaction since all the checking are performed in tests after model.end() call
+ theModel.begin()
# Get feature result/sub-result
aResult = theFeature.results()[0].resultSubShapePair()[0]
# Get result/sub-result shape
shapeExplorer.next()
# Create group with this selection list
Group_1 = theModel.addGroup(thePartDoc, selectionList)
+ theModel.end()
+
+ # Now you can check that all selected shapes in group have right shape type and name.
+ groupFeature = Group_1.feature()
+ groupSelectionList = groupFeature.selectionList("group_list")
+ assert(groupSelectionList.size() == len(selectionList))
+ for index in range(0, groupSelectionList.size()):
+ attrSelection = groupSelectionList.value(index)
+ shape = attrSelection.value()
+ name = attrSelection.namingName()
+ assert(shape.isFace())
+ assert(name != ""), "String empty"
+
+def testHaveNamingEdges(theFeature, theModel, thePartDoc) :
+ """ Tests if all faces of result have a name
+ :param theFeature: feature to test.
+ """
+ # Get feature result/sub-result
+ aResult = theFeature.results()[0].resultSubShapePair()[0]
+ # Get result/sub-result shape
+ shape = aResult.shape()
+ # Create shape explorer with desired shape type
+ shapeExplorer = GeomAPI_ShapeExplorer(shape, GeomAPI_Shape.EDGE)
+ # Create list, and store selections in it
+ selectionList = []
+ while shapeExplorer.more():
+ selection = theModel.selection(aResult, shapeExplorer.current()) # First argument should be result/sub-result, second is sub-shape on this result/sub-result
+ selectionList.append(selection)
+ shapeExplorer.next()
+ # Create group with this selection list
+ Group_1 = theModel.addGroup(thePartDoc, selectionList)
theModel.do()
theModel.end()
attrSelection = groupSelectionList.value(index)
shape = attrSelection.value()
name = attrSelection.namingName()
- assert(shape.isFace())
+ assert(shape.isEdge())
assert(name != ""), "String empty"
+
def testNbSubFeatures(theComposite, theKindOfSub, theExpectedCount):
""" Tests number of sub-features of the given type
:param theComposite composite feature to check its subs
if aFeature is not None and aFeature.getKind() == theKindOfSub:
count += 1
assert (count == theExpectedCount), "Number of sub-features of type {}: {}, expected {}".format(theKindOfSub, count, theExpectedCount)
+
+def assertSketchArc(theArcFeature):
+ """ Tests whether the arc is correctly defined
+ """
+ aCenterPnt = geomDataAPI_Point2D(theArcFeature.attribute("center_point"))
+ aStartPnt = geomDataAPI_Point2D(theArcFeature.attribute("start_point"))
+ aEndPnt = geomDataAPI_Point2D(theArcFeature.attribute("end_point"))
+ aRadius = theArcFeature.real("radius")
+ aDistCS = sketcher.tools.distancePointPoint(aCenterPnt, aStartPnt)
+ aDistCE = sketcher.tools.distancePointPoint(aCenterPnt, aEndPnt)
+ assert math.fabs(aDistCS - aDistCE) < TOLERANCE, "Wrong arc: center-start distance {}, center-end distance {}".format(aDistCS, aDistCE)
+ assert math.fabs(aRadius.value() -aDistCS) < TOLERANCE, "Wrong arc: radius is {0}, expected {1}".format(aRadius.value(), aDistCS)
${OCCViewer}
${qtx}
${CAS_SHAPE}
+ ${SalomeObject}
)
ADD_DEFINITIONS( -DSHAPERGUI_EXPORTS ${CAS_DEFINITIONS} )
#include <SUIT_ViewManager.h>
#include <QtxActionToolMgr.h>
+#include <SALOME_AISShape.hxx>
#include <SelectMgr_ListIteratorOfListOfFilter.hxx>
//**********************************************
void SHAPERGUI_SalomeViewer::eraseAll()
{
- SOCC_Viewer* aViewer = dynamic_cast<SOCC_Viewer*>(myView->viewer());
- aViewer->EraseAll(0);
+ Handle(AIS_InteractiveContext) aContext = AISContext();
+ AIS_ListOfInteractive aList;
+ aContext->DisplayedObjects(aList);
+ AIS_ListIteratorOfListOfInteractive aLIt;
+ Handle(AIS_InteractiveObject) anAISIO;
+ for (aLIt.Initialize(aList); aLIt.More(); aLIt.Next()) {
+ anAISIO = aLIt.Value();
+ Handle(Standard_Type) aType = anAISIO->DynamicType();
+ if (anAISIO->IsKind(STANDARD_TYPE(SALOME_AISShape))) {
+ aContext->Erase(anAISIO, false);
+ }
+ }
}
//**********************************************
SketchPlugin_ConstraintDistanceHorizontal.h
SketchPlugin_ConstraintDistanceVertical.h
SketchPlugin_ConstraintEqual.h
+ SketchPlugin_Fillet.h
SketchPlugin_ConstraintHorizontal.h
SketchPlugin_ConstraintLength.h
SketchPlugin_ConstraintMiddle.h
SketchPlugin_Ellipse.h
SketchPlugin_ExternalValidator.h
SketchPlugin_Feature.h
- SketchPlugin_Fillet.h
SketchPlugin_IntersectionPoint.h
SketchPlugin_Line.h
SketchPlugin_MacroArc.h
SketchPlugin_ConstraintDistanceHorizontal.cpp
SketchPlugin_ConstraintDistanceVertical.cpp
SketchPlugin_ConstraintEqual.cpp
+ SketchPlugin_Fillet.cpp
SketchPlugin_ConstraintHorizontal.cpp
SketchPlugin_ConstraintLength.cpp
SketchPlugin_ConstraintMiddle.cpp
SketchPlugin_Ellipse.cpp
SketchPlugin_ExternalValidator.cpp
SketchPlugin_Feature.cpp
- SketchPlugin_Fillet.cpp
SketchPlugin_IntersectionPoint.cpp
SketchPlugin_Line.cpp
SketchPlugin_MacroArc.cpp
TestTrimCircleAndArc01.py
TestTrimLine01.py
TestTrimLine02.py
- TestMovePoint.py
- TestMoveLine.py
- TestMoveCircle.py
- TestMoveArc.py
- TestMovementComplex.py
+ Test2229.py
+ Test2239.py
TestDistanceSignedVsUnsigned01.py
TestDistanceSignedVsUnsigned02.py
TestDistanceSignedVsUnsigned03.py
TestSignedDistancePointPoint.py
TestSignedDistancePointLine.py
)
+
+if(${SKETCHER_CHANGE_RADIUS_WHEN_MOVE})
+ ADD_UNIT_TESTS(
+ TestMovePoint.py
+ TestMoveLine.py
+ TestMoveCircle.py
+ TestMoveArc.py
+ TestMovementComplex.py
+ )
+endif()
\ No newline at end of file
{
if (!sketch())
return false;
- std::shared_ptr<GeomAPI_Pln> aPlane = sketch()->plane();
std::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = std::dynamic_pointer_cast<
ModelAPI_AttributeRefAttr>(data()->attribute(SketchPlugin_Constraint::ENTITY_A()));
if (!anAttr)
SketchPlugin_Tools::findCoincidences(theConstraintCoincidence,
SketchPlugin_ConstraintCoincidence::ENTITY_A(),
- aCoincides);
+ aCoincides,
+ true);
SketchPlugin_Tools::findCoincidences(theConstraintCoincidence,
SketchPlugin_ConstraintCoincidence::ENTITY_B(),
- aCoincides);
+ aCoincides,
+ true);
// Remove points from set of coincides.
std::set<FeaturePtr> aNewSetOfCoincides;
for(std::set<FeaturePtr>::iterator anIt = aCoincides.begin(); anIt != aCoincides.end(); ++anIt) {
std::shared_ptr<SketchPlugin_SketchEntity> aSketchEntity =
std::dynamic_pointer_cast<SketchPlugin_SketchEntity>(*anIt);
- if(aSketchEntity.get() && aSketchEntity->isCopy()) {
+ if(aSketchEntity.get() && (aSketchEntity->isCopy() || aSketchEntity->isExternal())) {
continue;
}
if((*anIt)->getKind() == SketchPlugin_Line::ID()) {
AISObjectPtr SketchPlugin_MacroArc::getAISObject(AISObjectPtr thePrevious)
{
- if(!myStart.get() || !myEnd.get() || !myCenter.get()) {
+ GeomShapePtr anArcShape = getArcShape();
+ if(!anArcShape.get())
return AISObjectPtr();
- }
SketchPlugin_Sketch* aSketch = sketch();
- if(!aSketch) {
- return AISObjectPtr();
- }
-
- GeomShapePtr anArcShape = getArcShape();
std::shared_ptr<GeomAPI_Pnt> aCenter = aSketch->to3D(myCenter->x(), myCenter->y());;
GeomShapePtr aCenterPointShape = GeomAlgoAPI_PointBuilder::vertex(aCenter);
- if(!anArcShape.get() || !aCenterPointShape.get()) {
+ if(!aCenterPointShape.get())
return AISObjectPtr();
- }
std::list<std::shared_ptr<GeomAPI_Shape> > aShapes;
aShapes.push_back(anArcShape);
}
void SketchPlugin_MacroCircle::attributeChanged(const std::string& theID) {
+ double aRadius = 0.0;
// If circle type switched reset all attributes.
if(theID == CIRCLE_TYPE()) {
SketchPlugin_Tools::resetAttribute(this, CENTER_POINT_ID());
void findCoincidences(const FeaturePtr theStartCoin,
const std::string& theAttr,
- std::set<FeaturePtr>& theList)
+ std::set<FeaturePtr>& theList,
+ const bool theIsAttrOnly)
{
AttributeRefAttrPtr aPnt = theStartCoin->refattr(theAttr);
if(!aPnt) {
if(aOrig.get() == NULL) {
return;
}
- theList.insert(aObj);
+ if(!theIsAttrOnly || !aPnt->isObject()) {
+ theList.insert(aObj);
+ }
std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(aObj);
std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
for (; aCIt != aCoincidences.end(); ++aCIt) {
FeaturePtr aConstrFeature = *aCIt;
std::shared_ptr<GeomAPI_Pnt2d> aPnt = getCoincidencePoint(aConstrFeature);
if(aPnt.get() && aOrig->isEqual(aPnt)) {
- findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A(), theList);
- findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_B(), theList);
+ findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A(),
+ theList, theIsAttrOnly);
+ findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_B(),
+ theList, theIsAttrOnly);
}
}
}
/// \param[in] theStartCoin coincidence feature
/// \param[in] theAttr attribute name
/// \param[out] theList list of lines
+/// \param[in] theIsAttrOnly if true includes only coincidences with attributes.
void findCoincidences(const FeaturePtr theStartCoin,
const std::string& theAttr,
- std::set<FeaturePtr>& theList);
+ std::set<FeaturePtr>& theList,
+ const bool theIsAttrOnly = false);
/// Find all features the point is coincident to.
std::set<FeaturePtr> findFeaturesCoincidentToPoint(const AttributePoint2DPtr& thePoint);
std::set<FeaturePtr> aCoinsides;
SketchPlugin_Tools::findCoincidences(aConstraintCoincidence,
SketchPlugin_ConstraintCoincidence::ENTITY_A(),
- aCoinsides);
+ aCoinsides,
+ true);
SketchPlugin_Tools::findCoincidences(aConstraintCoincidence,
SketchPlugin_ConstraintCoincidence::ENTITY_B(),
- aCoinsides);
+ aCoinsides,
+ true);
- // Remove points from set of coincides.
+ // Remove points and external lines from set of coincides.
std::set<FeaturePtr> aNewSetOfCoincides;
for(std::set<FeaturePtr>::iterator anIt = aCoinsides.begin();
anIt != aCoinsides.end(); ++anIt) {
std::shared_ptr<SketchPlugin_SketchEntity> aSketchEntity =
std::dynamic_pointer_cast<SketchPlugin_SketchEntity>(*anIt);
- if(aSketchEntity.get() && aSketchEntity->isCopy()) {
+ if(aSketchEntity.get() && (aSketchEntity->isCopy() || aSketchEntity->isExternal())) {
continue;
}
if((*anIt)->getKind() != SketchPlugin_Line::ID() &&
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+from ModelAPI import *
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+model.addParameter(Part_1_doc, "Wall_R", "6.188")
+model.addParameter(Part_1_doc, "Wall_T1", "0.089")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchPoint_1 = Sketch_1.addPoint(0, 2.424999999999997)
+SketchLine_1 = Sketch_1.addLine(model.selection("EDGE", "PartSet/OY"))
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchPoint_1.coordinates(), SketchLine_1.result())
+SketchConstraintRigid_1 = Sketch_1.setFixed(SketchPoint_1.coordinates())
+SketchLine_2 = Sketch_1.addLine(6.277, 3.700188311077954, 6.277, -1.894463229482514)
+SketchLine_2.setAuxiliary(True)
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintDistance_1 = Sketch_1.setDistance(SketchPoint_1.coordinates(), SketchLine_2.result(), "Wall_R+Wall_T1")
+model.end()
+
+# check that resulting sketch is valid
+aFactory = ModelAPI_Session.get().validators()
+assert(aFactory.validate(Sketch_1.feature()))
--- /dev/null
+## Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU Lesser General Public
+## License along with this library; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+## See http:##www.salome-platform.org/ or
+## email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+##
+
+"""
+ Test2239.py
+ Test case for issue #2239 "Sketch not updated after having changed the parameter of multi-translation to 1"
+"""
+
+from salome.shaper import model
+
+model.begin()
+partSet = model.moduleDocument()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Parameter_N = model.addParameter(Part_1_doc, "N", "5")
+Sketch_1 = model.addSketch(Part_1_doc, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(20, 0, 0, 0)
+SketchPoint_1 = Sketch_1.addPoint(model.selection("VERTEX", "PartSet/Origin"))
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchPoint_1.result())
+SketchLine_2 = Sketch_1.addLine(0, 0, 0, 20)
+SketchLine_3 = Sketch_1.addLine(0, 20, 20, 20)
+SketchLine_4 = Sketch_1.addLine(20, 20, 20, 0)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintEqual_1 = Sketch_1.setEqual(SketchLine_3.result(), SketchLine_4.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_3.result(), 20)
+SketchLine_5 = Sketch_1.addLine(20, 0, 30, 0)
+SketchLine_5.setAuxiliary(True)
+SketchConstraintHorizontal_3 = Sketch_1.setHorizontal(SketchLine_5.result())
+SketchConstraintCoincidence_6 = Sketch_1.setCoincident(SketchLine_5.startPoint(), SketchLine_1.startPoint())
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_5.result(), 10)
+SketchMultiTranslation_1_objects = [SketchLine_1.result(), SketchLine_2.result(), SketchLine_3.result(), SketchLine_4.result()]
+SketchMultiTranslation_1 = Sketch_1.addTranslation(SketchMultiTranslation_1_objects, SketchLine_1.endPoint(), SketchLine_5.endPoint(), "N")
+model.do()
+
+from GeomAPI import GeomAPI_Shape
+
+model.testNbResults(Sketch_1, 1)
+model.testNbSubShapes(Sketch_1, GeomAPI_Shape.EDGE, [20])
+model.testNbSubShapes(Sketch_1, GeomAPI_Shape.VERTEX, [40])
+
+# check MultiTranslation error
+Parameter_N.setValue(1)
+model.do()
+assert(SketchMultiTranslation_1.feature().error() != "")
+
+
+# check MultiTranslation error disappears
+Parameter_N.setValue(2)
+model.do()
+assert(SketchMultiTranslation_1.feature().error() == "")
+
+model.testNbResults(Sketch_1, 1)
+model.testNbSubShapes(Sketch_1, GeomAPI_Shape.EDGE, [8])
+model.testNbSubShapes(Sketch_1, GeomAPI_Shape.VERTEX, [16])
+
+# check MultiTranslation is still correct
+Parameter_N.setValue(5)
+model.do()
+assert(SketchMultiTranslation_1.feature().error() == "")
+
+model.testNbResults(Sketch_1, 1)
+model.testNbSubShapes(Sketch_1, GeomAPI_Shape.EDGE, [20])
+model.testNbSubShapes(Sketch_1, GeomAPI_Shape.VERTEX, [40])
+
+model.end()
+
+
+assert(model.checkPythonDump())
label="Total number of objects"
tooltip="Total number of objects"
default="2" min="2" use_reset="false">
- <validator id="GeomValidators_Positive"/>
+ <validator id="GeomValidators_Positive" parameters="1"/>
</integervalue>
<validator id="PartSet_MultyTranslationSelection" />
</feature>
label="Total number of objects"
tooltip="Total number of objects"
default="2" min="2" use_reset="false">
- <validator id="GeomValidators_Positive"/>
+ <validator id="GeomValidators_Positive" parameters="1"/>
</integervalue>
<validator id="PartSet_MultyTranslationSelection" />
</feature>
<validator id="SketchPlugin_ExternalValidator" parameters="ConstraintEntityB"/>
<validator id="PartSet_DifferentObjects"/>
<validator id="GeomValidators_ShapeType" parameters="vertex,line"/>
+ <validator id="PartSet_DifferentPoints" parameters="ConstraintEntityB"/>
</sketch_shape_selector>
<sketch_shape_selector
id="ConstraintEntityB"
<validator id="SketchPlugin_DistanceAttr" parameters="ConstraintEntityA"/>
<validator id="SketchPlugin_ExternalValidator" parameters="ConstraintEntityA"/>
<validator id="GeomValidators_ShapeType" parameters="vertex,line"/>
+ <validator id="PartSet_DifferentPoints" parameters="ConstraintEntityA"/>
</sketch_shape_selector>
<sketch-2dpoint_flyout_selector id="ConstraintFlyoutValuePnt" default="computed" internal="1" obligatory="0"/>
${SKETCHSOLVER_CONSTRAINT_SOURCES}
)
+if(${SKETCHER_CHANGE_RADIUS_WHEN_MOVE})
+ ADD_DEFINITIONS(-DCHANGE_RADIUS_WHILE_MOVE)
+endif()
+
ADD_LIBRARY(PlaneGCSSolver MODULE ${PROJECT_SOURCES} ${PROJECT_HEADERS} ${SKETCHSOLVER_TEXT_RESOURCES})
TARGET_LINK_LIBRARIES(PlaneGCSSolver ${PROJECT_LIBRARIES} ${SKETCHSOLVER_LIBRARIES})
INSTALL(TARGETS PlaneGCSSolver DESTINATION ${SHAPER_INSTALL_PLUGIN_FILES})
static bool isSimpleMove(FeaturePtr theMovedFeature, AttributePtr theDraggedPoint)
{
bool isSimple = true;
+#ifdef CHANGE_RADIUS_WHILE_MOVE
if (theMovedFeature->getKind() == SketchPlugin_Circle::ID())
isSimple = (theDraggedPoint.get() != 0);
else if (theMovedFeature->getKind() == SketchPlugin_Arc::ID()) {
isSimple = (theDraggedPoint.get() != 0 &&
theDraggedPoint->id() == SketchPlugin_Arc::CENTER_ID());
}
+#endif
return isSimple;
}
double aDelta[2] = { theDestinationPoint->x() - myStartPoint->x(),
theDestinationPoint->y() - myStartPoint->y() };
+#ifdef CHANGE_RADIUS_WHILE_MOVE
int aMaxSize = mySimpleMove ? (int)myFixedValues.size() : 2;
+#else
+ int aMaxSize = myMovedFeature->getKind() == SketchPlugin_Line::ID() && !myDraggedPoint ? 4 : 2;
+#endif
for (int i = 0; i < aMaxSize; ++i)
myFixedValues[i] += aDelta[i % 2];
}
#include <ModelAPI_ResultConstruction.h>
#include <ModelAPI_Session.h>
#include <ModelAPI_Validator.h>
-#include <SketchPlugin_Constraint.h>
#include <SketchPlugin_Sketch.h>
/// Global constraint manager object
Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_DELETED));
Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_MOVED));
+ ////Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_SOLVER_FAILED));
+ ////Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_SOLVER_REPAIRED));
Events_Loop::loop()->registerListener(this, Events_Loop::eventByName(EVENT_SKETCH_PREPARED));
}
bool isUpdateFlushed = false;
bool isMovedEvt = false;
+ static const Events_ID aCreatedEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
static const Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
static const Events_ID aSketchPreparedEvent = Events_Loop::eventByName(EVENT_SKETCH_PREPARED);
// sketch is prepared for resolve: all the needed events
return;
myIsComputed = true;
- if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED)
- || theMessage->eventID() == anUpdateEvent) {
+ if (theMessage->eventID() == aCreatedEvent || theMessage->eventID() == anUpdateEvent) {
std::shared_ptr<ModelAPI_ObjectUpdatedMessage> anUpdateMsg =
std::dynamic_pointer_cast<ModelAPI_ObjectUpdatedMessage>(theMessage);
- std::set<ObjectPtr> aFeatures = anUpdateMsg->objects();
isUpdateFlushed = stopSendUpdate();
// update sketch features only
- std::set<ObjectPtr>::iterator aFeatIter;
- for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) {
- std::shared_ptr<SketchPlugin_Feature> aFeature =
- std::dynamic_pointer_cast<SketchPlugin_Feature>(*aFeatIter);
- if (!aFeature || aFeature->isMacro())
- continue;
-
- updateFeature(aFeature);
+ const std::set<ObjectPtr>& aFeatures = anUpdateMsg->objects();
+ // try to keep order as features were created if there are several created features: #2229
+ if (theMessage->eventID() == aCreatedEvent && aFeatures.size() > 1) {
+ std::map<int, std::shared_ptr<SketchPlugin_Feature>> anOrderedFeatures;
+ std::set<ObjectPtr>::iterator aFeatIter;
+ for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) {
+ std::shared_ptr<SketchPlugin_Feature> aFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(*aFeatIter);
+ if (aFeature && !aFeature->isMacro() && aFeature->data() && aFeature->data()->isValid()) {
+ anOrderedFeatures[aFeature->data()->featureId()] = aFeature;
+ }
+ }
+ std::map<int, std::shared_ptr<SketchPlugin_Feature>>::iterator aFeat;
+ for(aFeat = anOrderedFeatures.begin(); aFeat != anOrderedFeatures.end(); aFeat++) {
+ updateFeature(aFeat->second);
+ }
+ } else { // order is not important
+ std::set<ObjectPtr>::iterator aFeatIter;
+ for (aFeatIter = aFeatures.begin(); aFeatIter != aFeatures.end(); aFeatIter++) {
+ std::shared_ptr<SketchPlugin_Feature> aFeature =
+ std::dynamic_pointer_cast<SketchPlugin_Feature>(*aFeatIter);
+ if (aFeature && !aFeature->isMacro())
+ updateFeature(aFeature);
+ }
}
} else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_MOVED)) {
void XGUI_ContextMenuMgr::onRename()
{
QObjectPtrList anObjects = myWorkshop->selector()->selection()->selectedObjects();
- if (!myWorkshop->operationMgr()->abortAllOperations())
+ if (!myWorkshop->abortAllOperations())
return;
// restore selection in case if dialog box was shown
myWorkshop->objectBrowser()->setObjectsSelected(anObjects);
const NCollection_DataMap<TopoDS_Shape,
NCollection_Map<Handle(AIS_InteractiveObject)>>& theShapesToBeSelected)
{
+ NCollection_Map<Handle(AIS_InteractiveObject)> aCompsolidPresentations;
+ NCollection_Map<Handle(AIS_InteractiveObject)> aSelectedPresentations;
+
NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners;
theContext->MainSelector()->ActiveOwners(anActiveOwners);
NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (anActiveOwners);
if (aShape.IsNull())
continue;
+ Handle(ModuleBase_BRepOwner) aCustomOwner = Handle(ModuleBase_BRepOwner)::DownCast(anOwner);
+
NCollection_DataMap<TopoDS_Shape, NCollection_Map<Handle(AIS_InteractiveObject)> >
::Iterator aShapeIt(theShapesToBeSelected);
for (; aShapeIt.More(); aShapeIt.Next()) {
- if (aShapeIt.Key().IsSame(aShape)) {
- const TopoDS_Shape& aParameterShape = aShapeIt.Key();
- // isSame should be used here as it does not check orientation of shapes
- // despite on isEqual of shapes or IsBound for shape in QMap. Orientation is
- // different for Edges shapes in model shape and owner even if this is the same shape
- if (aParameterShape.IsSame(aShape)) {
- Handle(AIS_InteractiveObject) anOwnerPresentation =
- Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable());
- NCollection_Map<Handle(AIS_InteractiveObject)> aPresentations =
- theShapesToBeSelected.Find(aParameterShape);
- if (aPresentations.Contains(anOwnerPresentation)) {
- theContext->AddOrRemoveSelected(anOwner);
- anOwner->SetSelected (Standard_True);
- }
+ const TopoDS_Shape& aParameterShape = aShapeIt.Key();
+ // isSame should be used here as it does not check orientation of shapes
+ // despite on isEqual of shapes or IsBound for shape in QMap. Orientation is
+ // different for Edges shapes in model shape and owner even if this is the same shape
+ if (aParameterShape.IsSame(aShape)) {
+ Handle(AIS_InteractiveObject) anOwnerPresentation =
+ Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable());
+ NCollection_Map<Handle(AIS_InteractiveObject)> aPresentations =
+ theShapesToBeSelected.Find(aParameterShape);
+ if (aPresentations.Contains(anOwnerPresentation)) {
+ theContext->AddOrRemoveSelected(anOwner, Standard_False);
+ anOwner->SetSelected (Standard_True);
+ // collect selected presentations to do not select them if compsolid is selected
+ if (!aSelectedPresentations.Contains(anOwnerPresentation))
+ aSelectedPresentations.Add(anOwnerPresentation);
}
}
+ else if (!aCustomOwner.IsNull()) { // CompSolid processing #2219
+ // shape of owner is compound, but shape to be selected is compsolid, so
+ // we need to compare shape to AIS presentation of owner(rule of the owner creation)
+ Handle(AIS_Shape) anOwnerPresentation =
+ Handle(AIS_Shape)::DownCast(anOwner->Selectable());
+ const TopoDS_Shape& aPresentationShape = anOwnerPresentation->Shape();
+ if (aParameterShape.IsSame(anOwnerPresentation->Shape()) &&
+ !aCompsolidPresentations.Contains(anOwnerPresentation))
+ aCompsolidPresentations.Add(anOwnerPresentation);
+ }
}
}
}
+ // select CompSolid presentations if their owners was not selected yet
+ NCollection_Map<Handle(AIS_InteractiveObject)>::Iterator anIt (aCompsolidPresentations);
+ for (; anIt.More(); anIt.Next()) {
+ if (aSelectedPresentations.Contains(anIt.Value()))
+ continue;
+ theContext->AddOrRemoveSelected(anIt.Value(), Standard_False);
+ }
}
}
if (aNestedActions.contains(FEATURE_WHEN_NESTED_ABORT)) {
QAction* anAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AbortAll);
- QObject::connect(anAction, SIGNAL(triggered()),
- anOperationMgr, SLOT(onAbortAllOperations()));
+ QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(abortAllOperations()));
aNestedActList << anAction;
}
}
}
if (aNestedActions.contains(FEATURE_WHEN_NESTED_ABORT)) {
QAction* anAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AbortAll);
- QObject::connect(anAction, SIGNAL(triggered()),
- anOperationMgr, SLOT(onAbortAllOperations()));
+ QObject::connect(anAction, SIGNAL(triggered()), anOperationMgr, SLOT(abortAllOperations()));
aNestedActList << anAction;
}
anAction = aSalomeConnector->addFeatureOfNested(theWchName.c_str(), aFeatureInfo,
return myWorkshop->desktop();
}
+bool XGUI_ModuleConnector::hasSHIFTPressed() const
+{
+ return myWorkshop->operationMgr()->hasSHIFTPressed();
+}
std::shared_ptr<Config_FeatureMessage> XGUI_ModuleConnector::featureInfo(const QString& theId) const
{
/// Return application main window
virtual QMainWindow* desktop() const;
+ /// Returns true if SHIFT is pressed
+ /// \return boolean value
+ virtual bool hasSHIFTPressed() const;
//! Returns workshop
XGUI_Workshop* workshop() const { return myWorkshop; }
virtual bool eventFilter(QObject *theObject, QEvent *theEvent)
{
bool isAccepted = false;
- if (myIsActive && theEvent->type() == QEvent::KeyRelease) {
- QKeyEvent* aKeyEvent = dynamic_cast<QKeyEvent*>(theEvent);
- if (aKeyEvent) {
- switch (aKeyEvent->key()) {
- case Qt::Key_Delete:
- isAccepted = myOperationMgr->onProcessDelete(theObject);
- break;
- default:
- isAccepted = myOperationMgr->onKeyReleased(theObject, aKeyEvent);
+ if (myIsActive) {
+ if (theEvent->type() == QEvent::KeyRelease) {
+ QKeyEvent* aKeyEvent = dynamic_cast<QKeyEvent*>(theEvent);
+ if (aKeyEvent) {
+ myOperationMgr->setSHIFTPressed(aKeyEvent->modifiers() & Qt::ShiftModifier);
+ switch (aKeyEvent->key()) {
+ case Qt::Key_Delete:
+ isAccepted = myOperationMgr->onProcessDelete(theObject);
break;
+ default:
+ isAccepted = myOperationMgr->onKeyReleased(theObject, aKeyEvent);
+ break;
+ }
}
}
+ else if (theEvent->type() == QEvent::KeyPress) {
+ QKeyEvent* aKeyEvent = dynamic_cast<QKeyEvent*>(theEvent);
+ myOperationMgr->setSHIFTPressed(aKeyEvent->modifiers() & Qt::ShiftModifier);
+ }
}
if (!isAccepted)
isAccepted = QObject::eventFilter(theObject, theEvent);
XGUI_OperationMgr::XGUI_OperationMgr(QObject* theParent,
ModuleBase_IWorkshop* theWorkshop)
-: QObject(theParent), myWorkshop(theWorkshop)
+: QObject(theParent), myWorkshop(theWorkshop), mySHIFTPressed(false)
{
/// we need to install filter to the application in order to react to 'Delete' key button
/// this key can not be a short cut for a corresponded action because we need to set
return isStarted;
}
-void XGUI_OperationMgr::onAbortAllOperations()
-{
- abortAllOperations();
-}
-
-bool XGUI_OperationMgr::abortAllOperations(const XGUI_MessageKind& theMessageKind)
+bool XGUI_OperationMgr::abortAllOperations()
{
bool aResult = true;
if(!hasOperation())
if (operationsCount() == 1) {
ModuleBase_Operation* aCurrentOperation = currentOperation();
- if (canStopOperation(aCurrentOperation, theMessageKind)) {
+ if (canStopOperation(aCurrentOperation)) {
abortOperation(aCurrentOperation);
}
else
aResult = false;
}
else {
- if (theMessageKind == XGUI_AbortOperationMessage) {
- aResult = QMessageBox::question(qApp->activeWindow(),
- tr("Abort operation"),
- tr("All active operations will be aborted."),
- QMessageBox::Ok | QMessageBox::Cancel,
- QMessageBox::Cancel) == QMessageBox::Ok;
- }
- else if (theMessageKind == XGUI_InformationMessage) {
- QString aMessage = tr("Please validate all your active operations before saving.");
- QMessageBox::question(qApp->activeWindow(),
- tr("Validate operation"),
- aMessage,
- QMessageBox::Ok,
- QMessageBox::Ok);
- aResult = false; // do not perform abort
- }
+ aResult = QMessageBox::question(qApp->activeWindow(),
+ tr("Abort operation"),
+ tr("All active operations will be aborted."),
+ QMessageBox::Ok | QMessageBox::Cancel,
+ QMessageBox::Cancel) == QMessageBox::Ok;
while(aResult && hasOperation()) {
abortOperation(currentOperation());
}
while (hasOperation()) {
ModuleBase_Operation* anOperation = currentOperation();
if (XGUI_Tools::workshop(myWorkshop)->errorMgr()->isApplyEnabled()) {
- anOperationProcessed = commitOperation();
+ anOperationProcessed = onCommitOperation();
} else {
abortOperation(anOperation);
anOperationProcessed = true;
onValidateOperation();
}
-bool XGUI_OperationMgr::canStopOperation(ModuleBase_Operation* theOperation,
- const XGUI_OperationMgr::XGUI_MessageKind& theMessageKind)
+bool XGUI_OperationMgr::canStopOperation(ModuleBase_Operation* theOperation)
{
//in case of nested (sketch) operation no confirmation needed
if (isGrantedOperation(theOperation->id()))
return true;
if (theOperation && theOperation->isModified()) {
- if (theMessageKind == XGUI_AbortOperationMessage) {
- QString aMessage = tr("%1 operation will be aborted.").arg(theOperation->id());
- int anAnswer = QMessageBox::question(qApp->activeWindow(),
- tr("Abort operation"),
- aMessage,
- QMessageBox::Ok | QMessageBox::Cancel,
- QMessageBox::Cancel);
- return anAnswer == QMessageBox::Ok;
- }
- else if (theMessageKind == XGUI_InformationMessage) {
- QString aMessage = tr("Please validate your %1 before saving.").arg(theOperation->id());
- QMessageBox::question(qApp->activeWindow(),
- tr("Validate operation"),
- aMessage,
- QMessageBox::Ok,
- QMessageBox::Ok);
- return false;
- }
+ QString aMessage = tr("%1 operation will be aborted.").arg(theOperation->id());
+ int anAnswer = QMessageBox::question(qApp->activeWindow(),
+ tr("Abort operation"),
+ aMessage,
+ QMessageBox::Ok | QMessageBox::Cancel,
+ QMessageBox::Cancel);
+ return anAnswer == QMessageBox::Ok;
}
return true;
}
+bool XGUI_OperationMgr::commitOperation()
+{
+ //if (hasOperation() && currentOperation()->isValid()) {
+ // onCommitOperation();
+ // return true;
+ //}
+ //return false;
+ return onCommitOperation();
+}
+
void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation)
{
theOperation->resume();
}
}
-bool XGUI_OperationMgr::commitOperation()
+bool XGUI_OperationMgr::onCommitOperation()
{
bool isCommitted = false;
ModuleBase_Operation* anOperation = currentOperation();
class XGUI_EXPORT XGUI_OperationMgr : public QObject
{
Q_OBJECT
-public:
- /// Enumeration of kind of message that is used when trying to stop the active operation
- enum XGUI_MessageKind
- {
- XGUI_AbortOperationMessage, //< warns and give possibility to abort current operation
- XGUI_InformationMessage //< ask to apply the current operation before performing something
- };
-
-public:
+ public:
/// Constructor
/// \param theParent the parent
/// \param theWorkshop a reference to workshop
/// Returns true if the operation can be aborted. If the operation is modified,
/// the warning message box is shown.
/// \param theOperation an operation which is checked on stop
- /// \param theMessageKind a kind of message in warning message box
- bool canStopOperation(ModuleBase_Operation* theOperation,
- const XGUI_MessageKind& theMessageKind = XGUI_AbortOperationMessage);
+ bool canStopOperation(ModuleBase_Operation* theOperation);
/// Find and return operation by its Id.
ModuleBase_Operation* findOperation(const QString& theId) const;
/// \param theOperation an aborted operation
void abortOperation(ModuleBase_Operation* theOperation);
- bool abortAllOperations(const XGUI_MessageKind& theMessageKind = XGUI_AbortOperationMessage);
+ /// Slot that commits the current operation.
+ bool onCommitOperation();
+
+ /// Returns true if SHIFT is pressed
+ /// \param thePressed new boolean state
+ void setSHIFTPressed(const bool thePressed) { mySHIFTPressed = thePressed; }
+
+ /// Returns true if SHIFT is pressed
+ /// \return boolean value
+ bool hasSHIFTPressed() const { return mySHIFTPressed; }
public slots:
/// Slot that aborts the current operation.
/// Commit all operations
bool commitAllOperations();
/// Abort all operations
- void onAbortAllOperations();
-
-protected slots:
-
+ bool abortAllOperations();
signals:
/// Signal about an operation is stopped. It is emitted after the stop() of operation is done.
ModuleBase_IWorkshop* myWorkshop;
XGUI_ShortCutListener* myShortCutListener;
+ bool mySHIFTPressed;
};
#endif
XGUI_Workshop* workshop(ModuleBase_IWorkshop* theWorkshop)
{
XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(theWorkshop);
- if (aConnector)
- return aConnector->workshop();
- return 0;
+ return aConnector->workshop();
}
}
(anOperationMgr->currentOperation());
if (aFOperation) {
//if (errorMgr()->canProcessClick(anAction, aFOperation->feature()))
- myOperationMgr->commitOperation();
+ myOperationMgr->onCommitOperation();
}
}
}
QApplication::restoreOverrideCursor();
}
+//******************************************************
+bool XGUI_Workshop::abortAllOperations()
+{
+ return myOperationMgr->abortAllOperations();
+}
+
//******************************************************
void XGUI_Workshop::operationStarted(ModuleBase_Operation* theOperation)
{
//******************************************************
void XGUI_Workshop::onOpen()
{
- if(!myOperationMgr->abortAllOperations())
+ if(!abortAllOperations())
return;
//save current file before close if modified
SessionPtr aSession = ModelAPI_Session::get();
//******************************************************
bool XGUI_Workshop::onSave()
{
- if(!myOperationMgr->abortAllOperations(XGUI_OperationMgr::XGUI_InformationMessage))
+ if(!abortAllOperations())
return false;
if (myCurrentDir.isEmpty()) {
return onSaveAs();
//******************************************************
bool XGUI_Workshop::onSaveAs()
{
- if(!myOperationMgr->abortAllOperations(XGUI_OperationMgr::XGUI_InformationMessage))
+ if(!abortAllOperations())
return false;
QFileDialog dialog(desktop());
dialog.setWindowTitle(tr("Select directory to save files..."));
aParameters.Append(aContext);
MyVCallBack = new VInspector_CallBack();
+ MyTCommunicator->RegisterPlugin("TKDFBrowser");
+ MyTCommunicator->RegisterPlugin("TKVInspector");
+ MyTCommunicator->RegisterPlugin("TKShapeView");
myDisplayer->setCallBack(MyVCallBack);
#ifndef HAVE_SALOME
AppElements_Viewer* aViewer = mainWindow()->viewer();
}
QObjectPtrList anObjects = mySelector->selection()->selectedObjects();
- if (!myOperationMgr->abortAllOperations())
+ if (!abortAllOperations())
return;
bool hasResult = false;
//**************************************************************
void XGUI_Workshop::cleanHistory()
{
- if (!myOperationMgr->abortAllOperations())
+ if (!abortAllOperations())
return;
QObjectPtrList anObjects = mySelector->selection()->selectedObjects();
//**************************************************************
void XGUI_Workshop::moveObjects()
{
- if (!myOperationMgr->abortAllOperations())
+ if (!abortAllOperations())
return;
SessionPtr aMgr = ModelAPI_Session::get();
if (aColor.size() != 3)
return;
- if (!myOperationMgr->abortAllOperations())
+ if (!abortAllOperations())
return;
// 2. show the dialog to change the value
XGUI_ColorDialog* aDlg = new XGUI_ColorDialog(desktop());
if (aDeflection < 0)
return;
- if (!myOperationMgr->abortAllOperations())
+ if (!abortAllOperations())
return;
// 2. show the dialog to change the value
XGUI_DeflectionDialog* aDlg = new XGUI_DeflectionDialog(desktop());
if (module()->canEraseObject(aObj))
aObj->setDisplayed(false);
}
+ //Do not use eraseAll if you didn't send Redisplay event:
+ //all objects are erased from viewer, but considered as displayed in displayer
+ // Problem in bug 2218
Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY));
#ifdef HAVE_SALOME
//issue #2159 Hide all incomplete behavior
*/
void saveDocument(const QString& theName, std::list<std::string>& theFileNames);
+ /**
+ * If there is an active (uncommitted) operation shows a prompt to abort it
+ * and performs abortion if user agreed. Returns true if
+ * - operation aborted successfully
+ * - there is no active operation
+ */
+ bool abortAllOperations();
+
/// Updates workshop state according to the started operation, e.g. visualizes the property panel
/// and connect to it.
/// \param theOpertion a started operation
void operationStarted(ModuleBase_Operation* theOperation);
+
//! Delete features. Delete the referenced features. There can be a question with a list of
//! referenced objects.
//! \param theFeatures a list of objects to be deleted
#include <ModelAPI_Result.h>
#include <ModelAPI_Feature.h>
#include <ModelAPI_Data.h>
-#include <ModelAPI_ResultBody.h>
-#include <ModelAPI_ResultGroup.h>
#include <ModelAPI_ResultCompSolid.h>
#include <ModelAPI_Tools.h>
XGUI_Workshop* aWorkshop = workshop();
XGUI_Displayer* aDisplayer = aWorkshop->displayer();
- //bool aFirstVisualizedBody = false;
- bool aDoFitAll = false;
- int aNbOfShownObjects = workshop()->displayer()->objectsCount();
bool aRedisplayed = false;
//std::list<ObjectPtr> aHiddenObjects;
for (aIt = anObjects.begin(); aIt != anObjects.end(); ++aIt) {
}
} else { // display object if the current operation has it
if (displayObject(aObj)) {
- aDoFitAll = aDoFitAll || neededFitAll(aObj, aNbOfShownObjects);
-
aRedisplayed = true;
// Deactivate object of current operation from selection
aWorkshop->deactivateActiveObject(aObj, false);
if (aRedisplayed || isCustomized) {
Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_EMPTY_AIS_PRESENTATION));
- //VSV FitAll updated viewer by itself
- if (aDoFitAll)
- myWorkshop->viewer()->fitAll();
- else
- aDisplayer->updateViewer();
+ aDisplayer->updateViewer();
}
}
.arg(anObjects.size()).arg(anInfoStr).toStdString().c_str());
#endif
- bool aDoFitAll = false;
- int aNbOfShownObjects = workshop()->displayer()->objectsCount();
-
//bool aHasPart = false;
bool aDisplayed = false;
for (aIt = anObjects.begin(); aIt != anObjects.end(); ++aIt) {
if (myWorkshop->module()->canDisplayObject(anObject)) {
anObject->setDisplayed(true);
aDisplayed = displayObject(anObject);
- if (aDisplayed)
- aDoFitAll = aDoFitAll || neededFitAll(anObject, aNbOfShownObjects);
} else
anObject->setDisplayed(false);
}
// myObjectBrowser->processEvent(theMsg);
if (aDisplayed) {
Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_EMPTY_AIS_PRESENTATION));
- //VSV FitAll updated viewer by itself
- if (aDoFitAll)
- myWorkshop->viewer()->fitAll();
- else
- workshop()->displayer()->updateViewer();
+ workshop()->displayer()->updateViewer();
}
//if (aHasPart) { // TODO: Avoid activate last part on loading of document
// activateLastPart();
return aDisplayer->display(theObj, false);
}
-//**************************************************************
-bool XGUI_WorkshopListener::neededFitAll(ObjectPtr theObj, const int theNbOfShownObjects)
-{
- bool aFirstVisualizedBody = false;
-
- if (theNbOfShownObjects == 0) {
- ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObj);
- if (aResult.get()) {
- std::string aResultGroupName = aResult->groupName();
- if (aResultGroupName == ModelAPI_ResultBody::group() ||
- aResultGroupName == ModelAPI_ResultGroup::group()) {
- std::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(aResult);
- aFirstVisualizedBody = aShapePtr.get() != NULL;
- }
- }
- }
- return aFirstVisualizedBody;
-}
-
bool XGUI_WorkshopListener::customizeCurrentObject(const std::set<ObjectPtr>& theObjects,
bool theForceRedisplay)
{
/// \return true if the object is displayed
bool displayObject(ObjectPtr theObj);
- /// Answer if the viewer needed to be fit all after the object visualization
- /// The condition is there is not shown objects and the object is a group or body result
- /// \param theObject a shown object
- /// \param theNbOfShownObjects a count of already shown objects in the viewer
- /// \return true if fit all should be done
- bool neededFitAll(ObjectPtr theObject, const int theNbOfShownObjects);
-
/// Calls the module method of cusomize object for the feature of the current operation
/// Perform cusomize if the force redisplay flag is true or the list of objects contains the
/// current operation feature
Primitives/TestAPI_Cylinder.py
GDML/TestConeSegment.py
GDML/TestAPI_ConeSegment.py
- Transformations/TestScale.py
- Transformations/TestSymmetry.py
- Transformations/TestTranslation.py
+ Transformations/TestAPI_MultiTranslation.py
+ Transformations/TestAPI_Rotation.py
Transformations/TestAPI_Scale.py
Transformations/TestAPI_Symmetry.py
Transformations/TestAPI_Translation.py
+ Transformations/TestMultiTranslation.py
+ Transformations/TestRotation.py
+ Transformations/TestScale.py
+ Transformations/TestSymmetry.py
+ Transformations/TestTranslation_1.py
+ Transformations/TestTranslation_2.py
+ Transformations/TestTranslation_3.py
+ Transformations/TestTranslation_4.py
+ Transformations/TestTranslation_5.py
+ Transformations/TestTranslation.py
)
Translation_14 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "MultiTranslation_5_1")], model.selection("EDGE", "PartSet/OZ"), "d")
Translation_15 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "MultiTranslation_6_1")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_2"), 50)
Translation_16 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "MultiTranslation_7_1")], model.selection("EDGE", "Edge_1_1"), 50)
-Translation_17 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "MultiTranslation_8_1")], model.selection("EDGE", "MultiTranslation_8_1/Translated_Edge_8_8"), 50)
+#Translation_17 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "MultiTranslation_8_1")], model.selection("EDGE", "MultiTranslation_8_1/Translated_Edge_8_8"), 50)
+Translation_17 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "MultiTranslation_8_1")], model.selection("EDGE", "MultiTranslation_8_1/Translated_Face_3_4&MultiTranslation_8_1/Translated_Face_3_1"), 50)
Translation_18 = model.addTranslation(Part_1_doc, [model.selection("COMPOUND", "MultiTranslation_9_1")], model.selection("EDGE", "PartSet/Axis_4"), 50)
Translation_19 = model.addTranslation(partSet, [model.selection("COMPOUND", "Part_2/")], model.selection("EDGE", "OX"), 15)
Translation_20 = model.addTranslation(partSet, [model.selection("COMPOUND", "Part_3/")], model.selection("EDGE", "OX"), 0)
Partition_6 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_30_1"), model.selection("SOLID", "Translation_29_1")])
Translation_41 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_6_1")], model.selection("EDGE", "Sketch_1/Edge-SketchLine_1"), 15)
-# Translateion 42
+# Translation 42
Translation_42_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_31_1")], model.selection("EDGE", "PartSet/OX"), 5)
Partition_7 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_32_1"), model.selection("SOLID", "Translation_31_1")])
Translation_42 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_7_1")], model.selection("EDGE", "Edge_1_1"), 15)
# Translation 43
Translation_43_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_33_1")], model.selection("EDGE", "PartSet/OX"), 5)
Partition_8 = model.addPartition(Part_1_doc, [model.selection("SOLID", "Box_34_1"), model.selection("SOLID", "Translation_33_1")])
-Translation_43 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_8_1")], model.selection("EDGE", "Partition_8_1/Modified_Face_1_1_1&Partition_8_1/Modified_Face_1_9_1"), 15)
+Translation_43 = model.addTranslation(Part_1_doc, [model.selection("COMPSOLID", "Partition_8_1")], model.selection("EDGE", "Partition_8_1_1/Modified_Face_1_4&Partition_8_1_1/Modified_Face_1_1"), 15)
# Translation 44
Translation_44_1 = model.addTranslation(Part_1_doc, [model.selection("SOLID", "Box_35_1")], model.selection("EDGE", "PartSet/OX"), 5)
model.do()
model.end()
-
# Checks
from GeomAPI import GeomAPI_Shape
-from GeomAPI import GeomAPI_ShapeExplorer
-
-def testHaveNamingEdges(theFeature, theModel, thePartDoc) :
- """ Tests if all faces of result have a name
- :param theFeature: feature to test.
- """
- # Get feature result/sub-result
- aResult = theFeature.results()[0].resultSubShapePair()[0]
- # Get result/sub-result shape
- shape = aResult.shape()
- # Create shape explorer with desired shape type
- shapeExplorer = GeomAPI_ShapeExplorer(shape, GeomAPI_Shape.EDGE)
- # Create list, and store selections in it
- selectionList = []
- while shapeExplorer.more():
- selection = theModel.selection(aResult, shapeExplorer.current()) # First argument should be result/sub-result, second is sub-shape on this result/sub-result
- selectionList.append(selection)
- shapeExplorer.next()
- # Create group with this selection list
- Group_1 = theModel.addGroup(thePartDoc, selectionList)
- theModel.do()
- theModel.end()
-
- # Now you can check that all selected shapes in group have right shape type and name.
- groupFeature = Group_1.feature()
- groupSelectionList = groupFeature.selectionList("group_list")
- theModel.end()
- assert(groupSelectionList.size() == len(selectionList))
- for index in range(0, groupSelectionList.size()):
- attrSelection = groupSelectionList.value(index)
- shape = attrSelection.value()
- name = attrSelection.namingName()
- assert(shape.isEdge())
- assert(name != ""), "String empty"
# Translation 27
model.testNbResults(Translation_27, 1)
model.testNbSubResults(Translation_27, [12])
model.testNbSubShapes(Translation_27, GeomAPI_Shape.SOLID, [0])
model.testNbSubShapes(Translation_27, GeomAPI_Shape.EDGE, [12])
-testHaveNamingEdges(Translation_27, model, Part_1_doc)
+model.testHaveNamingEdges(Translation_27, model, Part_1_doc)
# Translation 28
model.testNbResults(Translation_28, 1)
model.testNbSubResults(Translation_28, [12])
model.testNbSubShapes(Translation_28, GeomAPI_Shape.SOLID, [0])
model.testNbSubShapes(Translation_28, GeomAPI_Shape.EDGE, [12])
-testHaveNamingEdges(Translation_28, model, Part_1_doc)
+model.testHaveNamingEdges(Translation_28, model, Part_1_doc)
# Translation 29
model.testNbResults(Translation_29, 1)
model.testNbSubResults(Translation_29, [12])
model.testNbSubShapes(Translation_29, GeomAPI_Shape.SOLID, [0])
model.testNbSubShapes(Translation_29, GeomAPI_Shape.EDGE, [12])
-testHaveNamingEdges(Translation_29, model, Part_1_doc)
+model.testHaveNamingEdges(Translation_29, model, Part_1_doc)
# Translation 31
model.testNbResults(Translation_31, 1)
model.testNbSubResults(Translation_31, [12])
model.testNbSubShapes(Translation_31, GeomAPI_Shape.SOLID, [0])
model.testNbSubShapes(Translation_31, GeomAPI_Shape.EDGE, [12])
-testHaveNamingEdges(Translation_31, model, Part_1_doc)
+model.testHaveNamingEdges(Translation_31, model, Part_1_doc)
# Translation 32
model.testNbResults(Translation_32, 1)
model.testNbSubResults(Translation_32, [12])
model.testNbSubShapes(Translation_32, GeomAPI_Shape.SOLID, [0])
model.testNbSubShapes(Translation_32, GeomAPI_Shape.EDGE, [12])
-testHaveNamingEdges(Translation_32, model, Part_1_doc)
+model.testHaveNamingEdges(Translation_32, model, Part_1_doc)
# Translation 33
model.testNbResults(Translation_33, 1)
model.testNbSubResults(Translation_33, [12])
model.testNbSubShapes(Translation_33, GeomAPI_Shape.SOLID, [0])
model.testNbSubShapes(Translation_33, GeomAPI_Shape.EDGE, [12])
-testHaveNamingEdges(Translation_33, model, Part_1_doc)
+model.testHaveNamingEdges(Translation_33, model, Part_1_doc)
# Translation 34
model.testNbResults(Translation_34, 1)
model.testNbSubResults(Translation_34, [12])
model.testNbSubShapes(Translation_34, GeomAPI_Shape.SOLID, [0])
model.testNbSubShapes(Translation_34, GeomAPI_Shape.EDGE, [12])
-testHaveNamingEdges(Translation_34, model, Part_1_doc)
+model.testHaveNamingEdges(Translation_34, model, Part_1_doc)
# Translation 35
model.testNbResults(Translation_35, 1)
model.testNbSubResults(Translation_35, [12])
model.testNbSubShapes(Translation_35, GeomAPI_Shape.SOLID, [0])
model.testNbSubShapes(Translation_35, GeomAPI_Shape.EDGE, [12])
-testHaveNamingEdges(Translation_35, model, Part_1_doc)
+model.testHaveNamingEdges(Translation_35, model, Part_1_doc)
# Translation 36
model.testNbResults(Translation_36, 1)
Boolean_1 = model.addSmash(Part_1_doc, [model.selection("SOLID", "Extrusion_3_1")], [model.selection("SOLID", "ExtrusionCut_4_1")])
ExtrusionCut_5 = model.addExtrusionCut(Part_1_doc, [model.selection("WIRE", "Sketch_3/Wire-SketchCircle_8_2f")], model.selection(), 10, 0, [model.selection("SOLID", "Boolean_1_1_1")])
ExtrusionCut_6 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_3/Face-SketchCircle_8_2f")], model.selection(), 10, 0, [model.selection("SOLID", "ExtrusionCut_5_1_1")])
-Axis_4 = model.addAxis(Part_1_doc, model.selection("FACE", "ExtrusionCut_6_1/Modfied_1"))
+Axis_4 = model.addAxis(Part_1_doc, model.selection("FACE", "ExtrusionCut_6_1_2/Modfied_1"))
Sketch_4 = model.addSketch(Part_1_doc, model.selection("FACE", "Plane_1"))
SketchProjection_7 = Sketch_4.addProjection(model.selection("EDGE", "PartSet/OY"))
SketchLine_28 = SketchProjection_7.createdFeature()
Boolean_2 = model.addSmash(Part_1_doc, [model.selection("SOLID", "ExtrusionCut_6_1_1"), model.selection("SOLID", "Extrusion_4_1")], [model.selection("SOLID", "ExtrusionCut_6_1_2")])
ExtrusionCut_7 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_4/Face-SketchCircle_9_2f")], model.selection(), 0, 10, [model.selection("SOLID", "Boolean_2_1_1")])
ExtrusionCut_8 = model.addExtrusionCut(Part_1_doc, [model.selection("FACE", "Sketch_4/Face-SketchCircle_9_2f")], model.selection(), 0, 10, [model.selection("SOLID", "ExtrusionCut_7_1_1")])
-Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "Boolean_2_1/Modified_1"))
+Sketch_5 = model.addSketch(Part_1_doc, model.selection("FACE", "Boolean_2_1_1/Modified_1"))
SketchPoint_3 = Sketch_5.addPoint(model.selection("VERTEX", "PartSet/Origin"))
SketchPoint_3.setName("SketchPoint_2")
SketchPoint_3.result().setName("SketchPoint_2")